rattler 0.2.2 → 0.3.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 (56) hide show
  1. data/README.rdoc +83 -64
  2. data/features/grammar/comments.feature +24 -0
  3. data/features/grammar/list_matching.feature +41 -0
  4. data/features/grammar/symantic_action.feature +30 -12
  5. data/lib/rattler/back_end/parser_generator/assert_generator.rb +27 -27
  6. data/lib/rattler/back_end/parser_generator/choice_generator.rb +29 -29
  7. data/lib/rattler/back_end/parser_generator/direct_action_generator.rb +17 -17
  8. data/lib/rattler/back_end/parser_generator/disallow_generator.rb +27 -27
  9. data/lib/rattler/back_end/parser_generator/dispatch_action_generator.rb +17 -17
  10. data/lib/rattler/back_end/parser_generator/expr_generator.rb +129 -40
  11. data/lib/rattler/back_end/parser_generator/label_generator.rb +15 -15
  12. data/lib/rattler/back_end/parser_generator/list1_generator.rb +61 -0
  13. data/lib/rattler/back_end/parser_generator/list_generating.rb +71 -0
  14. data/lib/rattler/back_end/parser_generator/list_generator.rb +57 -0
  15. data/lib/rattler/back_end/parser_generator/one_or_more_generator.rb +14 -15
  16. data/lib/rattler/back_end/parser_generator/optional_generator.rb +24 -24
  17. data/lib/rattler/back_end/parser_generator/predicate_propogating.rb +9 -9
  18. data/lib/rattler/back_end/parser_generator/repeat_generating.rb +16 -16
  19. data/lib/rattler/back_end/parser_generator/sequence_generator.rb +40 -40
  20. data/lib/rattler/back_end/parser_generator/skip_generator.rb +18 -18
  21. data/lib/rattler/back_end/parser_generator/skip_propogating.rb +5 -5
  22. data/lib/rattler/back_end/parser_generator/sub_generating.rb +128 -0
  23. data/lib/rattler/back_end/parser_generator/token_generator.rb +15 -15
  24. data/lib/rattler/back_end/parser_generator/token_propogating.rb +1 -1
  25. data/lib/rattler/back_end/parser_generator/zero_or_more_generator.rb +12 -13
  26. data/lib/rattler/back_end/parser_generator.rb +10 -7
  27. data/lib/rattler/grammar/grammar_parser.rb +16 -21
  28. data/lib/rattler/grammar/metagrammar.rb +1039 -1035
  29. data/lib/rattler/grammar/rattler.rtlr +28 -28
  30. data/lib/rattler/parsers/action_code.rb +20 -9
  31. data/lib/rattler/parsers/fail.rb +7 -1
  32. data/lib/rattler/parsers/list.rb +57 -0
  33. data/lib/rattler/parsers/list1.rb +58 -0
  34. data/lib/rattler/parsers/parser_dsl.rb +60 -38
  35. data/lib/rattler/parsers.rb +5 -3
  36. data/lib/rattler/runtime/extended_packrat_parser.rb +88 -20
  37. data/lib/rattler/runtime/packrat_parser.rb +21 -14
  38. data/lib/rattler/runtime/parser.rb +74 -18
  39. data/lib/rattler/runtime/recursive_descent_parser.rb +15 -46
  40. data/spec/rattler/back_end/compiler_spec.rb +173 -107
  41. data/spec/rattler/back_end/parser_generator/list1_generator_spec.rb +304 -0
  42. data/spec/rattler/back_end/parser_generator/list_generator_spec.rb +288 -0
  43. data/spec/rattler/grammar/grammar_parser_spec.rb +65 -76
  44. data/spec/rattler/parsers/action_code_spec.rb +84 -34
  45. data/spec/rattler/parsers/direct_action_spec.rb +56 -34
  46. data/spec/rattler/parsers/fail_spec.rb +20 -0
  47. data/spec/rattler/parsers/list1_spec.rb +82 -0
  48. data/spec/rattler/parsers/list_spec.rb +82 -0
  49. data/spec/rattler/parsers/parser_dsl_spec.rb +48 -19
  50. data/spec/rattler/runtime/extended_packrat_parser_spec.rb +0 -1
  51. metadata +92 -173
  52. data/bin/rtlr.bat +0 -3
  53. data/lib/rattler/back_end/parser_generator/generator_helper.rb +0 -130
  54. data/lib/rattler/back_end/parser_generator/generators.rb +0 -86
  55. data/lib/rattler/back_end/parser_generator/nested_generators.rb +0 -15
  56. data/lib/rattler/back_end/parser_generator/top_level_generators.rb +0 -15
