antelope 0.3.2 → 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 (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
+ }