antelope 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +25 -25
  3. data/.rspec +3 -3
  4. data/.travis.yml +10 -10
  5. data/.yardopts +7 -7
  6. data/CONTRIBUTING.md +50 -38
  7. data/GENERATORS.md +180 -124
  8. data/Gemfile +7 -7
  9. data/LICENSE.txt +22 -22
  10. data/README.md +240 -104
  11. data/Rakefile +2 -2
  12. data/TODO.md +58 -58
  13. data/antelope.gemspec +29 -28
  14. data/bin/antelope +7 -7
  15. data/examples/deterministic.ace +35 -35
  16. data/examples/example.ace +52 -51
  17. data/examples/example.ace.err +192 -192
  18. data/examples/example.ace.inf +432 -432
  19. data/examples/example.ate +70 -70
  20. data/examples/example.ate.err +192 -192
  21. data/examples/example.ate.inf +432 -432
  22. data/examples/liquidscript.ace +233 -233
  23. data/examples/simple.ace +22 -22
  24. data/lib/antelope/ace/compiler.rb +334 -334
  25. data/lib/antelope/ace/errors.rb +30 -30
  26. data/lib/antelope/ace/scanner/argument.rb +57 -57
  27. data/lib/antelope/ace/scanner/first.rb +89 -89
  28. data/lib/antelope/ace/scanner/second.rb +178 -178
  29. data/lib/antelope/ace/scanner/third.rb +27 -27
  30. data/lib/antelope/ace/scanner.rb +144 -144
  31. data/lib/antelope/ace.rb +47 -47
  32. data/lib/antelope/cli.rb +60 -60
  33. data/lib/antelope/errors.rb +25 -25
  34. data/lib/antelope/generation/constructor/first.rb +86 -86
  35. data/lib/antelope/generation/constructor/follow.rb +105 -105
  36. data/lib/antelope/generation/constructor/nullable.rb +64 -64
  37. data/lib/antelope/generation/constructor.rb +127 -127
  38. data/lib/antelope/generation/errors.rb +17 -17
  39. data/lib/antelope/generation/null.rb +13 -13
  40. data/lib/antelope/generation/recognizer/rule.rb +216 -216
  41. data/lib/antelope/generation/recognizer/state.rb +129 -129
  42. data/lib/antelope/generation/recognizer.rb +177 -177
  43. data/lib/antelope/generation/tableizer.rb +176 -176
  44. data/lib/antelope/generation.rb +15 -15
  45. data/lib/antelope/generator/base/coerce.rb +115 -0
  46. data/lib/antelope/generator/base/extra.rb +50 -0
  47. data/lib/antelope/generator/base.rb +134 -264
  48. data/lib/antelope/generator/c.rb +11 -11
  49. data/lib/antelope/generator/c_header.rb +105 -105
  50. data/lib/antelope/generator/c_source.rb +39 -39
  51. data/lib/antelope/generator/error.rb +34 -34
  52. data/lib/antelope/generator/group.rb +60 -57
  53. data/lib/antelope/generator/html.rb +51 -51
  54. data/lib/antelope/generator/info.rb +47 -47
  55. data/lib/antelope/generator/null.rb +18 -18
  56. data/lib/antelope/generator/output.rb +17 -17
  57. data/lib/antelope/generator/ruby.rb +112 -79
  58. data/lib/antelope/generator/templates/c_header.ant +36 -36
  59. data/lib/antelope/generator/templates/c_source.ant +202 -202
  60. data/lib/antelope/generator/templates/error.erb +40 -0
  61. data/lib/antelope/generator/templates/html/antelope.css +53 -1
  62. data/lib/antelope/generator/templates/html/antelope.html +82 -1
  63. data/lib/antelope/generator/templates/html/antelope.js +9 -1
  64. data/lib/antelope/generator/templates/html/css.ant +53 -53
  65. data/lib/antelope/generator/templates/html/html.ant +82 -82
  66. data/lib/antelope/generator/templates/html/js.ant +9 -9
  67. data/lib/antelope/generator/templates/info.erb +61 -0
  68. data/lib/antelope/generator/templates/{ruby.ant → ruby.erb} +171 -178
  69. data/lib/antelope/generator.rb +62 -66
  70. data/lib/antelope/grammar/generation.rb +76 -76
  71. data/lib/antelope/grammar/loading.rb +84 -84
  72. data/lib/antelope/grammar/precedence.rb +59 -59
  73. data/lib/antelope/grammar/precedences.rb +64 -64
  74. data/lib/antelope/grammar/production.rb +56 -56
  75. data/lib/antelope/grammar/productions.rb +154 -154
  76. data/lib/antelope/grammar/symbols.rb +64 -64
  77. data/lib/antelope/grammar/token/epsilon.rb +23 -23
  78. data/lib/antelope/grammar/token/error.rb +24 -24
  79. data/lib/antelope/grammar/token/nonterminal.rb +15 -15
  80. data/lib/antelope/grammar/token/terminal.rb +15 -15
  81. data/lib/antelope/grammar/token.rb +231 -231
  82. data/lib/antelope/grammar.rb +68 -68
  83. data/lib/antelope/version.rb +6 -6
  84. data/lib/antelope.rb +18 -19
  85. data/optimizations.txt +42 -42
  86. data/spec/antelope/ace/compiler_spec.rb +60 -60
  87. data/spec/antelope/ace/scanner_spec.rb +27 -27
  88. data/spec/antelope/generation/constructor_spec.rb +131 -131
  89. data/spec/fixtures/simple.ace +22 -22
  90. data/spec/spec_helper.rb +39 -39
  91. data/spec/support/benchmark_helper.rb +5 -5
  92. data/spec/support/grammar_helper.rb +14 -14
  93. data/subl/Ace (Ruby).JSON-tmLanguage +94 -94
  94. data/subl/Ace (Ruby).tmLanguage +153 -153
  95. metadata +22 -11
  96. data/lib/antelope/generator/templates/error.ant +0 -34
  97. data/lib/antelope/generator/templates/info.ant +0 -53
  98. data/lib/antelope/template/compiler.rb +0 -78
  99. data/lib/antelope/template/errors.rb +0 -9
  100. data/lib/antelope/template/scanner.rb +0 -109
  101. data/lib/antelope/template.rb +0 -64
  102. data/spec/antelope/template_spec.rb +0 -50
