rattler 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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