rattler 0.3.0 → 0.4.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.
Files changed (182) hide show
  1. data/README.rdoc +57 -37
  2. data/features/command_line/dest_option.feature +8 -21
  3. data/features/command_line/lib_option.feature +37 -0
  4. data/features/command_line/parser_generator.feature +7 -4
  5. data/features/grammar/back_reference.feature +37 -0
  6. data/features/grammar/fail.feature +3 -3
  7. data/features/grammar/labels.feature +11 -3
  8. data/features/grammar/list_matching.feature +14 -5
  9. data/features/grammar/literal.feature +30 -4
  10. data/features/grammar/nonterminal.feature +1 -1
  11. data/features/grammar/ordered_choice.feature +2 -2
  12. data/features/grammar/skip_operator.feature +1 -1
  13. data/features/grammar/symantic_action.feature +7 -7
  14. data/features/grammar/whitespace.feature +2 -2
  15. data/features/step_definitions/grammar_steps.rb +2 -2
  16. data/lib/rattler/back_end.rb +1 -0
  17. data/lib/rattler/back_end/compiler.rb +19 -20
  18. data/lib/rattler/back_end/optimizer.rb +100 -0
  19. data/lib/rattler/back_end/optimizer/composite_reducing.rb +18 -0
  20. data/lib/rattler/back_end/optimizer/flatten_choice.rb +31 -0
  21. data/lib/rattler/back_end/optimizer/flatten_sequence.rb +59 -0
  22. data/lib/rattler/back_end/optimizer/flattening.rb +17 -0
  23. data/lib/rattler/back_end/optimizer/inline_regular_rules.rb +46 -0
  24. data/lib/rattler/back_end/optimizer/join_match_capturing_sequence.rb +71 -0
  25. data/lib/rattler/back_end/optimizer/join_match_choice.rb +37 -0
  26. data/lib/rattler/back_end/optimizer/join_match_matching_sequence.rb +38 -0
  27. data/lib/rattler/back_end/optimizer/join_match_sequence.rb +17 -0
  28. data/lib/rattler/back_end/optimizer/join_predicate_bare_match.rb +68 -0
  29. data/lib/rattler/back_end/optimizer/join_predicate_match.rb +17 -0
  30. data/lib/rattler/back_end/optimizer/join_predicate_nested_match.rb +37 -0
  31. data/lib/rattler/back_end/optimizer/join_predicate_or_bare_match.rb +68 -0
  32. data/lib/rattler/back_end/optimizer/join_predicate_or_match.rb +17 -0
  33. data/lib/rattler/back_end/optimizer/join_predicate_or_nested_match.rb +36 -0
  34. data/lib/rattler/back_end/optimizer/match_joining.rb +60 -0
  35. data/lib/rattler/back_end/optimizer/optimization.rb +94 -0
  36. data/lib/rattler/back_end/optimizer/optimization_context.rb +72 -0
  37. data/lib/rattler/back_end/optimizer/optimization_sequence.rb +37 -0
  38. data/lib/rattler/back_end/optimizer/optimize_children.rb +46 -0
  39. data/lib/rattler/back_end/optimizer/reduce_repeat_match.rb +44 -0
  40. data/lib/rattler/back_end/optimizer/remove_meaningless_wrapper.rb +32 -0
  41. data/lib/rattler/back_end/optimizer/simplify_redundant_repeat.rb +43 -0
  42. data/lib/rattler/back_end/optimizer/simplify_token_match.rb +38 -0
  43. data/lib/rattler/back_end/parser_generator.rb +21 -14
  44. data/lib/rattler/back_end/parser_generator/apply_generator.rb +35 -35
  45. data/lib/rattler/back_end/parser_generator/assert_generator.rb +29 -30
  46. data/lib/rattler/back_end/parser_generator/back_reference_generator.rb +93 -0
  47. data/lib/rattler/back_end/parser_generator/choice_generator.rb +33 -49
  48. data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +14 -14
  49. data/lib/rattler/back_end/parser_generator/disallow_generator.rb +29 -30
  50. data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +11 -13
  51. data/lib/rattler/back_end/parser_generator/expr_generator.rb +36 -56
  52. data/lib/rattler/back_end/parser_generator/fail_generator.rb +18 -18
  53. data/lib/rattler/back_end/parser_generator/group_match.rb +18 -0
  54. data/lib/rattler/back_end/parser_generator/group_match_generator.rb +76 -0
  55. data/lib/rattler/back_end/parser_generator/label_generator.rb +25 -6
  56. data/lib/rattler/back_end/parser_generator/list1_generator.rb +7 -7
  57. data/lib/rattler/back_end/parser_generator/list_generating.rb +19 -20
  58. data/lib/rattler/back_end/parser_generator/list_generator.rb +5 -5
  59. data/lib/rattler/back_end/parser_generator/match_generator.rb +52 -52
  60. data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +6 -6
  61. data/lib/rattler/back_end/parser_generator/optional_generator.rb +30 -29
  62. data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +8 -8
  63. data/lib/rattler/back_end/parser_generator/repeat_generating.rb +23 -25
  64. data/lib/rattler/back_end/parser_generator/rule_generator.rb +27 -79
  65. data/lib/rattler/back_end/parser_generator/rule_set_generator.rb +102 -0
  66. data/lib/rattler/back_end/parser_generator/sequence_generator.rb +49 -41
  67. data/lib/rattler/back_end/parser_generator/skip_generator.rb +14 -20
  68. data/lib/rattler/back_end/parser_generator/skip_propogating.rb +4 -4
  69. data/lib/rattler/back_end/parser_generator/sub_generating.rb +6 -0
  70. data/lib/rattler/back_end/parser_generator/token_generator.rb +12 -12
  71. data/lib/rattler/back_end/parser_generator/token_propogating.rb +2 -2
  72. data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +4 -4
  73. data/lib/rattler/grammar.rb +4 -3
  74. data/lib/rattler/grammar/analysis.rb +91 -0
  75. data/lib/rattler/grammar/grammar.rb +37 -25
  76. data/lib/rattler/grammar/grammar_parser.rb +19 -11
  77. data/lib/rattler/grammar/metagrammar.rb +569 -800
  78. data/lib/rattler/grammar/rattler.rtlr +162 -144
  79. data/lib/rattler/parsers.rb +5 -1
  80. data/lib/rattler/parsers/action_code.rb +29 -15
  81. data/lib/rattler/parsers/apply.rb +5 -5
  82. data/lib/rattler/parsers/assert.rb +4 -18
  83. data/lib/rattler/parsers/back_reference.rb +46 -0
  84. data/lib/rattler/parsers/choice.rb +6 -39
  85. data/lib/rattler/parsers/combinator_parser.rb +32 -0
  86. data/lib/rattler/parsers/combining.rb +3 -29
  87. data/lib/rattler/parsers/direct_action.rb +27 -30
  88. data/lib/rattler/parsers/disallow.rb +4 -18
  89. data/lib/rattler/parsers/dispatch_action.rb +30 -25
  90. data/lib/rattler/parsers/label.rb +9 -18
  91. data/lib/rattler/parsers/list.rb +3 -34
  92. data/lib/rattler/parsers/list1.rb +4 -36
  93. data/lib/rattler/parsers/list_parser.rb +64 -0
  94. data/lib/rattler/parsers/match.rb +7 -42
  95. data/lib/rattler/parsers/node_code.rb +44 -0
  96. data/lib/rattler/parsers/one_or_more.rb +7 -27
  97. data/lib/rattler/parsers/optional.rb +5 -25
  98. data/lib/rattler/parsers/parser.rb +16 -44
  99. data/lib/rattler/parsers/parser_dsl.rb +13 -3
  100. data/lib/rattler/parsers/predicate.rb +4 -12
  101. data/lib/rattler/parsers/rule.rb +18 -19
  102. data/lib/rattler/parsers/rule_set.rb +63 -0
  103. data/lib/rattler/parsers/sequence.rb +12 -46
  104. data/lib/rattler/parsers/skip.rb +12 -26
  105. data/lib/rattler/parsers/token.rb +6 -21
  106. data/lib/rattler/parsers/zero_or_more.rb +6 -26
  107. data/lib/rattler/runner.rb +66 -28
  108. data/lib/rattler/runtime/extended_packrat_parser.rb +26 -20
  109. data/lib/rattler/runtime/packrat_parser.rb +17 -21
  110. data/lib/rattler/runtime/parser.rb +12 -2
  111. data/lib/rattler/runtime/recursive_descent_parser.rb +3 -11
  112. data/lib/rattler/util.rb +2 -1
  113. data/lib/rattler/util/graphviz.rb +29 -0
  114. data/lib/rattler/util/graphviz/digraph_builder.rb +71 -0
  115. data/lib/rattler/util/graphviz/node_builder.rb +84 -0
  116. data/lib/rattler/util/node.rb +37 -19
  117. data/lib/rattler/util/parser_spec_helper.rb +61 -35
  118. data/spec/rattler/back_end/compiler_spec.rb +6 -860
  119. data/spec/rattler/back_end/optimizer/flatten_choice_spec.rb +70 -0
  120. data/spec/rattler/back_end/optimizer/flatten_sequence_spec.rb +130 -0
  121. data/spec/rattler/back_end/optimizer/inline_regular_rules_spec.rb +80 -0
  122. data/spec/rattler/back_end/optimizer/join_match_capturing_sequence_spec.rb +241 -0
  123. data/spec/rattler/back_end/optimizer/join_match_choice_spec.rb +100 -0
  124. data/spec/rattler/back_end/optimizer/join_match_matching_sequence_spec.rb +112 -0
  125. data/spec/rattler/back_end/optimizer/join_predicate_bare_match_spec.rb +194 -0
  126. data/spec/rattler/back_end/optimizer/join_predicate_nested_match_spec.rb +180 -0
  127. data/spec/rattler/back_end/optimizer/join_predicate_or_bare_match_spec.rb +153 -0
  128. data/spec/rattler/back_end/optimizer/join_predicate_or_nested_match_spec.rb +153 -0
  129. data/spec/rattler/back_end/optimizer/reduce_repeat_match_spec.rb +98 -0
  130. data/spec/rattler/back_end/optimizer/simplify_redundant_repeat_spec.rb +226 -0
  131. data/spec/rattler/back_end/optimizer/simplify_token_match_spec.rb +85 -0
  132. data/spec/rattler/back_end/parser_generator/apply_generator_spec.rb +38 -33
  133. data/spec/rattler/back_end/parser_generator/assert_generator_spec.rb +38 -33
  134. data/spec/rattler/back_end/parser_generator/back_reference_generator_spec.rb +181 -0
  135. data/spec/rattler/back_end/parser_generator/choice_generator_spec.rb +38 -33
  136. data/spec/rattler/back_end/parser_generator/direct_action_generator_spec.rb +38 -33
  137. data/spec/rattler/back_end/parser_generator/disallow_generator_spec.rb +38 -33
  138. data/spec/rattler/back_end/parser_generator/dispatch_action_generator_spec.rb +38 -33
  139. data/spec/rattler/back_end/parser_generator/group_match_generator_spec.rb +185 -0
  140. data/spec/rattler/back_end/parser_generator/label_generator_spec.rb +38 -33
  141. data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +10 -5
  142. data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +10 -5
  143. data/spec/rattler/back_end/parser_generator/match_generator_spec.rb +38 -33
  144. data/spec/rattler/back_end/parser_generator/one_or_more_generator_spec.rb +38 -33
  145. data/spec/rattler/back_end/parser_generator/optional_generator_spec.rb +38 -33
  146. data/spec/rattler/back_end/parser_generator/rule_generator_spec.rb +13 -46
  147. data/spec/rattler/back_end/parser_generator/rule_set_generator_spec.rb +97 -0
  148. data/spec/rattler/back_end/parser_generator/sequence_generator_spec.rb +38 -33
  149. data/spec/rattler/back_end/parser_generator/skip_generator_spec.rb +38 -33
  150. data/spec/rattler/back_end/parser_generator/token_generator_spec.rb +38 -33
  151. data/spec/rattler/back_end/parser_generator/zero_or_more_generator_spec.rb +39 -34
  152. data/spec/rattler/back_end/shared_compiler_examples.rb +885 -0
  153. data/spec/rattler/grammar/analysis_spec.rb +167 -0
  154. data/spec/rattler/grammar/grammar_parser_spec.rb +169 -179
  155. data/spec/rattler/grammar/grammar_spec.rb +24 -21
  156. data/spec/rattler/parsers/action_code_spec.rb +64 -19
  157. data/spec/rattler/parsers/apply_spec.rb +9 -9
  158. data/spec/rattler/parsers/back_reference_spec.rb +38 -0
  159. data/spec/rattler/parsers/combinator_parser_spec.rb +14 -0
  160. data/spec/rattler/parsers/direct_action_spec.rb +16 -2
  161. data/spec/rattler/parsers/dispatch_action_spec.rb +15 -32
  162. data/spec/rattler/parsers/fail_spec.rb +6 -4
  163. data/spec/rattler/parsers/label_spec.rb +10 -28
  164. data/spec/rattler/parsers/node_code_spec.rb +48 -0
  165. data/spec/rattler/parsers/parser_dsl_spec.rb +1 -1
  166. data/spec/rattler/parsers/rule_set_spec.rb +35 -0
  167. data/spec/rattler/parsers/sequence_spec.rb +15 -24
  168. data/spec/rattler/runtime/extended_packrat_parser_spec.rb +22 -17
  169. data/spec/rattler/runtime/packrat_parser_spec.rb +1 -1
  170. data/spec/rattler/runtime/parse_node_spec.rb +15 -19
  171. data/spec/rattler/runtime/recursive_descent_parser_spec.rb +1 -1
  172. data/spec/rattler/runtime/shared_parser_examples.rb +61 -28
  173. data/spec/rattler/util/graphviz/node_builder_spec.rb +84 -0
  174. data/spec/rattler/util/node_spec.rb +92 -65
  175. data/spec/rattler_spec.rb +16 -16
  176. data/spec/support/combinator_parser_spec_helper.rb +19 -18
  177. data/spec/support/compiler_spec_helper.rb +56 -87
  178. data/spec/support/runtime_parser_spec_helper.rb +6 -14
  179. metadata +117 -22
  180. data/features/grammar/regex.feature +0 -24
  181. data/lib/rattler/parsers/match_joining.rb +0 -67
  182. data/lib/rattler/parsers/rules.rb +0 -43