data/README.rdoc CHANGED
@@ -14,13 +14,13 @@ A language syntax is specified in a grammar using the Rattler syntax. Parser
14
14
  classes and modules can be generated statically using the "rtlr" command or
15
15
  dynamically from strings.
16
16
 
17
- {RDoc}[http://rubydoc.info/gems/rattler/0.2.1/frames]
17
+ {RDoc}[http://rubydoc.info/gems/rattler/0.2.2/frames]
18
18
 
19
19
  == FEATURES:
20
20
 
21
21
  * Uses readable PEG-like grammars
22
22
  * A packrat parser to cache results for backtracking
23
- * A parser that supports directly left-recursive grammars
23
+ * An extended packrat parser that supports left-recursive grammars
24
24
  * Whitespace can be specified in one place and skipped automatically
25
25
  * Automatic and custom parse error reporting
26
26
  * Optimizing parser generator
@@ -30,91 +30,109 @@ dynamically from strings.
30
30
 
31
31
  == PROBLEMS/LIMITATIONS:
32
32
 
33
- * Indirect left-recursion is not yet supported
34
33
  * Optimizations are very limited at this point
35
34
  * Only strings can be parsed, so files have to be read completely before parsing
36
- * There are undoubtedly many bugs
35
+ * There are many holes in the tests so there are undoubtedly many bugs
37
36
 
38
37
  == EXAMPLES:
39
38
 
40
39
  === Example 1: Statically generated parser class
41
40
 
42
- ==== In file calculator.rtlr:
41
+ ==== json.rtlr:
43
42
 
44
- parser Calculator < Rattler::Runtime::WDMParser
45
-
46
- %whitespace SPACE*
47
-
48
- start <- expr EOF
49
-
50
- expr <- expr ~'+' term {|a, b| a + b }
51
- | expr ~'-' term {|a, b| a - b }
52
- | term
53
-
54
- term <- term ~'*' primary {|a, b| a * b }
55
- | term ~'/' primary {|a, b| a / b }
56
- | primary
57
-
58
- primary <- ~'(' expr ~')'
59
- | @(DIGIT+ ('.' DIGIT+)?) {|_| _.to_f }
60
-
61
- ==== In a shell:
43
+ # JSON parser based on the grammar at http://www.json.org
44
+
45
+ parser JsonParser < Rattler::Runtime::PackratParser
46
+
47
+ %whitespace (SPACE+ | '/*' (! '*/' .)* '*/' | '//' [^\n]*)*
48
+
49
+ object <- ~'{' members ~'}' { object _ }
50
+
51
+ members <- pair *^ ','
52
+
53
+ pair <- string ~':' value
54
+
55
+ array <- ~'[' elements ~']'
56
+
57
+ elements <- value *^ ','
58
+
59
+ value <- string { string _ }
60
+ | number !DIGIT { _.to_f }
61
+ | object
62
+ | array
63
+ | `true` { :true }
64
+ | `false` { :false }
65
+ | `null` { :null }
66
+ | fail "value expected"
67
+
68
+ string <- @('"' ('\\' . | [^"])* '"')
69
+
70
+ number <- @('-'? ('0' | [1-9] DIGIT*) ('.' DIGIT+)? ([eE] [+-]? DIGIT+)?)
71
+
72
+ ==== json_helper.rb:
73
+
74
+ module JsonHelper
75
+
76
+ def object(members)
77
+ Hash[*members.flatten(1)]
78
+ end
79
+
80
+ def string(expr)
81
+ eval expr, TOPLEVEL_BINDING
82
+ end
83
+
84
+ end
85
+
86
+ ==== $ rtlr json.rtlr
62
87
 
63
- $ rtlr calculator.rtlr
64
- calculator.rtlr -> calculator.rb
88
+ json.rtlr -> json_parser.rb
65
89
 
66
- ==== In file calculator.rb:
90
+ ==== parse_json.rb:
67
91
 
68
92
  require 'rubygems'
69
93
  require 'rattler'
70
- require 'calculator'
94
+ require 'json_parser'
71
95
 
72
96
  begin
73
- puts Calculator.parse!(expr)
97
+ p JsonParser.parse!(open(ARGV[0]) {|io| io.read })
74
98
  rescue Rattler::Runtime::SyntaxError => e
75
99
  puts e
76
100
  end
77
101
 
78
102
  === Example 2: Statically generated grammar module
79
103
 
80
- ==== calculator.rtlr:
81
-
82
- grammar CalculatorGrammar
83
-
84
- %whitespace SPACE*
85
-
86
- start <- expr EOF
104
+ ==== json.rtlr:
87
105
 
88
- expr <- expr ~'+' term {|a, b| a + b }
89
- | expr ~'-' term {|a, b| a - b }
90
- | term
91
-
92
- term <- term ~'*' primary {|a, b| a * b }
93
- | term ~'/' primary {|a, b| a / b }
94
- | primary
95
-
96
- primary <- ~'(' expr ~')'
97
- | @(DIGIT+ ('.' DIGIT+)?) {|_| _.to_f }
106
+ # JSON parser based on the grammar at http://www.json.org
107
+
108
+ grammar JsonGrammar
109
+
110
+ %whitespace (SPACE+ | '/*' (! '*/' .)* '*/' | '//' [^\n]*)*
111
+
112
+ ...
98
113
 
99
- ==== In a shell:
114
+ ==== $ rtlr json.rtlr
100
115
 
101
- $ rtlr calculator.rtlr
102
- calculator.rtlr -> calculator_grammar.rb
116
+ json.rtlr -> json_grammar.rb
103
117
 
104
- ==== calculator.rb:
118
+ ==== json_parser.rb:
105
119
 
106
120
  require 'rubygems'
107
121
  require 'rattler'
108
- require 'calculator_grammar'
122
+ require 'json_grammar'
109
123
 
110
- class Calculator < Rattler::Runtime::WDMParser
111
- include CalculatorGrammar
112
- end
113
-
114
- begin
115
- puts Calculator.parse!(expr)
116
- rescue Rattler::Runtime::SyntaxError => e
117
- puts e
124
+ class JsonParser < Rattler::Runtime::PackratParser
125
+
126
+ include JsonGrammar
127
+
128
+ def object(members)
129
+ Hash[*members.flatten(1)]
130
+ end
131
+
132
+ def string(expr)
133
+ eval expr, TOPLEVEL_BINDING
134
+ end
135
+
118
136
  end
119
137
 
120
138
  === Example 3: Dynamically generated parser class
@@ -127,17 +145,18 @@ dynamically from strings.
127
145
 
128
146
  start <- expr EOF
129
147
 
130
- expr <- expr ~'+' term {|a, b| a + b }
131
- | expr ~'-' term {|a, b| a - b }
148
+ expr <- expr ~'+' term {|a, b| a + b }
149
+ | expr ~'-' term {|a, b| a - b }
132
150
  | term
133
151
 
134
- term <- term ~'*' primary {|a, b| a * b }
135
- | term ~'/' primary {|a, b| a / b }
152
+ term <- term ~'*' primary {|a, b| a * b }
153
+ | term ~'/' primary {|a, b| a / b }
136
154
  | primary
137
155
 
138
156
  primary <- ~'(' expr ~')'
139
- | @(DIGIT+ ('.' DIGIT+)?) {|_| _.to_f }
140
- }, :type => :wdm
157
+ | @('-'? DIGIT+ '.' DIGIT+) { _.to_f }
158
+ | @('-'? DIGIT+) { _.to_i }
159
+ }, :type => :extended_packrat
141
160
 
142
161
  begin
143
162
  puts Calculator.parse!(expr)
@@ -0,0 +1,24 @@
1
+ Feature: Whitespace
2
+
3
+ Comments start with "#" and continue to the end of the line.
4
+
5
+ In order to clarify my grammars
6
+ As a language designer
7
+ I want to use comments
8
+
9
+ Scenario: Entire line as a comment
10
+ Given a grammar with:
11
+ """
12
+ # match one or more alphanumeric or underscore characters
13
+ word <- @WORD+
14
+ """
15
+ When I parse "foo"
16
+ Then the parse result should be "foo"
17
+
18
+ Scenario: Comment at the end of a line
19
+ Given a grammar with:
20
+ """
21
+ word <- @WORD+ # WORD matches any alphanumeric or underscore character
22
+ """
23
+ When I parse "foo"
24
+ Then the parse result should be "foo"
@@ -0,0 +1,41 @@
1
+ Feature: List Matching
2
+
3
+ An term expression followed by "*^" or "+^" and a separator expression means
4
+ to match a list of terms with separators between them. "*^" matches a list of
5
+ zero or more terms, "+^" matches a list of one or more term.
6
+
7
+ In order to clearly and easily match list expressions
8
+ As a language designer
9
+ I want to use a list-matching expression
10
+
11
+ Scenario Outline: Zero or more terms
12
+ Given a grammar with:
13
+ """
14
+ words <- @WORD+ *^ ','
15
+ """
16
+ When I parse <input>
17
+ Then the parse result should be <result>
18
+ And the parse position should be <pos>
19
+
20
+ Examples:
21
+ | input | result | pos |
22
+ | "foo" | ["foo"] | 3 |
23
+ | "foo,bar,baz" | ["foo", "bar", "baz"] | 11 |
24
+ | "foo,bar," | ["foo", "bar"] | 7 |
25
+ | " " | [] | 0 |
26
+
27
+ Scenario Outline: One or more terms
28
+ Given a grammar with:
29
+ """
30
+ words <- @WORD+ +^ ','
31
+ """
32
+ When I parse <input>
33
+ Then the parse result should be <result>
34
+ And the parse position should be <pos>
35
+
36
+ Examples:
37
+ | input | result | pos |
38
+ | "foo" | ["foo"] | 3 |
39
+ | "foo,bar,baz" | ["foo", "bar", "baz"] | 11 |
40
+ | "foo,bar," | ["foo", "bar"] | 7 |
41
+ | " " | FAIL | 0 |
@@ -6,7 +6,7 @@ Feature: Symantic Actions
6
6
  specified like Ruby block parameters and are bound to the parse results from
7
7
  the match. If there are fewer parameters than parse results the extra results
8
8
  are simply ignored. Labeled parse results can be refered to as identifiers in
9
- the action.
9
+ the action. The special identifier "_" refers to the entire parse results.
10
10
 
11
11
  In order to add simple symantics to parse results
12
12
  As a language designer
@@ -15,19 +15,11 @@ Feature: Symantic Actions
15
15
  Scenario: Single token
16
16
  Given a grammar with:
17
17
  """
18
- integer <- /\d+/ {|_| _.to_i }
18
+ integer <- /\d+/ {|s| s.to_i }
19
19
  """
20
20
  When I parse "42"
21
21
  Then the parse result should be 42
22
22
 
23
- Scenario: Shortcut form
24
- Given a grammar with:
25
- """
26
- integer <- /\d+/ <.to_i>
27
- """
28
- When I parse "23"
29
- Then the parse result should be 23
30
-
31
23
  Scenario: Sequence
32
24
  Given a grammar with:
33
25
  """
@@ -36,7 +28,7 @@ Feature: Symantic Actions
36
28
  """
37
29
  When I parse "3 16"
38
30
  Then the parse result should be 48
39
-
31
+
40
32
  Scenario: Sequence with non-capturing expressions
41
33
  Given a grammar with:
42
34
  """
@@ -51,4 +43,30 @@ Feature: Symantic Actions
51
43
  sum <- "(" left:/\d+/ "+" right:/\d+/ ")" { left.to_i + right.to_i }
52
44
  """
53
45
  When I parse "(17+29)"
54
- Then the parse result should be 46
46
+ Then the parse result should be 46
47
+
48
+ Scenario: Single token using "_"
49
+ Given a grammar with:
50
+ """
51
+ integer <- /\d+/ { _.to_i }
52
+ """
53
+ When I parse "23"
54
+ Then the parse result should be 23
55
+
56
+ Scenario: Sequence using "_"
57
+ Given a grammar with:
58
+ """
59
+ %whitespace SPACE*
60
+ ints <- /\d+/ /\d+/ { _.reverse }
61
+ """
62
+ When I parse "3 16"
63
+ Then the parse result should be ["16", "3"]
64
+
65
+ Scenario: Sequence using "_" as a parameter name
66
+ Given a grammar with:
67
+ """
68
+ %whitespace SPACE*
69
+ ints <- /\d+/ /\d+/ {|_| _.to_i }
70
+ """
71
+ When I parse "3 16"
72
+ Then the parse result should be 3
@@ -1,94 +1,94 @@
1
1
  require 'rattler/back_end/parser_generator'
2
2
 
3
3
  module Rattler::BackEnd::ParserGenerator
4
-
4
+
5
5
  # @private
6
6
  class AssertGenerator < ExprGenerator #:nodoc:
7
-
7
+
8
8
  def gen_basic(assert)
9
- generate assert.child, :gen_assert
9
+ generate assert.child, :assert
10
10
  end
11
-
11
+
12
12
  def gen_assert(assert)
13
13
  gen_basic assert
14
14
  end
15
-
15
+
16
16
  def gen_disallow(assert)
17
17
  @g << 'false'
18
18
  end
19
-
19
+
20
20
  def gen_skip_nested(assert)
21
21
  gen_basic_nested assert
22
22
  end
23
-
23
+
24
24
  def gen_skip_top_level(assert)
25
25
  gen_basic_top_level assert
26
26
  end
27
-
27
+
28
28
  def gen_dispatch_action_nested(assert, target, method_name)
29
29
  atomic_block { gen_dispatch_action_top_level assert, target, method_name }
30
30
  end
31
-
31
+
32
32
  def gen_dispatch_action_top_level(assert, target, method_name)
33
33
  gen_action assert,
34
34
  dispatch_action_result(target, method_name, :array_expr => '[]')
35
35
  end
36
-
36
+
37
37
  def gen_direct_action_nested(assert, code)
38
38
  atomic_block { gen_direct_action_top_level assert, code }
39
39
  end
40
-
40
+
41
41
  def gen_direct_action_top_level(assert, code)
42
42
  gen_action assert, direct_action_result(code)
43
43
  end
44
-
44
+
45
45
  def gen_token_nested(assert)
46
46
  atomic_block { gen_token_top_level assert }
47
47
  end
48
-
48
+
49
49
  def gen_token_top_level(assert)
50
50
  gen_action assert, "''"
51
51
  end
52
-
52
+
53
53
  def gen_intermediate(assert)
54
- generate assert.child, :gen_intermediate_assert
54
+ generate assert.child, :intermediate_assert
55
55
  end
56
-
56
+
57
57
  def gen_intermediate_assert(assert)
58
58
  gen_intermediate assert
59
59
  end
60
-
60
+
61
61
  def gen_intermediate_skip(assert)
62
62
  gen_intermediate assert
63
63
  end
64
-
64
+
65
65
  private
66
-
66
+
67
67
  def gen_action(assert, result_code)
68
68
  gen_intermediate assert
69
69
  (@g << ' &&').newline << result_code
70
70
  end
71
-
71
+
72
72
  end
73
-
73
+
74
74
  # @private
75
75
  class NestedAssertGenerator < AssertGenerator #:nodoc:
76
76
  include Nested
77
- include NestedGenerators
77
+ include NestedSubGenerating
78
78
  end
79
-
79
+
80
80
  def AssertGenerator.nested(*args)
81
81
  NestedAssertGenerator.new(*args)
82
82
  end
83
-
83
+
84
84
  # @private
85
85
  class TopLevelAssertGenerator < AssertGenerator #:nodoc:
86
86
  include TopLevel
87
- include TopLevelGenerators
87
+ include TopLevelSubGenerating
88
88
  end
89
-
89
+
90
90
  def AssertGenerator.top_level(*args)
91
91
  TopLevelAssertGenerator.new(*args)
92
92
  end
93
-
93
+
94
94
  end
@@ -1,88 +1,88 @@
1
1
  require 'rattler/back_end/parser_generator'
2
2
 
3
3
  module Rattler::BackEnd::ParserGenerator
4
-
4
+
5
5
  # @private
6
6
  class ChoiceGenerator < ExprGenerator #:nodoc:
7
- include NestedGenerators
8
-
7
+ include NestedSubGenerating
8
+
9
9
  def gen_basic_nested(choice)
10
10
  atomic_block { gen_basic_top_level choice }
11
11
  end
12
-
12
+
13
13
  def gen_basic_top_level(choice)
14
14
  @g.intersperse_nl(choice, ' ||') {|_| generate _ }
15
15
  end
16
-
16
+
17
17
  def gen_assert_nested(choice)
18
18
  atomic_expr { gen_assert_top_level choice }
19
19
  end
20
-
20
+
21
21
  def gen_assert_top_level(choice)
22
22
  gen_intermediate_assert choice
23
23
  @g << ' && true'
24
24
  end
25
-
25
+
26
26
  def gen_disallow(choice)
27
27
  @g << '!'
28
28
  gen_intermediate_assert choice
29
29
  end
30
-
30
+
31
31
  def gen_dispatch_action_nested(choice, target, method_name)
32
32
  atomic_block { gen_dispatch_action_top_level choice, target, method_name }
33
33
  end
34
-
34
+
35
35
  def gen_dispatch_action_top_level(choice, target, method_name)
36
36
  gen_action_code choice do |labeled|
37
37
  dispatch_action_result(target, method_name, :labeled => labeled)
38
38
  end
39
39
  end
40
-
40
+
41
41
  def gen_direct_action_nested(choice, action)
42
42
  atomic_block { gen_direct_action_top_level choice, action }
43
43
  end
44
-
44
+
45
45
  def gen_direct_action_top_level(choice, action)
46
46
  gen_action_code choice do |labeled|
47
47
  direct_action_result(action, :labeled => labeled)
48
48
  end
49
49
  end
50
-
50
+
51
51
  def gen_token_nested(choice)
52
52
  atomic_block { gen_token_top_level choice }
53
53
  end
54
-
54
+
55
55
  def gen_token_top_level(choice)
56
- @g.intersperse_nl(choice, ' ||') {|_| generate _, :gen_token }
56
+ @g.intersperse_nl(choice, ' ||') {|_| generate _, :token }
57
57
  end
58
-
58
+
59
59
  def gen_skip_nested(choice)
60
60
  @g.surround('(', ')') { gen_skip_top_level choice }
61
61
  end
62
-
62
+
63
63
  def gen_skip_top_level(choice)
64
64
  gen_intermediate_skip choice
65
65
  @g << ' && true'
66
66
  end
67
-
67
+
68
68
  def gen_intermediate_assert(choice)
69
69
  atomic_block do
70
70
  @g.intersperse_nl(choice, ' ||') do |_|
71
- generate _, :gen_intermediate_assert
71
+ generate _, :intermediate_assert
72
72
  end
73
73
  end
74
74
  end
75
-
75
+
76
76
  def gen_intermediate_skip(choice)
77
77
  atomic_block do
78
78
  @g.intersperse_nl(choice, ' ||') do |_|
79
- generate _, :gen_intermediate_skip
79
+ generate _, :intermediate_skip
80
80
  end
81
81
  end
82
82
  end
83
-
83
+
84
84
  private
85
-
85
+
86
86
  def gen_action_code(choice)
87
87
  labeled = choice.any? {|_| _.labeled? } ? labeled_name : nil
88
88
  @g.block("(#{result_name} = begin", 'end)') do
@@ -101,29 +101,29 @@ module Rattler::BackEnd::ParserGenerator
101
101
  end << ' && '
102
102
  @g << yield(labeled)
103
103
  end
104
-
104
+
105
105
  def labeled_name
106
106
  "l#{choice_level}"
107
107
  end
108
-
108
+
109
109
  end
110
-
110
+
111
111
  # @private
112
112
  class NestedChoiceGenerator < ChoiceGenerator #:nodoc:
113
113
  include Nested
114
114
  end
115
-
115
+
116
116
  def ChoiceGenerator.nested(*args)
117
117
  NestedChoiceGenerator.new(*args)
118
118
  end
119
-
119
+
120
120
  # @private
121
121
  class TopLevelChoiceGenerator < ChoiceGenerator #:nodoc:
122
122
  include TopLevel
123
123
  end
124
-
124
+
125
125
  def ChoiceGenerator.top_level(*args)
126
126
  TopLevelChoiceGenerator.new(*args)
127
127
  end
128
-
128
+
129
129
  end
@@ -1,59 +1,59 @@
1
1
  require 'rattler/back_end/parser_generator'
2
2
 
3
3
  module Rattler::BackEnd::ParserGenerator
4
-
4
+
5
5
  # @private
6
6
  class DirectActionGenerator < ExprGenerator #:nodoc:
7
7
  include PredicatePropogating
8
8
  include TokenPropogating
9
9
  include SkipPropogating
10
-
10
+
11
11
  def gen_basic_nested(action)
12
- generate action.child, :gen_direct_action_nested, action.bindable_code
12
+ generate action.child, :direct_action_nested, action.bindable_code
13
13
  end
14
-
14
+
15
15
  def gen_basic_top_level(action)
16
- generate action.child, :gen_direct_action_top_level, action.bindable_code
16
+ generate action.child, :direct_action_top_level, action.bindable_code
17
17
  end
18
-
18
+
19
19
  def gen_dispatch_action_nested(inner, target, method_name)
20
20
  atomic_block { gen_dispatch_action_top_level inner, target, method_name }
21
21
  end
22
-
22
+
23
23
  def gen_dispatch_action_top_level(inner, target, method_name)
24
24
  @g.surround("(#{result_name} = ", ')') { gen_basic_nested inner }
25
25
  (@g << ' &&').newline << dispatch_action_result(target, method_name)
26
26
  end
27
-
27
+
28
28
  def gen_direct_action_nested(inner, code)
29
29
  atomic_block { gen_direct_action_top_level inner, code }
30
30
  end
31
-
31
+
32
32
  def gen_direct_action_top_level(inner, code)
33
33
  @g.surround("(#{result_name} = ", ')') { gen_basic_nested inner }
34
34
  (@g << ' &&').newline << direct_action_result(code)
35
35
  end
36
-
36
+
37
37
  end
38
-
38
+
39
39
  # @private
40
40
  class NestedDirectActionGenerator < DirectActionGenerator #:nodoc:
41
41
  include Nested
42
- include NestedGenerators
42
+ include NestedSubGenerating
43
43
  end
44
-
44
+
45
45
  def DirectActionGenerator.nested(*args)
46
46
  NestedDirectActionGenerator.new(*args)
47
47
  end
48
-
48
+
49
49
  # @private
50
50
  class TopLevelDirectActionGenerator < DirectActionGenerator #:nodoc:
51
51
  include TopLevel
52
- include TopLevelGenerators
52
+ include TopLevelSubGenerating
53
53
  end
54
-
54
+
55
55
  def DirectActionGenerator.top_level(*args)
56
56
  TopLevelDirectActionGenerator.new(*args)
57
57
  end
58
-
58
+
59
59
  end