racc 1.4.6

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 (109) hide show
  1. data/.gitattributes +2 -0
  2. data/.gitignore +7 -0
  3. data/COPYING +515 -0
  4. data/ChangeLog +846 -0
  5. data/DEPENDS +4 -0
  6. data/README.en.rdoc +86 -0
  7. data/README.ja.rdoc +96 -0
  8. data/Rakefile +15 -0
  9. data/TODO +5 -0
  10. data/bin/racc +308 -0
  11. data/bin/racc2y +195 -0
  12. data/bin/y2racc +339 -0
  13. data/doc/en/NEWS.en.rdoc +282 -0
  14. data/doc/en/command.en.html +78 -0
  15. data/doc/en/debug.en.rdoc +20 -0
  16. data/doc/en/grammar.en.rdoc +230 -0
  17. data/doc/en/index.en.html +10 -0
  18. data/doc/en/parser.en.rdoc +74 -0
  19. data/doc/en/usage.en.html +92 -0
  20. data/doc/ja/NEWS.ja.rdoc +307 -0
  21. data/doc/ja/command.ja.html +94 -0
  22. data/doc/ja/debug.ja.rdoc +36 -0
  23. data/doc/ja/grammar.ja.rdoc +348 -0
  24. data/doc/ja/index.ja.html +10 -0
  25. data/doc/ja/parser.ja.rdoc +125 -0
  26. data/doc/ja/usage.ja.html +414 -0
  27. data/ext/racc/cparse/MANIFEST +4 -0
  28. data/ext/racc/cparse/cparse.c +824 -0
  29. data/ext/racc/cparse/depend +1 -0
  30. data/ext/racc/cparse/extconf.rb +7 -0
  31. data/fastcache/extconf.rb +2 -0
  32. data/fastcache/fastcache.c +185 -0
  33. data/lib/racc.rb +6 -0
  34. data/lib/racc/compat.rb +40 -0
  35. data/lib/racc/debugflags.rb +59 -0
  36. data/lib/racc/exception.rb +15 -0
  37. data/lib/racc/grammar.rb +1115 -0
  38. data/lib/racc/grammarfileparser.rb +559 -0
  39. data/lib/racc/info.rb +16 -0
  40. data/lib/racc/iset.rb +91 -0
  41. data/lib/racc/logfilegenerator.rb +214 -0
  42. data/lib/racc/parser.rb +439 -0
  43. data/lib/racc/parserfilegenerator.rb +511 -0
  44. data/lib/racc/pre-setup +13 -0
  45. data/lib/racc/sourcetext.rb +34 -0
  46. data/lib/racc/state.rb +971 -0
  47. data/lib/racc/statetransitiontable.rb +316 -0
  48. data/lib/racc/static.rb +5 -0
  49. data/misc/dist.sh +31 -0
  50. data/sample/array.y +67 -0
  51. data/sample/array2.y +59 -0
  52. data/sample/calc-ja.y +66 -0
  53. data/sample/calc.y +65 -0
  54. data/sample/conflict.y +15 -0
  55. data/sample/hash.y +60 -0
  56. data/sample/lalr.y +17 -0
  57. data/sample/lists.y +57 -0
  58. data/sample/syntax.y +46 -0
  59. data/sample/yyerr.y +46 -0
  60. data/setup.rb +1587 -0
  61. data/tasks/doc.rb +12 -0
  62. data/tasks/email.rb +55 -0
  63. data/tasks/file.rb +37 -0
  64. data/tasks/gem.rb +37 -0
  65. data/tasks/test.rb +16 -0
  66. data/test/assets/chk.y +126 -0
  67. data/test/assets/conf.y +16 -0
  68. data/test/assets/digraph.y +29 -0
  69. data/test/assets/echk.y +118 -0
  70. data/test/assets/err.y +60 -0
  71. data/test/assets/expect.y +7 -0
  72. data/test/assets/firstline.y +4 -0
  73. data/test/assets/ichk.y +102 -0
  74. data/test/assets/intp.y +546 -0
  75. data/test/assets/mailp.y +437 -0
  76. data/test/assets/newsyn.y +25 -0
  77. data/test/assets/noend.y +4 -0
  78. data/test/assets/nonass.y +41 -0
  79. data/test/assets/normal.y +27 -0
  80. data/test/assets/norule.y +4 -0
  81. data/test/assets/nullbug1.y +25 -0
  82. data/test/assets/nullbug2.y +15 -0
  83. data/test/assets/opt.y +123 -0
  84. data/test/assets/percent.y +35 -0
  85. data/test/assets/recv.y +97 -0
  86. data/test/assets/rrconf.y +14 -0
  87. data/test/assets/scan.y +72 -0
  88. data/test/assets/syntax.y +50 -0
  89. data/test/assets/unterm.y +5 -0
  90. data/test/assets/useless.y +12 -0
  91. data/test/assets/yyerr.y +46 -0
  92. data/test/bench.y +36 -0
  93. data/test/helper.rb +88 -0
  94. data/test/infini.y +8 -0
  95. data/test/scandata/brace +7 -0
  96. data/test/scandata/gvar +1 -0
  97. data/test/scandata/normal +4 -0
  98. data/test/scandata/percent +18 -0
  99. data/test/scandata/slash +10 -0
  100. data/test/src.intp +34 -0
  101. data/test/start.y +20 -0
  102. data/test/test_chk_y.rb +51 -0
  103. data/test/test_grammar_file_parser.rb +15 -0
  104. data/test/test_racc_command.rb +155 -0
  105. data/test/test_scan_y.rb +51 -0
  106. data/test/testscanner.rb +51 -0
  107. data/web/racc.en.rhtml +42 -0
  108. data/web/racc.ja.rhtml +51 -0
  109. metadata +166 -0