@@ -4,149 +4,167 @@ grammar Rattler::Grammar::Metagrammar
4
4
 
5
5
  include Rattler::Parsers
6
6
 
7
- %whitespace (SPACE+ | ('#' [^\n]*))* {
8
-
9
- grammar <- heading rules EOF <Grammar>
10
-
11
- heading <- requires module_decl? includes { heading *_ }
12
-
13
- requires <- (~`require` literal ~eol)* { { :requires => _ } }
14
-
15
- module_decl <- ~`parser` constant (~'<' constant)? ~eol { parser_decl *_ }
16
- | ~`grammar` constant ~eol { { :grammar_name => _ } }
17
-
18
- includes <- (~`include` constant ~eol)* { { :includes => _ } }
19
-
20
- rules <- (directive | rule | block_close)+ <Rules>
21
-
22
- directive <- ws_directive | wc_directive
23
-
24
- ws_directive <- ws_decl ~'{' { start_ws _ }
25
- | ws_decl { set_ws _ }
26
-
27
- ws_decl <- ~`%whitespace` unattributed
28
-
29
- wc_directive <- wc_decl ~'{' { start_wc _ }
30
- | wc_decl { set_wc _ }
31
-
32
- wc_decl <- ~`%word_character` unattributed
33
-
34
- block_close <- ~'}' { end_block }
35
-
36
- rule <- identifier ~'<-' expression { rule *_ }
37
-
38
- unattributed <- unattributed ~'|' terms <Choice>
39
- | terms
40
-
41
- expression <- expression ~'|' attributed <Choice>
42
- | attributed
43
-
44
- attributed <- attributed ~'<' dispatch? ~'>' <DispatchAction>
45
- | attributed ~'{' action ~'}' <DirectAction>
46
- | terms
47
-
48
- dispatch <- @(name (~'.' var_name)?)
49
-
50
- action <- @(('{' [^}]* '}' | [^{}])*)
51
-
52
- terms <- terms term <Sequence>
53
- | term
54
-
55
- term <- fail_expr | labeled | labelable
56
-
57
- fail_expr <- (`fail` | `fail_rule` | `fail_parse`) fail_arg <Fail>
58
-
59
- fail_arg <- ~'(' literal ~')'
60
- | literal
61
-
62
- labeled <- var_name ~':' labelable <Label>
63
-
64
- labelable <- list | list_term
65
-
66
- list <- list_term ~'*^' list_term <List>
67
- | list_term ~'+^' list_term <List1>
68
-
69
- list_term <- prefixed | prefixable
70
-
71
- prefixed <- ~'&' prefixable <Assert>
72
- | ~'!' prefixable <Disallow>
73
- | ~'~' prefixable <Skip>
74
- | ~'@' prefixable <Token>
75
-
76
- prefixable <- suffixed | primary
77
-
78
- suffixed <- primary ~'?' <Optional>
79
- | primary ~'*' !'^' <ZeroOrMore>
80
- | primary ~'+' !'^' <OneOrMore>
81
-
82
- primary <- ~'(' expression ~')'
83
- | atom
84
-
85
- atom <- `EOF` <Eof>
86
- | posix_class { posix_class _ }
87
- | identifier !'<-' <Apply>
88
- | literal { literal _ }
89
- | word_literal { word_literal _ }
90
- | class { char_class _ }
91
- | regexp <Match>
92
- | ~'.' { Match[/./] }
93
-
94
- posix_class <- `ALNUM`
95
- | `ALPHA`
96
- | `ASCII`
97
- | `BLANK`
98
- | `CNTRL`
99
- | `DIGIT`
100
- | `GRAPH`
101
- | `LOWER`
102
- | `PRINT`
103
- | `PUNCT`
104
- | `SPACE`
105
- | `UPPER`
106
- | `XDIGIT`
107
- | `WORD`
108
-
109
- literal <- /(["'])(?:\\.|(?:(?!\1).))*\1/
110
-
111
- word_literal <- @("`" ('\\' . | [^`])* "`")
112
-
113
- class <- @('[' (!']' range)+ ']')
114
-
115
- regexp <- /\/(?:\\.|[^\/])+\/(?:[iomx]+(?!\w))?/
116
-
117
- name <- var_name
118
- | constant
119
-
120
- identifier <- !`EOF` @WORD+
121
-
122
- var_name <- @(LOWER WORD*)
123
-
124
- constant <- @((const_name '::')* const_name)
125
-
126
- const_name <- @(UPPER WORD*)
7
+ %whitespace (SPACE+ / comment)* {
8
+
9
+ grammar <- heading rules EOF <Grammar>
10
+
11
+ heading <- requires module_decl? includes { heading *_ }
12
+
13
+ requires <- (~`require` @(!eol .)+ ~eol)* { { :requires => _ } }
14
+
15
+ module_decl <- ~`parser` constant (~'<' constant)? ~eol { parser_decl *_ }
16
+ / ~`grammar` constant ~eol { { :grammar_name => _ } }
17
+
18
+ includes <- (~`include` constant ~eol)* { { :includes => _ } }
19
+
20
+ rules <- (directive / rule / block_close)+ <RuleSet>
21
+
22
+ directive <- ws_directive / wc_directive / inline_directive
23
+
24
+ ws_directive <- ws_decl ~'{' { start_ws _ }
25
+ / ws_decl { set_ws _ }
26
+
27
+ ws_decl <- ~`%whitespace` unattributed
28
+
29
+ wc_directive <- wc_decl ~'{' { start_wc _ }
30
+ / wc_decl { set_wc _ }
31
+
32
+ wc_decl <- ~`%word_character` unattributed
33
+
34
+ inline_directive <- ~`%inline` ~'{' { start_inline }
35
+ / ~`%inline` { set_inline }
36
+
37
+ block_close <- ~'}' { end_block }
38
+
39
+ rule <- identifier ~'<-' expression { rule *_ }
40
+
41
+ unattributed <- unattributed ~'/' terms <Choice>
42
+ / terms
43
+
44
+ expression <- expression ~'/' attributed <Choice>
45
+ / attributed
46
+
47
+ attributed <- attributed ~'<' node_action? ~'>' <DispatchAction>
48
+ / attributed ~'{' action ~'}' <DirectAction>
49
+ / terms
50
+
51
+ node_action <- @(name (~'.' var_name)?)
52
+
53
+ action <- @( ('{' [^}]* '}'
54
+ / [^{}])* )
55
+
56
+ terms <- terms term <Sequence>
57
+ / term
58
+
59
+ term <- fail_expr / labeled / labelable
60
+
61
+ fail_expr <- (`fail` / `fail_rule` / `fail_parse`) fail_arg <Fail>
62
+
63
+ fail_arg <- ~'(' literal ~')'
64
+ / literal
65
+
66
+ labeled <- var_name ~':' labelable <Label>
67
+
68
+ labelable <- list
69
+ / list_term
70
+
71
+ list <- list_term ~'*,' list_term <List>
72
+ / list_term ~'+,' list_term <List1>
73
+
74
+ list_term <- prefixed
75
+ / prefixable
76
+ / fail 'term expected'
77
+
78
+ prefixed <- ~'&' prefixable <Assert>
79
+ / ~'!' prefixable <Disallow>
80
+ / ~'~' prefixable <Skip>
81
+ / ~'@' prefixable <Token>
82
+
83
+ prefixable <- suffixed / primary
84
+
85
+ suffixed <- primary ~'?' <Optional>
86
+ / primary ~'*' !',' <ZeroOrMore>
87
+ / primary ~'+' !',' <OneOrMore>
88
+
89
+ primary <- ~'(' expression ~')'
90
+ / atom
91
+
92
+ atom <- ~`EOF` <Eof>
93
+ / posix_class { posix_class _ }
94
+ / identifier !'<-' <Apply>
95
+ / literal { literal _ }
96
+ / word_literal { word_literal _ }
97
+ / class { char_class _ }
98
+ / back_reference <BackReference>
99
+ / ~'.' { Match[/./] }
100
+ / fail 'atom expected'
101
+
102
+ %inline
103
+
104
+ posix_class <- `ALNUM`
105
+ / `ALPHA`
106
+ / `ASCII`
107
+ / `BLANK`
108
+ / `CNTRL`
109
+ / `DIGIT`
110
+ / `GRAPH`
111
+ / `LOWER`
112
+ / `PRINT`
113
+ / `PUNCT`
114
+ / `SPACE`
115
+ / `UPPER`
116
+ / `XDIGIT`
117
+ / `WORD`
118
+ / fail 'posix_class expected'
119
+
120
+ literal <- @('"' ('\\' . / [^"])* '"')
121
+ / @("'" ('\\' . / [^'])* "'")
122
+ / @('%(' ('\\' . / [^)])* ')')
123
+ / @('%{' ('\\' . / [^}])* '}')
124
+ / @('%[' ('\\' . / [^\]])* ']')
125
+ / @('%<' ('\\' . / [^>])* '>')
126
+ / @('%' q:PUNCT ('\\' . / !$q .)* $q)
127
+
128
+ word_literal <- @("`" ('\\' . / [^`])* "`")
129
+
130
+ class <- @('[' (!']' range)+ ']')
131
+
132
+ name <- var_name
133
+ / constant
134
+
135
+ identifier <- !`EOF` @WORD+
136
+
137
+ back_reference <- @('$' LOWER WORD*)
138
+
139
+ var_name <- @(LOWER WORD*)
140
+
141
+ constant <- @((UPPER WORD* '::')* UPPER WORD*)
142
+
143
+ const_name <- @(UPPER WORD*)
127
144
  }
128
145
 
129
- range <- @( '[:' posix_name ':]'
130
- | class_char ('-' class_char)?)
131
-
132
- posix_name <- `alnum`
133
- | `alpha`
134
- | `ascii`
135
- | `blank`
136
- | `cntrl`
137
- | `digit`
138
- | `graph`
139
- | `lower`
140
- | `print`
141
- | `punct`
142
- | `space`
143
- | `upper`
144
- | `xdigit`
145
- | `word`
146
-
147
- class_char <- @( '\\' [0-3] [0-7] [0-7]
148
- | '\\x' XDIGIT XDIGIT
149
- | '\\' .
150
- | [^\\\]] )
151
-
152
- eol <- ~(BLANK* (EOF | ';' | ("\r"? "\n") | ('#' [^\n]*)))
146
+ range <- @( '[:' posix_name ':]'
147
+ / class_char ('-' class_char)?)
148
+
149
+ posix_name <- `alnum`
150
+ / `alpha`
151
+ / `ascii`
152
+ / `blank`
153
+ / `cntrl`
154
+ / `digit`
155
+ / `graph`
156
+ / `lower`
157
+ / `print`
158
+ / `punct`
159
+ / `space`
160
+ / `upper`
161
+ / `xdigit`
162
+
163
+ class_char <- @( '\\' [0-3] [0-7] [0-7]
164
+ / '\\x' XDIGIT XDIGIT
165
+ / '\\' .
166
+ / [^\\\]] )
167
+
168
+ eol <- ~(BLANK* (EOF / ';' / ("\r"? "\n") / ('#' [^\n]*)))
169
+
170
+ comment <- ~('#' [^\n]*)
@@ -16,7 +16,8 @@ module Rattler
16
16
  module Parsers
17
17
 
18
18
  autoload :Parser, 'rattler/parsers/parser'
19
- autoload :Rules, 'rattler/parsers/rules'
19
+ autoload :CombinatorParser, 'rattler/parsers/combinator_parser'
20
+ autoload :RuleSet, 'rattler/parsers/rule_set'
20
21
  autoload :Rule, 'rattler/parsers/rule'
21
22
  autoload :Match, 'rattler/parsers/match'
22
23
  autoload :Choice, 'rattler/parsers/choice'
@@ -24,6 +25,7 @@ module Rattler
24
25
  autoload :Optional, 'rattler/parsers/optional'
25
26
  autoload :ZeroOrMore, 'rattler/parsers/zero_or_more'
26
27
  autoload :OneOrMore, 'rattler/parsers/one_or_more'
28
+ autoload :ListParser, 'rattler/parsers/list_parser'
27
29
  autoload :List, 'rattler/parsers/list'
28
30
  autoload :List1, 'rattler/parsers/list1'
29
31
  autoload :Apply, 'rattler/parsers/apply'
@@ -35,12 +37,14 @@ module Rattler
35
37
  autoload :Token, 'rattler/parsers/token'
36
38
  autoload :Skip, 'rattler/parsers/skip'
37
39
  autoload :Label, 'rattler/parsers/label'
40
+ autoload :BackReference, 'rattler/parsers/back_reference'
38
41
  autoload :Fail, 'rattler/parsers/fail'
39
42
  autoload :ParserDSL, 'rattler/parsers/parser_dsl'
40
43
  autoload :Predicate, 'rattler/parsers/predicate'
41
44
  autoload :Combining, 'rattler/parsers/combining'
42
45
  autoload :MatchJoining, 'rattler/parsers/match_joining'
43
46
  autoload :ActionCode, 'rattler/parsers/action_code'
47
+ autoload :NodeCode, 'rattler/parsers/node_code'
44
48
 
45
49
  class <<self
46
50
  # Define parse rules with the given block
@@ -23,21 +23,31 @@ module Rattler::Parsers
23
23
 
24
24
  attr_reader :param_names, :body
25
25
 
26
- def bind(*args)
27
- bindings = {}
28
- if args.first.respond_to?(:to_ary)
29
- a = args.shift
30
- bindings.merge!(blank_binding(a)).merge!(arg_bindings(a))
31
- end
32
- bindings.merge!(args.shift) unless args.empty?
33
- bind_in body, bindings
26
+ def bind(scope, bind_args)
27
+ bind_in body, scoped_bindings(scope, bind_args)
28
+ end
29
+
30
+ def scoped_bindings(scope, bind_args)
31
+ to_bindings(scope).
32
+ merge(blank_binding(bind_args)).
33
+ merge(arg_bindings(bind_args))
34
34
  end
35
35
 
36
36
  def blank_binding(args)
37
37
  case args.size
38
- when 0 then {}
39
- when 1 then { '_' => args.first }
40
- else { '_' => '[' + args.join(', ') + ']' }
38
+
39
+ when 0
40
+ {}
41
+
42
+ when 1
43
+ { /\*_\b/ => args.first,
44
+ /\b_\b/ => args.first }
45
+
46
+ else
47
+ list = args.join(', ')
48
+ { /\*_\b/ => list,
49
+ /\b_\b/ => '[' + list + ']' }
50
+
41
51
  end
42
52
  end
43
53
 
@@ -45,18 +55,22 @@ module Rattler::Parsers
45
55
  if param_names.count > args.count
46
56
  raise ArgumentError, 'more parameter names than arguments'
47
57
  end
48
- bindings = {}
49
- param_names.zip(args).each {|name, arg| bindings[name] = arg if name }
50
- bindings
58
+ to_bindings param_names.zip(args)
51
59
  end
52
60
 
53
61
  private
54
62
 
63
+ def to_bindings(map)
64
+ bindings = {}
65
+ map.each {|name, arg| bindings[/\b#{name}\b/] = arg if name }
66
+ bindings
67
+ end
68
+
55
69
  def bind_in(code, bindings)
56
70
  new_code = code
57
71
  bindings.each do |k, v|
58
72
  next unless k and v
59
- new_code = new_code.gsub(/\b#{k}\b/, v.to_s)
73
+ new_code = new_code.gsub(k, v.to_s)
60
74
  end
61
75
  new_code
62
76
  end
@@ -14,7 +14,7 @@ module Rattler::Parsers
14
14
  # @author Jason Arhart
15
15
  #
16
16
  class Apply < Parser
17
-
17
+
18
18
  # Create a new parser that parses by applying the parse rule referenced
19
19
  # by +rule_name+.
20
20
  #
@@ -25,20 +25,20 @@ module Rattler::Parsers
25
25
  def self.[](rule_name)
26
26
  self.new(:rule_name => rule_name.to_sym)
27
27
  end
28
-
28
+
29
29
  # @private
30
30
  def self.parsed(results) #:nodoc:
31
31
  self[results.first]
32
32
  end
33
-
33
+
34
34
  # Apply the parse rule referenced by the #rule_name.
35
35
  #
36
36
  # @param (see Parser#parse_labeled)
37
37
  #
38
38
  # @return the result of applying the referenced parse rule
39
- def parse(scanner, rules, labeled = {})
39
+ def parse(scanner, rules, scope = {})
40
40
  (rule = rules[rule_name]) && rule.parse(scanner, rules)
41
41
  end
42
-
42
+
43
43
  end
44
44
  end
@@ -15,33 +15,19 @@ module Rattler::Parsers
15
15
  # @author Jason Arhart
16
16
  #
17
17
  class Assert < Predicate
18
-
18
+
19
19
  # Succeed or fail like the decorated parser but do not consume any input
20
20
  # and return +true+ on success.
21
21
  #
22
22
  # @param (see Parser#parse_labeled)
23
23
  #
24
24
  # @return [Boolean] +true+ if the decorated parser succeeds
25
- def parse(scanner, rules, labeled = {})
25
+ def parse(scanner, rules, scope = {})
26
26
  pos = scanner.pos
27
- result = (child.parse(scanner, rules) && true)
27
+ result = (child.parse(scanner, rules, scope) && true)
28
28
  scanner.pos = pos
29
29
  result
30
30
  end
31
-
32
- # Return a parser that parses identically but may have a more optimized
33
- # structure.
34
- #
35
- # @return a parser that parses identically but may have a more optimized
36
- # structure
37
- def optimized
38
- Assert[child.optimized]
39
- end
40
-
41
- # @private
42
- def as_match #:nodoc:
43
- Match[child.assert_re] if Match === child
44
- end
45
-
31
+
46
32
  end
47
33
  end