parsanol 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of parsanol might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/HISTORY.txt +25 -0
- data/LICENSE +23 -0
- data/README.adoc +643 -0
- data/Rakefile +189 -0
- data/example/balanced-parens/basic.rb +42 -0
- data/example/balanced-parens/basic.rb.md +86 -0
- data/example/balanced-parens/parens.rb +42 -0
- data/example/balanced-parens/ruby_transform.rb +162 -0
- data/example/big.erb +73 -0
- data/example/boolean-algebra/basic.rb +70 -0
- data/example/boolean-algebra/basic.rb.md +108 -0
- data/example/boolean-algebra/ruby_transform.rb +263 -0
- data/example/calculator/basic.rb +153 -0
- data/example/calculator/basic.rb.md +120 -0
- data/example/calculator/pattern.rb +153 -0
- data/example/calculator/ruby_transform.rb +156 -0
- data/example/calculator/ruby_transform.rb.md +32 -0
- data/example/calculator/serialized.rb +257 -0
- data/example/calculator/serialized.rb.md +32 -0
- data/example/calculator/transform.rb +153 -0
- data/example/calculator/zero_copy.rb +269 -0
- data/example/calculator/zero_copy.rb.md +36 -0
- data/example/capture/basic.rb +49 -0
- data/example/capture/basic.rb.md +106 -0
- data/example/capture/example.json +39 -0
- data/example/comments/basic.rb +35 -0
- data/example/comments/basic.rb.md +110 -0
- data/example/csv/ruby_transform.rb +148 -0
- data/example/csv/ruby_transform.rb.md +131 -0
- data/example/csv/serialized.rb +201 -0
- data/example/csv/serialized.rb.md +31 -0
- data/example/csv/zero_copy.rb +276 -0
- data/example/csv/zero_copy.rb.md +36 -0
- data/example/custom_atoms/indent_atom.rb +79 -0
- data/example/deepest-errors/basic.rb +131 -0
- data/example/deepest-errors/basic.rb.md +152 -0
- data/example/documentation/basic.rb +18 -0
- data/example/documentation/basic.rb.md +97 -0
- data/example/email/basic.rb +55 -0
- data/example/email/basic.rb.md +102 -0
- data/example/email/ruby_transform.rb +106 -0
- data/example/empty/basic.rb +13 -0
- data/example/empty/basic.rb.md +73 -0
- data/example/empty/example.json +38 -0
- data/example/erb/basic.rb +47 -0
- data/example/erb/basic.rb.md +103 -0
- data/example/erb/optimized.rb +42 -0
- data/example/error-reporting/basic.rb +132 -0
- data/example/error-reporting/basic.rb.md +122 -0
- data/example/expression-evaluator/basic.rb +284 -0
- data/example/expression-evaluator/basic.rb.md +138 -0
- data/example/ini/basic.rb +154 -0
- data/example/ini/basic.rb.md +129 -0
- data/example/ini/ruby_transform.rb +154 -0
- data/example/ip-address/basic.rb +125 -0
- data/example/ip-address/basic.rb.md +139 -0
- data/example/iso-6709/basic.rb +231 -0
- data/example/iso-6709/basic.rb.md +143 -0
- data/example/iso-8601/basic.rb +275 -0
- data/example/iso-8601/basic.rb.md +149 -0
- data/example/json/basic.rb +128 -0
- data/example/json/basic.rb.md +121 -0
- data/example/json/pattern.rb +128 -0
- data/example/json/ruby_transform.rb +200 -0
- data/example/json/ruby_transform.rb.md +32 -0
- data/example/json/serialized.rb +233 -0
- data/example/json/serialized.rb.md +31 -0
- data/example/json/transform.rb +128 -0
- data/example/json/zero_copy.rb +316 -0
- data/example/json/zero_copy.rb.md +36 -0
- data/example/local/basic.rb +34 -0
- data/example/local/basic.rb.md +91 -0
- data/example/local/example.json +38 -0
- data/example/markdown/basic.rb +287 -0
- data/example/markdown/basic.rb.md +160 -0
- data/example/markup/basic.rb +173 -0
- data/example/markup/basic.rb.md +118 -0
- data/example/mathn/basic.rb +47 -0
- data/example/mathn/basic.rb.md +96 -0
- data/example/mathn/example.json +39 -0
- data/example/minilisp/basic.rb +94 -0
- data/example/minilisp/basic.rb.md +133 -0
- data/example/modularity/basic.rb +47 -0
- data/example/modularity/basic.rb.md +152 -0
- data/example/nested-errors/basic.rb +132 -0
- data/example/nested-errors/basic.rb.md +157 -0
- data/example/output/boolean_algebra.out +4 -0
- data/example/output/calc.out +1 -0
- data/example/output/capture.out +3 -0
- data/example/output/comments.out +8 -0
- data/example/output/deepest_errors.out +54 -0
- data/example/output/documentation.err +4 -0
- data/example/output/documentation.out +1 -0
- data/example/output/email_parser.out +2 -0
- data/example/output/empty.err +1 -0
- data/example/output/erb.out +7 -0
- data/example/output/ignore.out +1 -0
- data/example/output/ignore_whitespace.out +1 -0
- data/example/output/ip_address.out +9 -0
- data/example/output/json.out +5 -0
- data/example/output/local.out +3 -0
- data/example/output/mathn.out +4 -0
- data/example/output/minilisp.out +5 -0
- data/example/output/modularity.out +0 -0
- data/example/output/nested_errors.out +54 -0
- data/example/output/optimized_erb.out +1 -0
- data/example/output/parens.out +8 -0
- data/example/output/prec_calc.out +5 -0
- data/example/output/readme.out +1 -0
- data/example/output/scopes.out +1 -0
- data/example/output/seasons.out +28 -0
- data/example/output/sentence.out +1 -0
- data/example/output/simple_xml.out +2 -0
- data/example/output/string_parser.out +3 -0
- data/example/prec-calc/basic.rb +71 -0
- data/example/prec-calc/basic.rb.md +114 -0
- data/example/readme/basic.rb +30 -0
- data/example/readme/basic.rb.md +80 -0
- data/example/scopes/basic.rb +15 -0
- data/example/scopes/basic.rb.md +73 -0
- data/example/scopes/example.json +38 -0
- data/example/seasons/basic.rb +46 -0
- data/example/seasons/basic.rb.md +117 -0
- data/example/seasons/example.json +40 -0
- data/example/sentence/basic.rb +36 -0
- data/example/sentence/basic.rb.md +81 -0
- data/example/sexp/ruby_transform.rb +180 -0
- data/example/sexp/ruby_transform.rb.md +143 -0
- data/example/simple-xml/basic.rb +54 -0
- data/example/simple-xml/basic.rb.md +125 -0
- data/example/simple.lit +3 -0
- data/example/string-literal/basic.rb +77 -0
- data/example/string-literal/basic.rb.md +128 -0
- data/example/test.lit +4 -0
- data/example/toml/basic.rb +226 -0
- data/example/toml/basic.rb.md +173 -0
- data/example/url/basic.rb +219 -0
- data/example/url/basic.rb.md +142 -0
- data/example/url/ruby_transform.rb +219 -0
- data/example/yaml/basic.rb +216 -0
- data/example/yaml/basic.rb.md +148 -0
- data/ext/parsanol_native/extconf.rb +4 -0
- data/lib/parsanol/accelerator/application.rb +62 -0
- data/lib/parsanol/accelerator/engine.rb +112 -0
- data/lib/parsanol/accelerator.rb +162 -0
- data/lib/parsanol/ast_visitor.rb +122 -0
- data/lib/parsanol/atoms/alternative.rb +97 -0
- data/lib/parsanol/atoms/base.rb +214 -0
- data/lib/parsanol/atoms/can_flatten.rb +192 -0
- data/lib/parsanol/atoms/capture.rb +41 -0
- data/lib/parsanol/atoms/context.rb +351 -0
- data/lib/parsanol/atoms/context_optimized.rb +42 -0
- data/lib/parsanol/atoms/custom.rb +110 -0
- data/lib/parsanol/atoms/cut.rb +62 -0
- data/lib/parsanol/atoms/dsl.rb +130 -0
- data/lib/parsanol/atoms/dynamic.rb +33 -0
- data/lib/parsanol/atoms/entity.rb +55 -0
- data/lib/parsanol/atoms/ignored.rb +28 -0
- data/lib/parsanol/atoms/infix.rb +121 -0
- data/lib/parsanol/atoms/lookahead.rb +64 -0
- data/lib/parsanol/atoms/named.rb +50 -0
- data/lib/parsanol/atoms/re.rb +61 -0
- data/lib/parsanol/atoms/repetition.rb +241 -0
- data/lib/parsanol/atoms/scope.rb +28 -0
- data/lib/parsanol/atoms/sequence.rb +157 -0
- data/lib/parsanol/atoms/str.rb +90 -0
- data/lib/parsanol/atoms/visitor.rb +91 -0
- data/lib/parsanol/atoms.rb +36 -0
- data/lib/parsanol/buffer.rb +130 -0
- data/lib/parsanol/builder_callbacks.rb +353 -0
- data/lib/parsanol/cause.rb +101 -0
- data/lib/parsanol/context.rb +23 -0
- data/lib/parsanol/convenience.rb +35 -0
- data/lib/parsanol/edit_tracker.rb +107 -0
- data/lib/parsanol/error_reporter/contextual.rb +122 -0
- data/lib/parsanol/error_reporter/deepest.rb +106 -0
- data/lib/parsanol/error_reporter/tree.rb +68 -0
- data/lib/parsanol/error_reporter.rb +98 -0
- data/lib/parsanol/export.rb +163 -0
- data/lib/parsanol/expression/treetop.rb +94 -0
- data/lib/parsanol/expression.rb +51 -0
- data/lib/parsanol/fast_mode.rb +145 -0
- data/lib/parsanol/first_set.rb +75 -0
- data/lib/parsanol/grammar_builder.rb +177 -0
- data/lib/parsanol/graphviz.rb +97 -0
- data/lib/parsanol/incremental_parser.rb +179 -0
- data/lib/parsanol/interval_tree.rb +215 -0
- data/lib/parsanol/lazy_result.rb +178 -0
- data/lib/parsanol/lexer.rb +146 -0
- data/lib/parsanol/native/parser.rb +630 -0
- data/lib/parsanol/native/serializer.rb +245 -0
- data/lib/parsanol/native/transformer.rb +438 -0
- data/lib/parsanol/native/types.rb +41 -0
- data/lib/parsanol/native.rb +217 -0
- data/lib/parsanol/optimizer.rb +86 -0
- data/lib/parsanol/optimizers/choice_optimizer.rb +78 -0
- data/lib/parsanol/optimizers/cut_inserter.rb +175 -0
- data/lib/parsanol/optimizers/lookahead_optimizer.rb +58 -0
- data/lib/parsanol/optimizers/quantifier_optimizer.rb +62 -0
- data/lib/parsanol/optimizers/sequence_optimizer.rb +97 -0
- data/lib/parsanol/options/ruby_transform.rb +109 -0
- data/lib/parsanol/options/serialized.rb +94 -0
- data/lib/parsanol/options/zero_copy.rb +130 -0
- data/lib/parsanol/options.rb +20 -0
- data/lib/parsanol/parallel.rb +133 -0
- data/lib/parsanol/parsanol_native.bundle +0 -0
- data/lib/parsanol/parser.rb +151 -0
- data/lib/parsanol/parslet.rb +148 -0
- data/lib/parsanol/parslet_native.bundle +0 -0
- data/lib/parsanol/pattern/binding.rb +49 -0
- data/lib/parsanol/pattern.rb +115 -0
- data/lib/parsanol/pool.rb +220 -0
- data/lib/parsanol/pools/array_pool.rb +75 -0
- data/lib/parsanol/pools/buffer_pool.rb +173 -0
- data/lib/parsanol/pools/position_pool.rb +92 -0
- data/lib/parsanol/pools/slice_pool.rb +64 -0
- data/lib/parsanol/position.rb +89 -0
- data/lib/parsanol/result.rb +44 -0
- data/lib/parsanol/result_builder.rb +208 -0
- data/lib/parsanol/result_stream.rb +262 -0
- data/lib/parsanol/rig/rspec.rb +52 -0
- data/lib/parsanol/rope.rb +78 -0
- data/lib/parsanol/scope.rb +42 -0
- data/lib/parsanol/slice.rb +172 -0
- data/lib/parsanol/source/line_cache.rb +99 -0
- data/lib/parsanol/source.rb +171 -0
- data/lib/parsanol/source_location.rb +164 -0
- data/lib/parsanol/streaming_parser.rb +124 -0
- data/lib/parsanol/string_view.rb +192 -0
- data/lib/parsanol/transform.rb +267 -0
- data/lib/parsanol/version.rb +5 -0
- data/lib/parsanol/wasm/README.md +80 -0
- data/lib/parsanol/wasm/package.json +51 -0
- data/lib/parsanol/wasm/parsanol.js +252 -0
- data/lib/parsanol/wasm/parslet.d.ts +129 -0
- data/lib/parsanol/wasm_parser.rb +239 -0
- data/lib/parsanol.rb +408 -0
- data/parsanol-ruby.gemspec +56 -0
- data/spec/acceptance/examples_spec.rb +96 -0
- data/spec/acceptance/infix_parser_spec.rb +145 -0
- data/spec/acceptance/mixing_parsers_spec.rb +74 -0
- data/spec/acceptance/regression_spec.rb +329 -0
- data/spec/acceptance/repetition_and_maybe_spec.rb +44 -0
- data/spec/acceptance/unconsumed_input_spec.rb +21 -0
- data/spec/benchmark/comparative/runner_spec.rb +105 -0
- data/spec/integration/array_pooling_spec.rb +193 -0
- data/spec/integration/buffer_allocation_spec.rb +324 -0
- data/spec/integration/position_pooling_spec.rb +184 -0
- data/spec/integration/result_builder_spec.rb +282 -0
- data/spec/integration/rope_stringview_integration_spec.rb +188 -0
- data/spec/integration/slice_pooling_spec.rb +63 -0
- data/spec/integration/string_view_integration_spec.rb +125 -0
- data/spec/lexer_spec.rb +231 -0
- data/spec/parsanol/atom_results_spec.rb +39 -0
- data/spec/parsanol/atoms/alternative_spec.rb +26 -0
- data/spec/parsanol/atoms/base_spec.rb +127 -0
- data/spec/parsanol/atoms/capture_spec.rb +21 -0
- data/spec/parsanol/atoms/combinations_spec.rb +5 -0
- data/spec/parsanol/atoms/custom_spec.rb +79 -0
- data/spec/parsanol/atoms/dsl_spec.rb +7 -0
- data/spec/parsanol/atoms/entity_spec.rb +77 -0
- data/spec/parsanol/atoms/ignored_spec.rb +15 -0
- data/spec/parsanol/atoms/infix_spec.rb +5 -0
- data/spec/parsanol/atoms/lookahead_spec.rb +22 -0
- data/spec/parsanol/atoms/named_spec.rb +4 -0
- data/spec/parsanol/atoms/re_spec.rb +14 -0
- data/spec/parsanol/atoms/repetition_spec.rb +24 -0
- data/spec/parsanol/atoms/scope_spec.rb +26 -0
- data/spec/parsanol/atoms/sequence_spec.rb +28 -0
- data/spec/parsanol/atoms/str_spec.rb +15 -0
- data/spec/parsanol/atoms/visitor_spec.rb +101 -0
- data/spec/parsanol/atoms_spec.rb +488 -0
- data/spec/parsanol/auto_optimize_spec.rb +334 -0
- data/spec/parsanol/buffer_spec.rb +219 -0
- data/spec/parsanol/builder_callbacks_spec.rb +377 -0
- data/spec/parsanol/choice_optimizer_spec.rb +231 -0
- data/spec/parsanol/convenience_spec.rb +54 -0
- data/spec/parsanol/cut_inserter_spec.rb +248 -0
- data/spec/parsanol/cut_spec.rb +66 -0
- data/spec/parsanol/edit_tracker_spec.rb +218 -0
- data/spec/parsanol/error_reporter/contextual_spec.rb +122 -0
- data/spec/parsanol/error_reporter/deepest_spec.rb +82 -0
- data/spec/parsanol/error_reporter/tree_spec.rb +7 -0
- data/spec/parsanol/export_spec.rb +67 -0
- data/spec/parsanol/expression/treetop_spec.rb +75 -0
- data/spec/parsanol/first_set_spec.rb +298 -0
- data/spec/parsanol/interval_tree_spec.rb +205 -0
- data/spec/parsanol/lazy_result_spec.rb +288 -0
- data/spec/parsanol/lookahead_optimizer_spec.rb +252 -0
- data/spec/parsanol/minilisp.citrus +29 -0
- data/spec/parsanol/minilisp.tt +29 -0
- data/spec/parsanol/optimizer_spec.rb +459 -0
- data/spec/parsanol/options/parslet_compat_spec.rb +166 -0
- data/spec/parsanol/options/ruby_transform_spec.rb +70 -0
- data/spec/parsanol/options/serialized_spec.rb +69 -0
- data/spec/parsanol/options/zero_copy_spec.rb +230 -0
- data/spec/parsanol/parser_spec.rb +36 -0
- data/spec/parsanol/parslet_spec.rb +38 -0
- data/spec/parsanol/pattern_spec.rb +272 -0
- data/spec/parsanol/pool_spec.rb +392 -0
- data/spec/parsanol/pools/array_pool_spec.rb +356 -0
- data/spec/parsanol/pools/buffer_pool_spec.rb +365 -0
- data/spec/parsanol/pools/position_pool_spec.rb +118 -0
- data/spec/parsanol/pools/slice_pool_spec.rb +262 -0
- data/spec/parsanol/position_spec.rb +14 -0
- data/spec/parsanol/result_builder_spec.rb +391 -0
- data/spec/parsanol/rig/rspec_spec.rb +54 -0
- data/spec/parsanol/rope_spec.rb +207 -0
- data/spec/parsanol/scope_spec.rb +45 -0
- data/spec/parsanol/slice_spec.rb +249 -0
- data/spec/parsanol/source/line_cache_spec.rb +74 -0
- data/spec/parsanol/source_spec.rb +207 -0
- data/spec/parsanol/string_view_spec.rb +345 -0
- data/spec/parsanol/transform/context_spec.rb +56 -0
- data/spec/parsanol/transform_spec.rb +183 -0
- data/spec/parsanol/tree_memoization_spec.rb +149 -0
- data/spec/parslet_compatibility/expressir_edge_cases_spec.rb +153 -0
- data/spec/parslet_compatibility/minimal_reproduction.rb +199 -0
- data/spec/parslet_compatibility_spec.rb +399 -0
- data/spec/parslet_imported/atom_spec.rb +93 -0
- data/spec/parslet_imported/combinator_spec.rb +161 -0
- data/spec/parslet_imported/spec_helper.rb +73 -0
- data/spec/performance/batch_parsing_benchmark.rb +129 -0
- data/spec/performance/complete_optimization_summary.rb +143 -0
- data/spec/performance/grammar_caching_analysis.rb +121 -0
- data/spec/performance/grammar_caching_benchmark.rb +80 -0
- data/spec/performance/native_benchmark_spec.rb +230 -0
- data/spec/performance/phase5_benchmark.rb +144 -0
- data/spec/performance/profiling_benchmark.rb +131 -0
- data/spec/performance/ruby_improvements_benchmark.rb +171 -0
- data/spec/performance_spec.rb +374 -0
- data/spec/spec_helper.rb +79 -0
- data/spec/support/opal.rb +8 -0
- data/spec/support/opal.rb.erb +14 -0
- metadata +485 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Grammar Modularity - Ruby Implementation
|
|
2
|
+
|
|
3
|
+
## How to Run
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
cd parsanol-ruby/example/modularity
|
|
7
|
+
ruby basic.rb
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Code Walkthrough
|
|
11
|
+
|
|
12
|
+
### Module Mixins
|
|
13
|
+
|
|
14
|
+
Ruby modules can be mixed into parser classes:
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
module ALanguage
|
|
18
|
+
include Parsanol::Parslet
|
|
19
|
+
|
|
20
|
+
rule(:a_language) { str('aaa') }
|
|
21
|
+
end
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`include Parsanol::Parslet` makes the module a grammar container.
|
|
25
|
+
|
|
26
|
+
### Parser as Atom
|
|
27
|
+
|
|
28
|
+
Parser instances are valid atoms:
|
|
29
|
+
|
|
30
|
+
```ruby
|
|
31
|
+
class BLanguage < Parsanol::Parser
|
|
32
|
+
root :blang
|
|
33
|
+
|
|
34
|
+
rule(:blang) { str('bbb') }
|
|
35
|
+
end
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Use `BLanguage.new` directly in other parsers' rules.
|
|
39
|
+
|
|
40
|
+
### Passing Atoms
|
|
41
|
+
|
|
42
|
+
Atoms are Ruby values that can be passed around:
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
c_language = Parsanol.str('ccc')
|
|
46
|
+
|
|
47
|
+
class Language < Parsanol::Parser
|
|
48
|
+
def initialize(c_language)
|
|
49
|
+
@c_language = c_language
|
|
50
|
+
super()
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
rule(:root) { str('c(') >> @c_language >> str(')') }
|
|
54
|
+
end
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Constructor injection enables dynamic grammar composition.
|
|
58
|
+
|
|
59
|
+
### Combined Root Rule
|
|
60
|
+
|
|
61
|
+
The root combines all module entry points:
|
|
62
|
+
|
|
63
|
+
```ruby
|
|
64
|
+
rule(:root) {
|
|
65
|
+
str('a(') >> a_language >> str(')') >> space |
|
|
66
|
+
str('b(') >> BLanguage.new >> str(')') >> space |
|
|
67
|
+
str('c(') >> @c_language >> str(')') >> space
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Each alternative invokes a different module.
|
|
72
|
+
|
|
73
|
+
### Using the Composed Parser
|
|
74
|
+
|
|
75
|
+
```ruby
|
|
76
|
+
Language.new(c_language).parse('a(aaa)') # => matches
|
|
77
|
+
Language.new(c_language).parse('b(bbb)') # => matches
|
|
78
|
+
Language.new(c_language).parse('c(ccc)') # => matches
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Single parser instance handles all module syntaxes.
|
|
82
|
+
|
|
83
|
+
## Design Patterns
|
|
84
|
+
|
|
85
|
+
### Include Pattern
|
|
86
|
+
|
|
87
|
+
```ruby
|
|
88
|
+
module CommonExpressions
|
|
89
|
+
include Parsanol::Parslet
|
|
90
|
+
|
|
91
|
+
rule(:integer) { match('[0-9]').repeat(1) }
|
|
92
|
+
rule(:identifier) { match('[a-z]').repeat(1) }
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
class MyParser < Parsanol::Parser
|
|
96
|
+
include CommonExpressions
|
|
97
|
+
include WhitespaceRules
|
|
98
|
+
|
|
99
|
+
rule(:expr) { integer | identifier }
|
|
100
|
+
end
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Multiple modules combine via include.
|
|
104
|
+
|
|
105
|
+
### Delegation Pattern
|
|
106
|
+
|
|
107
|
+
```ruby
|
|
108
|
+
class JsonParser < Parsanol::Parser
|
|
109
|
+
rule(:value) { StringParser.new | NumberParser.new | ObjectParser.new }
|
|
110
|
+
end
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Each sub-parser handles one JSON type.
|
|
114
|
+
|
|
115
|
+
### Prefix Pattern
|
|
116
|
+
|
|
117
|
+
```ruby
|
|
118
|
+
module ExpressionParser
|
|
119
|
+
def expr_with_prefix(prefix)
|
|
120
|
+
prefix >> expr
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Modules can provide parameterized rules.
|
|
126
|
+
|
|
127
|
+
## Output
|
|
128
|
+
|
|
129
|
+
```ruby
|
|
130
|
+
# All three module syntaxes parse
|
|
131
|
+
Language.new(c_language).parse('a(aaa)')
|
|
132
|
+
Language.new(c_language).parse('b(bbb)')
|
|
133
|
+
Language.new(c_language).parse('c(ccc)')
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Design Decisions
|
|
137
|
+
|
|
138
|
+
### Why Include for Modules?
|
|
139
|
+
|
|
140
|
+
Ruby's include provides clean namespace integration. Rules become methods on the parser class.
|
|
141
|
+
|
|
142
|
+
### Why Parser as Atom?
|
|
143
|
+
|
|
144
|
+
Parsers being atoms enables composition without special syntax. Just instantiate and chain.
|
|
145
|
+
|
|
146
|
+
### Why Constructor Injection?
|
|
147
|
+
|
|
148
|
+
Dynamic composition allows runtime grammar modification. Same parser class with different sub-grammars.
|
|
149
|
+
|
|
150
|
+
### Why Not Class Inheritance?
|
|
151
|
+
|
|
152
|
+
Composition (include/instance) is more flexible than inheritance. Multiple modules can be combined in any order.
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + "/../lib"
|
|
2
|
+
|
|
3
|
+
require 'parsanol/parslet'
|
|
4
|
+
require 'parsanol/convenience'
|
|
5
|
+
|
|
6
|
+
# This example demonstrates tree error reporting in a real life example.
|
|
7
|
+
# Originally contributed to Parslet, ported to Parsanol as an example.
|
|
8
|
+
|
|
9
|
+
def prettify(str)
|
|
10
|
+
puts " "*3 + " "*4 + "." + " "*4 + "10" + " "*3 + "." + " "*4 + "20"
|
|
11
|
+
str.lines.each_with_index do |line, index|
|
|
12
|
+
printf "%02d %s\n",
|
|
13
|
+
index+1,
|
|
14
|
+
line.chomp
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class Parser < Parsanol::Parser
|
|
19
|
+
|
|
20
|
+
# commons
|
|
21
|
+
|
|
22
|
+
rule(:space) { match('[ \t]').repeat(1) }
|
|
23
|
+
rule(:space?) { space.maybe }
|
|
24
|
+
|
|
25
|
+
rule(:newline) { match('[\r\n]') }
|
|
26
|
+
|
|
27
|
+
rule(:comment) { str('#') >> match('[^\r\n]').repeat }
|
|
28
|
+
|
|
29
|
+
rule(:line_separator) {
|
|
30
|
+
(space? >> ((comment.maybe >> newline) | str(';')) >> space?).repeat(1)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
rule(:blank) { line_separator | space }
|
|
34
|
+
rule(:blank?) { blank.maybe }
|
|
35
|
+
|
|
36
|
+
rule(:identifier) { match('[a-zA-Z0-9_]').repeat(1) }
|
|
37
|
+
|
|
38
|
+
# res_statement
|
|
39
|
+
|
|
40
|
+
rule(:reference) {
|
|
41
|
+
(str('@').repeat(1,2) >> identifier).as(:reference)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
rule(:res_action_or_link) {
|
|
45
|
+
str('.').as(:dot) >> (identifier >> str('?').maybe ).as(:name) >> str('()')
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
rule(:res_actions) {
|
|
49
|
+
(
|
|
50
|
+
reference
|
|
51
|
+
).as(:resources) >>
|
|
52
|
+
(
|
|
53
|
+
res_action_or_link.as(:res_action)
|
|
54
|
+
).repeat(0).as(:res_actions)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
rule(:res_statement) {
|
|
58
|
+
res_actions >>
|
|
59
|
+
(str(':') >> identifier.as(:name)).maybe.as(:res_field)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# expression
|
|
63
|
+
|
|
64
|
+
rule(:expression) {
|
|
65
|
+
res_statement
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
# body
|
|
69
|
+
|
|
70
|
+
rule(:body) {
|
|
71
|
+
(line_separator >> (block | expression)).repeat(1).as(:body) >>
|
|
72
|
+
line_separator
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
# blocks
|
|
76
|
+
|
|
77
|
+
rule(:begin_block) {
|
|
78
|
+
(str('concurrent').as(:type) >> space).maybe.as(:pre) >>
|
|
79
|
+
str('begin').as(:begin) >>
|
|
80
|
+
body >>
|
|
81
|
+
str('end')
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
rule(:define_block) {
|
|
85
|
+
str('define').as(:define) >> space >>
|
|
86
|
+
identifier.as(:name) >> str('()') >>
|
|
87
|
+
body >>
|
|
88
|
+
str('end')
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
rule(:block) {
|
|
92
|
+
define_block | begin_block
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
# root
|
|
96
|
+
|
|
97
|
+
rule(:radix) {
|
|
98
|
+
line_separator.maybe >> block >> line_separator.maybe
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
root(:radix)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
ds = [
|
|
106
|
+
%{
|
|
107
|
+
define f()
|
|
108
|
+
@res.name
|
|
109
|
+
end
|
|
110
|
+
},
|
|
111
|
+
%{
|
|
112
|
+
define f()
|
|
113
|
+
begin
|
|
114
|
+
@res.name
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
|
|
120
|
+
ds.each do |d|
|
|
121
|
+
|
|
122
|
+
puts '-' * 80
|
|
123
|
+
prettify(d)
|
|
124
|
+
|
|
125
|
+
parser = Parser.new
|
|
126
|
+
|
|
127
|
+
begin
|
|
128
|
+
parser.parse_with_debug(d)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
puts '-' * 80
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Nested Error Reporting - Ruby Implementation
|
|
2
|
+
|
|
3
|
+
## How to Run
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
cd parsanol-ruby/example/nested-errors
|
|
7
|
+
ruby basic.rb
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Code Walkthrough
|
|
11
|
+
|
|
12
|
+
### parse_with_debug Output
|
|
13
|
+
|
|
14
|
+
The debug method shows full error information:
|
|
15
|
+
|
|
16
|
+
```ruby
|
|
17
|
+
parser.parse_with_debug(input)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
This automatically formats and displays the error tree.
|
|
21
|
+
|
|
22
|
+
### Error Tree Structure
|
|
23
|
+
|
|
24
|
+
Parslet errors form a tree:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
- Failed to parse sequence
|
|
28
|
+
- Expected "end" at line 3
|
|
29
|
+
- In block body
|
|
30
|
+
- Expected expression
|
|
31
|
+
- Expected "begin"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Each indentation represents a nested failure context.
|
|
35
|
+
|
|
36
|
+
### Helper Formatting
|
|
37
|
+
|
|
38
|
+
The example provides line-numbered output:
|
|
39
|
+
|
|
40
|
+
```ruby
|
|
41
|
+
def prettify(str)
|
|
42
|
+
puts " "*3 + " "*4 + "." + " "*4 + "10" + " "*3 + "." + " "*4 + "20"
|
|
43
|
+
str.lines.each_with_index do |line, index|
|
|
44
|
+
printf "%02d %s\n", index+1, line.chomp
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Column ruler helps locate errors visually.
|
|
50
|
+
|
|
51
|
+
### Complex Grammar for Testing
|
|
52
|
+
|
|
53
|
+
The example uses a realistic grammar:
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
rule(:reference) {
|
|
57
|
+
(str('@').repeat(1,2) >> identifier).as(:reference)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
rule(:res_action_or_link) {
|
|
61
|
+
str('.').as(:dot) >>
|
|
62
|
+
(identifier >> str('?').maybe).as(:name) >>
|
|
63
|
+
str('()')
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Multiple rules create multiple failure points.
|
|
68
|
+
|
|
69
|
+
### Block Structure
|
|
70
|
+
|
|
71
|
+
Nested blocks create deep error trees:
|
|
72
|
+
|
|
73
|
+
```ruby
|
|
74
|
+
rule(:begin_block) {
|
|
75
|
+
(str('concurrent').as(:type) >> space).maybe.as(:pre) >>
|
|
76
|
+
str('begin').as(:begin) >>
|
|
77
|
+
body >>
|
|
78
|
+
str('end')
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
rule(:define_block) {
|
|
82
|
+
str('define').as(:define) >> space >>
|
|
83
|
+
identifier.as(:name) >> str('()') >>
|
|
84
|
+
body >>
|
|
85
|
+
str('end')
|
|
86
|
+
}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Each block type has its own error context.
|
|
90
|
+
|
|
91
|
+
### Test Cases
|
|
92
|
+
|
|
93
|
+
```ruby
|
|
94
|
+
ds = [
|
|
95
|
+
%{
|
|
96
|
+
define f()
|
|
97
|
+
@res.name
|
|
98
|
+
end
|
|
99
|
+
},
|
|
100
|
+
%{
|
|
101
|
+
define f()
|
|
102
|
+
begin
|
|
103
|
+
@res.name
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
}
|
|
107
|
+
]
|
|
108
|
+
|
|
109
|
+
ds.each do |d|
|
|
110
|
+
puts '-' * 80
|
|
111
|
+
prettify(d)
|
|
112
|
+
parser.parse_with_debug(d)
|
|
113
|
+
end
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Each case demonstrates different error scenarios.
|
|
117
|
+
|
|
118
|
+
## Output Types
|
|
119
|
+
|
|
120
|
+
Successful parse:
|
|
121
|
+
```
|
|
122
|
+
01
|
|
123
|
+
02 define f()
|
|
124
|
+
03 @res.name
|
|
125
|
+
04 end
|
|
126
|
+
|
|
127
|
+
{:define=>"define"@..., :name=>"f"@..., :body=>[...]}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Failed parse with tree:
|
|
131
|
+
```
|
|
132
|
+
01
|
|
133
|
+
02 define f()
|
|
134
|
+
03 @res.name(
|
|
135
|
+
04 end
|
|
136
|
+
|
|
137
|
+
Failed to match sequence
|
|
138
|
+
`- Expected ")" at line 3, column 12
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Design Decisions
|
|
142
|
+
|
|
143
|
+
### Why parse_with_debug?
|
|
144
|
+
|
|
145
|
+
It handles error formatting automatically. For production use, catch `Parsanol::ParseFailed` and format custom messages.
|
|
146
|
+
|
|
147
|
+
### Why Multiple Test Cases?
|
|
148
|
+
|
|
149
|
+
Different constructs fail differently. Multiple cases show the full error reporting capability.
|
|
150
|
+
|
|
151
|
+
### Why Prettify Helper?
|
|
152
|
+
|
|
153
|
+
Line numbers help users find errors in their input. The column ruler aids visual scanning.
|
|
154
|
+
|
|
155
|
+
### Why Block-Structured Grammar?
|
|
156
|
+
|
|
157
|
+
Simple grammars have shallow error trees. Block-structured grammars demonstrate nested error contexts.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
123*2 (command line): -> 246
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
[{:exp=>{:a=>"a"@3}},
|
|
2
|
+
{:line=>"// line comment"@7},
|
|
3
|
+
{:exp=>{:a=>"a"@25}},
|
|
4
|
+
{:exp=>{:a=>"a"@27}},
|
|
5
|
+
{:exp=>[{:a=>"a"@29}, {:line=>"// line comment"@31}]},
|
|
6
|
+
{:exp=>[{:a=>"a"@49}, {:multi=>"/* inline comment */"@51}]},
|
|
7
|
+
{:exp=>{:a=>"a"@72}},
|
|
8
|
+
{:multi=>"/* multiline\n comment */"@77}]
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
--------------------------------------------------------------------------------
|
|
2
|
+
. 10 . 20
|
|
3
|
+
01
|
|
4
|
+
02 define f()
|
|
5
|
+
03 @res.name
|
|
6
|
+
04 end
|
|
7
|
+
05
|
|
8
|
+
Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
|
|
9
|
+
`- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
|
|
10
|
+
|- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
|
|
11
|
+
| `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 3 char 11.
|
|
12
|
+
| `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 3 char 11.
|
|
13
|
+
| `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 3 char 11.
|
|
14
|
+
| `- Expected one of [COMMENT? NEWLINE, ';'] at line 3 char 11.
|
|
15
|
+
| |- Failed to match sequence (COMMENT? NEWLINE) at line 3 char 11.
|
|
16
|
+
| | `- Expected "()", but got "\n " at line 3 char 16.
|
|
17
|
+
| `- Expected "()", but got "\n " at line 3 char 16.
|
|
18
|
+
`- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
|
|
19
|
+
`- Expected "()", but got "\n " at line 3 char 16.
|
|
20
|
+
--------------------------------------------------------------------------------
|
|
21
|
+
. 10 . 20
|
|
22
|
+
01
|
|
23
|
+
02 define f()
|
|
24
|
+
03 begin
|
|
25
|
+
04 @res.name
|
|
26
|
+
05 end
|
|
27
|
+
06 end
|
|
28
|
+
07
|
|
29
|
+
Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
|
|
30
|
+
`- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
|
|
31
|
+
|- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
|
|
32
|
+
| `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 2 char 15.
|
|
33
|
+
| `- Expected at least 1 of LINE_SEPARATOR (BLOCK / EXPRESSION) at line 2 char 15.
|
|
34
|
+
| `- Failed to match sequence (LINE_SEPARATOR (BLOCK / EXPRESSION)) at line 3 char 7.
|
|
35
|
+
| `- Expected one of [BLOCK, EXPRESSION] at line 3 char 7.
|
|
36
|
+
| |- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 3 char 7.
|
|
37
|
+
| | |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 3 char 7.
|
|
38
|
+
| | | `- Expected "define", but got "begin\n" at line 3 char 7.
|
|
39
|
+
| | `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 3 char 12.
|
|
40
|
+
| | `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 4 char 13.
|
|
41
|
+
| | `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 4 char 13.
|
|
42
|
+
| | `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 4 char 13.
|
|
43
|
+
| | `- Expected one of [COMMENT? NEWLINE, ';'] at line 4 char 13.
|
|
44
|
+
| | |- Failed to match sequence (COMMENT? NEWLINE) at line 4 char 13.
|
|
45
|
+
| | | `- Expected "()", but got "\n " at line 4 char 18.
|
|
46
|
+
| | `- Expected "()", but got "\n " at line 4 char 18.
|
|
47
|
+
| `- Failed to match sequence (RES_ACTIONS res_field:((':' name:IDENTIFIER)?)) at line 3 char 7.
|
|
48
|
+
| `- Failed to match sequence (resources:REFERENCE res_actions:(res_action:RES_ACTION_OR_LINK{0, })) at line 3 char 7.
|
|
49
|
+
| `- Failed to match sequence ('@'{1, 2} IDENTIFIER) at line 3 char 7.
|
|
50
|
+
| `- Expected at least 1 of '@' at line 3 char 7.
|
|
51
|
+
| `- Expected "()", but got "\n " at line 4 char 18.
|
|
52
|
+
`- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
|
|
53
|
+
`- Expected "()", but got "\n " at line 4 char 18.
|
|
54
|
+
--------------------------------------------------------------------------------
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/Users/kaspar/git_work/own/parslet/lib/parslet/atoms/base.rb:326:in `parse_failed': Don't know what to do with bbbb at line 1 char 1. (Parslet::ParseFailed)
|
|
2
|
+
from /Users/kaspar/git_work/own/parslet/lib/parslet/atoms/base.rb:55:in `parse'
|
|
3
|
+
from example/documentation.rb:13:in `parse'
|
|
4
|
+
from example/documentation.rb:18:in `<main>'
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"aaaa"@0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
example/empty.rb:13:in `<main>': rule(:empty) { ... } returns nil. Still not implemented, but already used? (NotImplementedError)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{:text=>[{:text=>"The value of x is "@0}, {:expression=>{:ruby=>" x "@21}}, {:text=>"."@26}]}
|
|
2
|
+
{:text=>[{:code=>{:ruby=>" 1 + 2 "@2}}]}
|
|
3
|
+
{:text=>[{:comment=>{:ruby=>" commented "@3}}]}
|
|
4
|
+
The not printed result of "a = 2".
|
|
5
|
+
The not printed non-evaluated comment "a = 1", see the value of a below.
|
|
6
|
+
The nicely printed result.
|
|
7
|
+
The value of a is 2, and b is 3.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"ac"@0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[{:a=>"a"@0}, {:a=>"a"@1}, {:a=>"a"@5}, {:a=>"a"@7}]
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
0.0.0.0 -> {:ipv4=>"0.0.0.0"@0}
|
|
2
|
+
255.255.255.255 -> {:ipv4=>"255.255.255.255"@0}
|
|
3
|
+
255.255.255 -> Failed: Expected one of [IPV4, IPV6] at line 1 char 1.
|
|
4
|
+
1:2:3:4:5:6:7:8 -> {:ipv6=>"1:2:3:4:5:6:7:8"@0}
|
|
5
|
+
12AD:34FC:A453:1922:: -> {:ipv6=>"12AD:34FC:A453:1922::"@0}
|
|
6
|
+
12AD::34FC -> {:ipv6=>"12AD::34FC"@0}
|
|
7
|
+
12AD:: -> {:ipv6=>"12AD::"@0}
|
|
8
|
+
:: -> {:ipv6=>"::"@0}
|
|
9
|
+
1:2 -> Failed: Expected one of [IPV4, IPV6] at line 1 char 1.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
|
|
2
|
+
{:array=>[{:number=>"1"@5}, {:number=>"2"@8}, {:number=>"3"@11}, {:null=>"null"@14}, {:string=>"asdfasdf asdfds"@25}, {:object=>{:entry=>{:key=>{:string=>"a"@46}, :val=>{:number=>"-1.2"@50}}}}, {:object=>[{:entry=>{:key=>{:string=>"b"@61}, :val=>{:true=>"true"@65}}}, {:entry=>{:key=>{:string=>"c"@72}, :val=>{:false=>"false"@76}}}]}, {:number=>"0.1e24"@89}, {:true=>"true"@97}, {:false=>"false"@103}, {:array=>{:number=>"1"@112}}]}
|
|
3
|
+
|
|
4
|
+
[1, 2, 3, nil, "asdfasdf asdfds", {"a"=>-1.2}, {"b"=>true, "c"=>false}, 1.0e+23, true, false, [1]]
|
|
5
|
+
|
|
File without changes
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
--------------------------------------------------------------------------------
|
|
2
|
+
. 10 . 20
|
|
3
|
+
01
|
|
4
|
+
02 define f()
|
|
5
|
+
03 @res.name
|
|
6
|
+
04 end
|
|
7
|
+
05
|
|
8
|
+
Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
|
|
9
|
+
`- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
|
|
10
|
+
|- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
|
|
11
|
+
| `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 3 char 11.
|
|
12
|
+
| `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 3 char 11.
|
|
13
|
+
| `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 3 char 11.
|
|
14
|
+
| `- Expected one of [COMMENT? NEWLINE, ';'] at line 3 char 11.
|
|
15
|
+
| |- Failed to match sequence (COMMENT? NEWLINE) at line 3 char 11.
|
|
16
|
+
| | `- Failed to match [\\r\\n] at line 3 char 11.
|
|
17
|
+
| `- Expected ";", but got "." at line 3 char 11.
|
|
18
|
+
`- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
|
|
19
|
+
`- Expected "begin", but got "defin" at line 2 char 5.
|
|
20
|
+
--------------------------------------------------------------------------------
|
|
21
|
+
. 10 . 20
|
|
22
|
+
01
|
|
23
|
+
02 define f()
|
|
24
|
+
03 begin
|
|
25
|
+
04 @res.name
|
|
26
|
+
05 end
|
|
27
|
+
06 end
|
|
28
|
+
07
|
|
29
|
+
Failed to match sequence (LINE_SEPARATOR? BLOCK LINE_SEPARATOR?) at line 2 char 5.
|
|
30
|
+
`- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 2 char 5.
|
|
31
|
+
|- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 2 char 15.
|
|
32
|
+
| `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 2 char 15.
|
|
33
|
+
| `- Expected at least 1 of LINE_SEPARATOR (BLOCK / EXPRESSION) at line 2 char 15.
|
|
34
|
+
| `- Failed to match sequence (LINE_SEPARATOR (BLOCK / EXPRESSION)) at line 3 char 7.
|
|
35
|
+
| `- Expected one of [BLOCK, EXPRESSION] at line 3 char 7.
|
|
36
|
+
| |- Expected one of [DEFINE_BLOCK, BEGIN_BLOCK] at line 3 char 7.
|
|
37
|
+
| | |- Failed to match sequence (define:'define' SPACE name:IDENTIFIER '()' BODY 'end') at line 3 char 7.
|
|
38
|
+
| | | `- Expected "define", but got "begin\n" at line 3 char 7.
|
|
39
|
+
| | `- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 3 char 12.
|
|
40
|
+
| | `- Failed to match sequence (body:((LINE_SEPARATOR (BLOCK / EXPRESSION)){1, }) LINE_SEPARATOR) at line 4 char 13.
|
|
41
|
+
| | `- Expected at least 1 of SPACE? (COMMENT? NEWLINE / ';') SPACE? at line 4 char 13.
|
|
42
|
+
| | `- Failed to match sequence (SPACE? (COMMENT? NEWLINE / ';') SPACE?) at line 4 char 13.
|
|
43
|
+
| | `- Expected one of [COMMENT? NEWLINE, ';'] at line 4 char 13.
|
|
44
|
+
| | |- Failed to match sequence (COMMENT? NEWLINE) at line 4 char 13.
|
|
45
|
+
| | | `- Failed to match [\\r\\n] at line 4 char 13.
|
|
46
|
+
| | `- Expected ";", but got "." at line 4 char 13.
|
|
47
|
+
| `- Failed to match sequence (RES_ACTIONS res_field:((':' name:IDENTIFIER)?)) at line 3 char 7.
|
|
48
|
+
| `- Failed to match sequence (resources:REFERENCE res_actions:(res_action:RES_ACTION_OR_LINK{0, })) at line 3 char 7.
|
|
49
|
+
| `- Failed to match sequence ('@'{1, 2} IDENTIFIER) at line 3 char 7.
|
|
50
|
+
| `- Expected at least 1 of '@' at line 3 char 7.
|
|
51
|
+
| `- Expected "@", but got "b" at line 3 char 7.
|
|
52
|
+
`- Failed to match sequence (pre:((type:'concurrent' SPACE)?) begin:'begin' BODY 'end') at line 2 char 5.
|
|
53
|
+
`- Expected "begin", but got "defin" at line 2 char 5.
|
|
54
|
+
--------------------------------------------------------------------------------
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{:text=>[{:text=>"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n\n"@0}, {:expression=>{:ruby=>" erb tag "@2685}}, {:text=>"\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod\ntempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,\nquis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo\nconsequat. Duis aute irure dolor in reprehenderit in voluptate velit esse\ncillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non\nproident, sunt in culpa qui officia deserunt mollit anim id est laborum.\n"@2696}]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
(): {:l=>"("@0, :m=>nil, :r=>")"@1} (1 parens)
|
|
2
|
+
|
|
3
|
+
(()): {:l=>"("@0, :m=>{:l=>"("@1, :m=>nil, :r=>")"@2}, :r=>")"@3} (2 parens)
|
|
4
|
+
|
|
5
|
+
((((())))): {:l=>"("@0, :m=>{:l=>"("@1, :m=>{:l=>"("@2, :m=>{:l=>"("@3, :m=>{:l=>"("@4, :m=>nil, :r=>")"@5}, :r=>")"@6}, :r=>")"@7}, :r=>")"@8}, :r=>")"@9} (5 parens)
|
|
6
|
+
|
|
7
|
+
((()): Failed to match sequence (l:'(' m:(BALANCED?) r:')') at line 1 char 6.
|
|
8
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
String contents: This is a \"String\" in which you can escape stuff
|