@@ -1,79 +1,112 @@
1
- # encoding: utf-8
2
-
3
- require "pp"
4
-
5
- module Antelope
6
- module Generator
7
-
8
- # Generates a ruby parser.
9
- class Ruby < Base
10
-
11
- register_as "ruby", "rubby"
12
-
13
- has_directive "panic-mode", Boolean
14
- has_directive "ruby.error-class", String
15
-
16
- # Creates an action table for the parser.
17
- #
18
- # @return [String]
19
- def generate_action_table
20
- out = ""
21
- PP.pp(table, out)
22
- out
23
- end
24
-
25
- # Outputs an array of all of the productions.
26
- #
27
- # @return [String]
28
- def generate_productions_list
29
- out = "["
30
-
31
- productions.each do |(label, size, block)|
32
- out <<
33
- "[" <<
34
- label.name.inspect <<
35
- ", " <<
36
- size.inspect <<
37
- ", "
38
-
39
- block = if block.empty?
40
- "DEFAULT_PROC"
41
- else
42
- "proc { |match| #{block[1..-2]} }"
43
- end
44
-
45
- out << block << "],\n"
46
- end
47
-
48
- out.chomp!( ",\n")
49
-
50
- out << "]"
51
- end
52
-
53
- def define_own_handler?
54
- directives.ruby.error_class? or
55
- panic_mode?
56
- end
57
-
58
- def panic_mode?
59
- directives.panic_mode &&
60
- directives.ruby.error_class? &&
61
- grammar.contains_error_token?
62
- end
63
-
64
- def error_class
65
- directives.ruby.error_class
66
- end
67
-
68
- # Actually performs the generation. Takes the template from
69
- # ruby.ant and outputs it to `<file>.rb`.
70
- #
71
- # @return [void]
72
- def generate
73
- template "ruby", "#{file}.rb" do |body|
74
- sprintf(grammar.compiler.body, write: body)
75
- end
76
- end
77
- end
78
- end
79
- end
1
+ # encoding: utf-8
2
+
3
+ require 'pp'
4
+
5
+ module Antelope
6
+ module Generator
7
+ # Generates a ruby parser.
8
+ class Ruby < Base
9
+ register_as 'ruby', 'rubby'
10
+
11
+ has_directive 'output.panic-mode', Boolean
12
+ has_directive 'ruby.error-class', String
13
+ directive 'ruby.indent', Integer
14
+
15
+ # Creates an action table for the parser.
16
+ #
17
+ # @return [String]
18
+ def generate_action_table
19
+ parts = []
20
+ table.each do |state|
21
+ out = ''
22
+ state.each do |token, action|
23
+ inspect = %(:"#{token}" =>)
24
+ out << "#{basic_indent}#{inspect} #{action.inspect},\n"
25
+ end
26
+ parts << "{\n#{out.chomp(",\n")}\n}"
27
+ end
28
+
29
+ "[#{parts.join(', ')}]"
30
+ end
31
+
32
+ def indent
33
+ basic_indent * (directives.ruby.indent || 2)
34
+ end
35
+
36
+ def basic_indent
37
+ @_indent ||= case indent_type
38
+ when 'space'
39
+ ' '
40
+ when 'tab'
41
+ "\t"
42
+ else
43
+ indent_type
44
+ end * indent_size
45
+ end
46
+
47
+ def indent_type
48
+ directives.ruby.indent_type || 'space'
49
+ end
50
+
51
+ def indent_size
52
+ directives.ruby.indent_size ||
53
+ case indent_type
54
+ when 'tab'
55
+ 1
56
+ else
57
+ 2
58
+ end
59
+ end
60
+
61
+ # Outputs an array of all of the productions.
62
+ #
63
+ # @return [String]
64
+ def generate_productions_list
65
+ out = "[\n"
66
+
67
+ productions.each do |(label, size, block)|
68
+ out << '[' << label.name.inspect << ', ' <<
69
+ size.inspect << ', '
70
+
71
+ block = if block.empty?
72
+ 'DEFAULT_PROC'
73
+ else
74
+ "proc { |match| #{block[1..-2]} }"
75
+ end
76
+
77
+ out << block << "],\n"
78
+ end
79
+ out.chomp!(",\n")
80
+ out << ']'
81
+ end
82
+
83
+ def define_own_handler?
84
+ directives.ruby.error_class? ||
85
+ panic_mode?
86
+ end
87
+
88
+ def panic_mode?
89
+ directives.panic_mode &&
90
+ directives.ruby.error_class? &&
91
+ grammar.contains_error_token?
92
+ end
93
+
94
+ def error_class
95
+ directives.ruby.error_class
96
+ end
97
+
98
+ # Actually performs the generation. Takes the template from
99
+ # ruby.ant and outputs it to `<file>.rb`.
100
+ #
101
+ # @return [void]
102
+ def generate
103
+ template 'ruby', "#{file}.rb" do |body|
104
+ body
105
+ .gsub!("\n", "\n#{indent}")
106
+ .gsub!(/^[ \t]*\n/, "\n")
107
+ format(grammar.compiler.body, write: body)
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -1,36 +1,36 @@
1
- #ifndef _%{guard_name}_H
2
- #define _%{guard_name}_H
3
-
4
- % if define_stype?
5
- typedef union {
6
- %{union_body}
7
- } %{stype};
8
- % end
9
-
10
- enum %{prefix}tokentype {
11
- % starting = 257
12
- %{token_prefix}EOF = 0,
13
- % grammar.terminals.each_with_index do |terminal, i|
14
- %{token_prefix}%{terminal.name} = %{starting + i},
15
- % end
16
- };
17
-
18
- typedef struct {
19
- struct %{prefix}stack_element* elements;
20
- unsigned int current;
21
- unsigned int max;
22
- unsigned char free;
23
- } %{prefix}pstate;
24
-
25
- #define %{upper_prefix}PUSH_MORE -1
26
- #define %{upper_prefix}TERMINALS %{grammar.terminals.size}
27
- #define %{upper_prefix}STATES %{table.size}
28
-
29
- const char* %{prefix}token_string(%{terminal_type} token);
30
- int %{prefix}lex(%{stype}* lval%{lex_params});
31
- int %{prefix}parse_push(%{parse_params});
32
- int %{prefix}parse_pull(%{parse_params});
33
- %{prefix}pstate* %{prefix}pstate_new();
34
- void %{prefix}pstate_delete(%{prefix}pstate* stack);
35
-
36
- #endif
1
+ #ifndef _%{guard_name}_H
2
+ #define _%{guard_name}_H
3
+
4
+ % if define_stype?
5
+ typedef union {
6
+ %{union_body}
7
+ } %{stype};
8
+ % end
9
+
10
+ enum %{prefix}tokentype {
11
+ % starting = 257
12
+ %{token_prefix}EOF = 0,
13
+ % grammar.terminals.each_with_index do |terminal, i|
14
+ %{token_prefix}%{terminal.name} = %{starting + i},
15
+ % end
16
+ };
17
+
18
+ typedef struct {
19
+ struct %{prefix}stack_element* elements;
20
+ unsigned int current;
21
+ unsigned int max;
22
+ unsigned char free;
23
+ } %{prefix}pstate;
24
+
25
+ #define %{upper_prefix}PUSH_MORE -1
26
+ #define %{upper_prefix}TERMINALS %{grammar.terminals.size}
27
+ #define %{upper_prefix}STATES %{table.size}
28
+
29
+ const char* %{prefix}token_string(%{terminal_type} token);
30
+ int %{prefix}lex(%{stype}* lval%{lex_params});
31
+ int %{prefix}parse_push(%{parse_params});
32
+ int %{prefix}parse_pull(%{parse_params});
33
+ %{prefix}pstate* %{prefix}pstate_new();
34
+ void %{prefix}pstate_delete(%{prefix}pstate* stack);
35
+
36
+ #endif
@@ -1,202 +1,202 @@
1
- #include "%{file}.h"
2
- #include <stdlib.h>
3
- #include <stdio.h>
4
- #include <stdint.h>
5
- #include <limits.h>
6
- #include <alloca.h>
7
- #include <string.h>
8
-
9
- static const unsigned int %{prefix}states[][%{upper_prefix}TERMINALS] = {
10
- % table.each do |state|
11
- { %{action_for(state)} },
12
- % end
13
- };
14
-
15
- #ifndef %{upper_prefix}INITSTACK
16
- # define %{upper_prefix}INITSTACK 64
17
- #endif
18
-
19
- #ifndef %{upper_prefix}ALLOC
20
- # define %{upper_prefix}ALLOC malloc
21
- #endif
22
-
23
- #ifndef %{upper_prefix}FREE
24
- # define %{upper_prefix}FREE free
25
- #endif
26
-
27
- struct %{prefix}stack_element {
28
- %{stype}* val;
29
- unsigned int state;
30
- };
31
-
32
- #define %{upper_prefix}PUSH_STACK(stack, v, s) do { \
33
- int err; \
34
- if(stack.current + 1 > stack.max) \
35
- { \
36
- if((err = %{prefix}resize_stack(&stack)) != 0) \
37
- return err; \
38
- } \
39
- stack.elements[stack.current].val = val; \
40
- stack.elements[stack.current].state = s; \
41
- } while(0)
42
-
43
- #define %{upper_prefix}POP_STACK(stack, out) do { \
44
- out = stack.elements + stack.current; \
45
- stack.current -= 1; \
46
- } while(0)
47
-
48
- const char* %{prefix}token_string(%{terminal_type} token)
49
- {
50
- switch(token)
51
- {
52
- % grammar.terminals.each do |terminal|
53
- case %{token_prefix}%{terminal.name}:
54
- return %{terminal.to_s.inspect};
55
- % end
56
- }
57
-
58
- return "(unknown)";
59
- }
60
-
61
- %{prefix}pstate* %{prefix}state_new()
62
- {
63
- %{prefix}pstate* stack = %{upper_prefix}ALLOC(sizeof(%{prefix}pstate));
64
- if(stack != NULL)
65
- {
66
- stack->max = %{upper_prefix}INITSTACK;
67
- stack->elements = %{upper_prefix}ALLOC(sizeof(struct %{prefix}stack_element) * stack->max);
68
- stack->current = 0;
69
- stack->free = 1;
70
- }
71
-
72
- return stack;
73
- }
74
-
75
- void %{prefix}state_delete(%{prefix}pstate* stack)
76
- {
77
- stack->current = 0;
78
- stack->max = 0;
79
- stack->free = 0;
80
-
81
- if(stack->free)
82
- {
83
- %{upper_prefix}FREE(stack->elements);
84
- %{upper_prefix}FREE(stack);
85
- }
86
-
87
- stack->elements = 0;
88
- }
89
-
90
- int %{prefix}resize_stack(%{prefix}pstate* stack)
91
- {
92
- void* body;
93
- int new_max;
94
-
95
- if(stack->current + 1 > stack->max)
96
- {
97
- new_max = stack->max * 2;
98
- }
99
- else if((stack->current / 2) < stack->max)
100
- {
101
- new_max = stack->max / 2;
102
- }
103
- else
104
- {
105
- return 0;
106
- }
107
-
108
-
109
- body = %{upper_prefix}ALLOC(sizeof(struct %{prefix}stack_element) * new_max);
110
-
111
- if(body == NULL)
112
- {
113
- return ENOMEM;
114
- }
115
-
116
- memcpy(body, stack->elements, sizeof(struct %{prefix}stack_element) * stack->current);
117
-
118
- if(stack->free)
119
- {
120
- %{upper_prefix}FREE(stack->elements);
121
- }
122
-
123
- stack->elements = body;
124
- stack->max = new_max;
125
-
126
- return 0;
127
- }
128
-
129
- int %{prefix}parse_push(%{prefix}pstate* stack int token,
130
- %{upper_prefix}STYPE* val%{parse_params})
131
- {
132
- unsigned int action;
133
- %{prefix}stack_element* current_state;
134
-
135
- current_state = stack.elements + stack.current - 1;
136
-
137
- if(token > %{upper_prefix}TERMINALS || token < 0)
138
- %{prefix}abort;
139
-
140
- get_action:
141
- action = states[current_state->state][token];
142
-
143
- if(action < %{upper_prefix}STATES)
144
- {
145
- %{upper_prefix}PUSH_STACK(stack, val, action - 1);
146
- return %{upper_prefix}PUSH_MORE;
147
- }
148
-
149
- switch(action)
150
- {
151
- case 0:
152
- %{prefix}error;
153
- break;
154
- case %{table.size + 1}:
155
- stack.current = 0;
156
- return 0;
157
- % productions.each_with_index do |(label, size, block), i|
158
- case %{i + table.size + 2}: { // %{i}
159
- %{upper_prefix}STYPE* %{prefix}vals[%{size}];
160
- %{upper_prefix}STYPE* %{prefix}out;
161
- % size.times do |e|
162
- %{upper_prefix}POP_STACK(stack, %{prefix}vals[%{e}]);
163
- % end
164
- %{prefix}out = %{prefix}vals[0];
165
- current_state = stack.elements + stack.current - 1;
166
-
167
- do {
168
- {{= cify_block(block) }}
169
- } while(0);
170
-
171
- token = %{symbols[label.name]};
172
- action = states[current_state->state][token];
173
- %{upper_prefix}PUSH_STACK(stack, %{prefix}out, action);
174
- break;
175
- }
176
- % end
177
- }
178
-
179
- return %{upper_prefix}PUSH_MORE;
180
- }
181
-
182
- int %{prefix}parse_pull(%{parse_params})
183
- {
184
- %{prefix}pstate stack;
185
- int token;
186
- unsigned int action;
187
- %{upper_prefix}STYPE val;
188
- %{prefix}stack_element* current_state;
189
-
190
- stack.max = %{upper_prefix}INITSTACK;
191
- stack.elements = alloca(sizeof(struct %{prefix}stack_element) * stack.max);
192
- stack.current = 0;
193
- stack.free = 0;
194
-
195
- %{upper_prefix}PUSH_STACK(stack, NULL, 1);
196
-
197
- while(stack.current > 0)
198
- {
199
- token = %{prefix}lex(&val%{params});
200
- %{prefix}parse_push(&stack, token, &val%{parse_params});
201
- }
202
- }
1
+ #include "%{file}.h"
2
+ #include <stdlib.h>
3
+ #include <stdio.h>
4
+ #include <stdint.h>
5
+ #include <limits.h>
6
+ #include <alloca.h>
7
+ #include <string.h>
8
+
9
+ static const unsigned int %{prefix}states[][%{upper_prefix}TERMINALS] = {
10
+ % table.each do |state|
11
+ { %{action_for(state)} },
12
+ % end
13
+ };
14
+
15
+ #ifndef %{upper_prefix}INITSTACK
16
+ # define %{upper_prefix}INITSTACK 64
17
+ #endif
18
+
19
+ #ifndef %{upper_prefix}ALLOC
20
+ # define %{upper_prefix}ALLOC malloc
21
+ #endif
22
+
23
+ #ifndef %{upper_prefix}FREE
24
+ # define %{upper_prefix}FREE free
25
+ #endif
26
+
27
+ struct %{prefix}stack_element {
28
+ %{stype}* val;
29
+ unsigned int state;
30
+ };
31
+
32
+ #define %{upper_prefix}PUSH_STACK(stack, v, s) do { \
33
+ int err; \
34
+ if(stack.current + 1 > stack.max) \
35
+ { \
36
+ if((err = %{prefix}resize_stack(&stack)) != 0) \
37
+ return err; \
38
+ } \
39
+ stack.elements[stack.current].val = val; \
40
+ stack.elements[stack.current].state = s; \
41
+ } while(0)
42
+
43
+ #define %{upper_prefix}POP_STACK(stack, out) do { \
44
+ out = stack.elements + stack.current; \
45
+ stack.current -= 1; \
46
+ } while(0)
47
+
48
+ const char* %{prefix}token_string(%{terminal_type} token)
49
+ {
50
+ switch(token)
51
+ {
52
+ % grammar.terminals.each do |terminal|
53
+ case %{token_prefix}%{terminal.name}:
54
+ return %{terminal.to_s.inspect};
55
+ % end
56
+ }
57
+
58
+ return "(unknown)";
59
+ }
60
+
61
+ %{prefix}pstate* %{prefix}state_new()
62
+ {
63
+ %{prefix}pstate* stack = %{upper_prefix}ALLOC(sizeof(%{prefix}pstate));
64
+ if(stack != NULL)
65
+ {
66
+ stack->max = %{upper_prefix}INITSTACK;
67
+ stack->elements = %{upper_prefix}ALLOC(sizeof(struct %{prefix}stack_element) * stack->max);
68
+ stack->current = 0;
69
+ stack->free = 1;
70
+ }
71
+
72
+ return stack;
73
+ }
74
+
75
+ void %{prefix}state_delete(%{prefix}pstate* stack)
76
+ {
77
+ stack->current = 0;
78
+ stack->max = 0;
79
+ stack->free = 0;
80
+
81
+ if(stack->free)
82
+ {
83
+ %{upper_prefix}FREE(stack->elements);
84
+ %{upper_prefix}FREE(stack);
85
+ }
86
+
87
+ stack->elements = 0;
88
+ }
89
+
90
+ int %{prefix}resize_stack(%{prefix}pstate* stack)
91
+ {
92
+ void* body;
93
+ int new_max;
94
+
95
+ if(stack->current + 1 > stack->max)
96
+ {
97
+ new_max = stack->max * 2;
98
+ }
99
+ else if((stack->current / 2) < stack->max)
100
+ {
101
+ new_max = stack->max / 2;
102
+ }
103
+ else
104
+ {
105
+ return 0;
106
+ }
107
+
108
+
109
+ body = %{upper_prefix}ALLOC(sizeof(struct %{prefix}stack_element) * new_max);
110
+
111
+ if(body == NULL)
112
+ {
113
+ return ENOMEM;
114
+ }
115
+
116
+ memcpy(body, stack->elements, sizeof(struct %{prefix}stack_element) * stack->current);
117
+
118
+ if(stack->free)
119
+ {
120
+ %{upper_prefix}FREE(stack->elements);
121
+ }
122
+
123
+ stack->elements = body;
124
+ stack->max = new_max;
125
+
126
+ return 0;
127
+ }
128
+
129
+ int %{prefix}parse_push(%{prefix}pstate* stack int token,
130
+ %{upper_prefix}STYPE* val%{parse_params})
131
+ {
132
+ unsigned int action;
133
+ %{prefix}stack_element* current_state;
134
+
135
+ current_state = stack.elements + stack.current - 1;
136
+
137
+ if(token > %{upper_prefix}TERMINALS || token < 0)
138
+ %{prefix}abort;
139
+
140
+ get_action:
141
+ action = states[current_state->state][token];
142
+
143
+ if(action < %{upper_prefix}STATES)
144
+ {
145
+ %{upper_prefix}PUSH_STACK(stack, val, action - 1);
146
+ return %{upper_prefix}PUSH_MORE;
147
+ }
148
+
149
+ switch(action)
150
+ {
151
+ case 0:
152
+ %{prefix}error;
153
+ break;
154
+ case %{table.size + 1}:
155
+ stack.current = 0;
156
+ return 0;
157
+ % productions.each_with_index do |(label, size, block), i|
158
+ case %{i + table.size + 2}: { // %{i}
159
+ %{upper_prefix}STYPE* %{prefix}vals[%{size}];
160
+ %{upper_prefix}STYPE* %{prefix}out;
161
+ % size.times do |e|
162
+ %{upper_prefix}POP_STACK(stack, %{prefix}vals[%{e}]);
163
+ % end
164
+ %{prefix}out = %{prefix}vals[0];
165
+ current_state = stack.elements + stack.current - 1;
166
+
167
+ do {
168
+ {{= cify_block(block) }}
169
+ } while(0);
170
+
171
+ token = %{symbols[label.name]};
172
+ action = states[current_state->state][token];
173
+ %{upper_prefix}PUSH_STACK(stack, %{prefix}out, action);
174
+ break;
175
+ }
176
+ % end
177
+ }
178
+
179
+ return %{upper_prefix}PUSH_MORE;
180
+ }
181
+
182
+ int %{prefix}parse_pull(%{parse_params})
183
+ {
184
+ %{prefix}pstate stack;
185
+ int token;
186
+ unsigned int action;
187
+ %{upper_prefix}STYPE val;
188
+ %{prefix}stack_element* current_state;
189
+
190
+ stack.max = %{upper_prefix}INITSTACK;
191
+ stack.elements = alloca(sizeof(struct %{prefix}stack_element) * stack.max);
192
+ stack.current = 0;
193
+ stack.free = 0;
194
+
195
+ %{upper_prefix}PUSH_STACK(stack, NULL, 1);
196
+
197
+ while(stack.current > 0)
198
+ {
199
+ token = %{prefix}lex(&val%{params});
200
+ %{prefix}parse_push(&stack, token, &val%{parse_params});
201
+ }
202
+ }