@@ -0,0 +1,316 @@
1
+ #
2
+ # $Id$
3
+ #
4
+ # Copyright (c) 1999-2006 Minero Aoki
5
+ #
6
+ # This program is free software.
7
+ # You can distribute/modify this program under the terms of
8
+ # the GNU LGPL, Lesser General Public License version 2.1.
9
+ # For details of LGPL, see the file "COPYING".
10
+ #
11
+
12
+ require 'racc/parser'
13
+
14
+ unless Object.method_defined?(:funcall)
15
+ class Object
16
+ alias funcall __send__
17
+ end
18
+ end
19
+
20
+ module Racc
21
+
22
+ StateTransitionTable = Struct.new(:action_table,
23
+ :action_check,
24
+ :action_default,
25
+ :action_pointer,
26
+ :goto_table,
27
+ :goto_check,
28
+ :goto_default,
29
+ :goto_pointer,
30
+ :token_table,
31
+ :reduce_table,
32
+ :reduce_n,
33
+ :shift_n,
34
+ :nt_base,
35
+ :token_to_s_table,
36
+ :use_result_var,
37
+ :debug_parser)
38
+ class StateTransitionTable # reopen
39
+ def StateTransitionTable.generate(states)
40
+ StateTransitionTableGenerator.new(states).generate
41
+ end
42
+
43
+ def initialize(states)
44
+ super()
45
+ @states = states
46
+ @grammar = states.grammar
47
+ self.use_result_var = true
48
+ self.debug_parser = true
49
+ end
50
+
51
+ attr_reader :states
52
+ attr_reader :grammar
53
+
54
+ def parser_class
55
+ ParserClassGenerator.new(@states).generate
56
+ end
57
+
58
+ def token_value_table
59
+ h = {}
60
+ token_table().each do |sym, i|
61
+ h[sym.value] = i
62
+ end
63
+ h
64
+ end
65
+ end
66
+
67
+
68
+ class StateTransitionTableGenerator
69
+
70
+ def initialize(states)
71
+ @states = states
72
+ @grammar = states.grammar
73
+ end
74
+
75
+ def generate
76
+ t = StateTransitionTable.new(@states)
77
+ gen_action_tables t, @states
78
+ gen_goto_tables t, @grammar
79
+ t.token_table = token_table(@grammar)
80
+ t.reduce_table = reduce_table(@grammar)
81
+ t.reduce_n = @states.reduce_n
82
+ t.shift_n = @states.shift_n
83
+ t.nt_base = @grammar.nonterminal_base
84
+ t.token_to_s_table = @grammar.symbols.map {|sym| sym.to_s }
85
+ t
86
+ end
87
+
88
+ def reduce_table(grammar)
89
+ t = [0, 0, :racc_error]
90
+ grammar.each_with_index do |rule, idx|
91
+ next if idx == 0
92
+ t.push rule.size
93
+ t.push rule.target.ident
94
+ t.push(if rule.action.empty? # and @params.omit_action_call?
95
+ then :_reduce_none
96
+ else "_reduce_#{idx}".intern
97
+ end)
98
+ end
99
+ t
100
+ end
101
+
102
+ def token_table(grammar)
103
+ h = {}
104
+ grammar.symboltable.terminals.each do |t|
105
+ h[t] = t.ident
106
+ end
107
+ h
108
+ end
109
+
110
+ def gen_action_tables(t, states)
111
+ t.action_table = yytable = []
112
+ t.action_check = yycheck = []
113
+ t.action_default = yydefact = []
114
+ t.action_pointer = yypact = []
115
+ e1 = []
116
+ e2 = []
117
+ states.each do |state|
118
+ yydefact.push act2actid(state.defact)
119
+ if state.action.empty?
120
+ yypact.push nil
121
+ next
122
+ end
123
+ vector = []
124
+ state.action.each do |tok, act|
125
+ vector[tok.ident] = act2actid(act)
126
+ end
127
+ addent e1, vector, state.ident, yypact
128
+ end
129
+ set_table e1, e2, yytable, yycheck, yypact
130
+ end
131
+
132
+ def gen_goto_tables(t, grammar)
133
+ t.goto_table = yytable2 = []
134
+ t.goto_check = yycheck2 = []
135
+ t.goto_pointer = yypgoto = []
136
+ t.goto_default = yydefgoto = []
137
+ e1 = []
138
+ e2 = []
139
+ grammar.each_nonterminal do |tok|
140
+ tmp = []
141
+
142
+ # decide default
143
+ freq = Array.new(@states.size, 0)
144
+ @states.each do |state|
145
+ st = state.goto_table[tok]
146
+ if st
147
+ st = st.ident
148
+ freq[st] += 1
149
+ end
150
+ tmp[state.ident] = st
151
+ end
152
+ max = freq.max
153
+ if max > 1
154
+ default = freq.index(max)
155
+ tmp.map! {|i| default == i ? nil : i }
156
+ else
157
+ default = nil
158
+ end
159
+ yydefgoto.push default
160
+
161
+ # delete default value
162
+ tmp.pop until tmp.last or tmp.empty?
163
+ if tmp.compact.empty?
164
+ # only default
165
+ yypgoto.push nil
166
+ next
167
+ end
168
+
169
+ addent e1, tmp, (tok.ident - grammar.nonterminal_base), yypgoto
170
+ end
171
+ set_table e1, e2, yytable2, yycheck2, yypgoto
172
+ end
173
+
174
+ def addent(all, arr, chkval, ptr)
175
+ max = arr.size
176
+ min = nil
177
+ arr.each_with_index do |item, idx|
178
+ if item
179
+ min ||= idx
180
+ end
181
+ end
182
+ ptr.push(-7777) # mark
183
+ arr = arr[min...max]
184
+ all.push [arr, chkval, mkmapexp(arr), min, ptr.size - 1]
185
+ end
186
+
187
+ n = 2 ** 16
188
+ begin
189
+ Regexp.compile("a{#{n}}")
190
+ RE_DUP_MAX = n
191
+ rescue RegexpError
192
+ n /= 2
193
+ retry
194
+ end
195
+
196
+ def mkmapexp(arr)
197
+ i = ii = 0
198
+ as = arr.size
199
+ map = ''
200
+ maxdup = RE_DUP_MAX
201
+ curr = nil
202
+ while i < as
203
+ ii = i + 1
204
+ if arr[i]
205
+ ii += 1 while ii < as and arr[ii]
206
+ curr = '-'
207
+ else
208
+ ii += 1 while ii < as and not arr[ii]
209
+ curr = '.'
210
+ end
211
+
212
+ offset = ii - i
213
+ if offset == 1
214
+ map << curr
215
+ else
216
+ while offset > maxdup
217
+ map << "#{curr}{#{maxdup}}"
218
+ offset -= maxdup
219
+ end
220
+ map << "#{curr}{#{offset}}" if offset > 1
221
+ end
222
+ i = ii
223
+ end
224
+ Regexp.compile(map, 'n')
225
+ end
226
+
227
+ def set_table(entries, dummy, tbl, chk, ptr)
228
+ upper = 0
229
+ map = '-' * 10240
230
+
231
+ # sort long to short
232
+ entries.sort! {|a,b| b[0].size <=> a[0].size }
233
+
234
+ entries.each do |arr, chkval, expr, min, ptri|
235
+ if upper + arr.size > map.size
236
+ map << '-' * (arr.size + 1024)
237
+ end
238
+ idx = map.index(expr)
239
+ ptr[ptri] = idx - min
240
+ arr.each_with_index do |item, i|
241
+ if item
242
+ i += idx
243
+ tbl[i] = item
244
+ chk[i] = chkval
245
+ map[i] = ?o
246
+ end
247
+ end
248
+ upper = idx + arr.size
249
+ end
250
+ end
251
+
252
+ def act2actid(act)
253
+ case act
254
+ when Shift then act.goto_id
255
+ when Reduce then -act.ruleid
256
+ when Accept then @states.shift_n
257
+ when Error then @states.reduce_n * -1
258
+ else
259
+ raise "racc: fatal: wrong act type #{act.class} in action table"
260
+ end
261
+ end
262
+
263
+ end
264
+
265
+
266
+ class ParserClassGenerator
267
+
268
+ def initialize(states)
269
+ @states = states
270
+ @grammar = states.grammar
271
+ end
272
+
273
+ def generate
274
+ table = @states.state_transition_table
275
+ c = Class.new(::Racc::Parser)
276
+ c.const_set :Racc_arg, [table.action_table,
277
+ table.action_check,
278
+ table.action_default,
279
+ table.action_pointer,
280
+ table.goto_table,
281
+ table.goto_check,
282
+ table.goto_default,
283
+ table.goto_pointer,
284
+ table.nt_base,
285
+ table.reduce_table,
286
+ table.token_value_table,
287
+ table.shift_n,
288
+ table.reduce_n,
289
+ false]
290
+ c.const_set :Racc_token_to_s_table, table.token_to_s_table
291
+ c.const_set :Racc_debug_parser, true
292
+ define_actions c
293
+ c
294
+ end
295
+
296
+ private
297
+
298
+ def define_actions(c)
299
+ c.module_eval "def _reduce_none(vals, vstack) vals[0] end"
300
+ @grammar.each do |rule|
301
+ if rule.action.empty?
302
+ c.funcall(:alias_method, "_reduce_#{rule.ident}", :_reduce_none)
303
+ else
304
+ c.funcall(:define_method, "_racc_action_#{rule.ident}", &rule.action.proc)
305
+ c.module_eval(s = <<-End, __FILE__, __LINE__ + 1)
306
+ def _reduce_#{rule.ident}(vals, vstack)
307
+ _racc_action_#{rule.ident}(*vals)
308
+ end
309
+ End
310
+ end
311
+ end
312
+ end
313
+
314
+ end
315
+
316
+ end # module Racc
@@ -0,0 +1,5 @@
1
+ require 'racc'
2
+ require 'racc/parser'
3
+ require 'racc/grammarfileparser'
4
+ require 'racc/parserfilegenerator'
5
+ require 'racc/logfilegenerator'
@@ -0,0 +1,31 @@
1
+ #!/bin/sh
2
+
3
+ rm -rf tmp
4
+ mkdir tmp
5
+ cd tmp
6
+
7
+ # racc, raccrt
8
+ cvs -Q export -r`echo V$version | tr . -` -d racc-$version racc
9
+ cd racc-$version
10
+ make bootstrap lib/racc/parser-text.rb doc
11
+ rm -r doc web bits fastcache
12
+ cd ..
13
+ mkdir -p raccrt-$version/lib/racc
14
+ mv racc-$version/lib/racc/parser.rb raccrt-$version/lib/racc
15
+ mv racc-$version/ext raccrt-$version
16
+ cp racc-$version/setup.rb raccrt-$version
17
+ cp racc-$version/README.* raccrt-$version
18
+ cp racc-$version/COPYING raccrt-$version
19
+ tar czf $ardir/racc/racc-$version.tar.gz racc-$version
20
+ tar czf $ardir/raccrt/raccrt-$version.tar.gz raccrt-$version
21
+
22
+ # -all
23
+ mkdir -p racc-$version-all/packages
24
+ cp racc-$version/setup.rb racc-$version-all
25
+ cp racc-$version/README.* racc-$version-all
26
+ mv racc-$version racc-$version-all/packages/racc
27
+ mv raccrt-$version racc-$version-all/packages/raccrt
28
+ tar czf $ardir/racc/racc-$version-all.tar.gz racc-$version-all
29
+
30
+ cd ..
31
+ rm -rf tmp
@@ -0,0 +1,67 @@
1
+ # $Id$
2
+ #
3
+ # convert Array-like string into Ruby's Array.
4
+
5
+ class ArrayParser
6
+
7
+ rule
8
+
9
+ array : '[' contents ']'
10
+ {
11
+ result = val[1]
12
+ }
13
+ | '[' ']'
14
+ {
15
+ result = []
16
+ }
17
+
18
+ contents: ITEM
19
+ {
20
+ result = val
21
+ }
22
+ | contents ',' ITEM
23
+ {
24
+ result.push val[2]
25
+ }
26
+
27
+ ---- inner
28
+
29
+ def parse(str)
30
+ str = str.strip
31
+ @q = []
32
+ until str.empty?
33
+ case str
34
+ when /\A\s+/
35
+ str = $'
36
+ when /\A\w+/
37
+ @q.push [:ITEM, $&]
38
+ str = $'
39
+ else
40
+ c = str[0,1]
41
+ @q.push [c, c]
42
+ str = str[1..-1]
43
+ end
44
+ end
45
+ @q.push [false, '$'] # is optional from Racc 1.3.7
46
+ do_parse
47
+ end
48
+
49
+ def next_token
50
+ @q.shift
51
+ end
52
+
53
+ ---- footer
54
+
55
+ if $0 == __FILE__
56
+ src = <<EOS
57
+ [
58
+ a, b, c,
59
+ d,
60
+ e ]
61
+ EOS
62
+ puts 'parsing:'
63
+ print src
64
+ puts
65
+ puts 'result:'
66
+ p ArrayParser.new.parse(src)
67
+ end
@@ -0,0 +1,59 @@
1
+ # $Id$
2
+ #
3
+ # Converting Array-like string into Ruby's Array, version 2.
4
+ # This grammer uses no_result_var.
5
+
6
+ class ArrayParser2
7
+ options no_result_var
8
+ rule
9
+ array : '[' contents ']' { val[1] }
10
+ | '[' ']' { [] }
11
+
12
+ contents: ITEM { val }
13
+ | contents ',' ITEM { val[0].push val[2]; val[0] }
14
+ end
15
+
16
+ ---- inner
17
+
18
+ def parse(str)
19
+ @str = str
20
+ yyparse self, :scan
21
+ end
22
+
23
+ def scan
24
+ str = @str.strip
25
+ until str.empty?
26
+ case str
27
+ when /\A\s+/
28
+ str = $'
29
+ when /\A\w+/
30
+ yield :ITEM, $&
31
+ str = $'
32
+ else
33
+ c = str[0,1]
34
+ yield c, c
35
+ str = str[1..-1]
36
+ end
37
+ end
38
+ yield false, '$' # is optional from Racc 1.3.7
39
+ end
40
+
41
+ def next_token
42
+ @q.shift
43
+ end
44
+
45
+ ---- footer
46
+
47
+ if $0 == __FILE__
48
+ src = <<EOS
49
+ [
50
+ a, b, c,
51
+ d,
52
+ e ]
53
+ EOS
54
+ puts 'parsing:'
55
+ print src
56
+ puts
57
+ puts 'result:'
58
+ p ArrayParser2.new.parse(src)
59
+ end