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
data/DEPENDS ADDED
@@ -0,0 +1,4 @@
1
+ racc: raccruntime
2
+ raccruntime:
3
+ y2racc: strscan
4
+ racc2y: racc
@@ -0,0 +1,86 @@
1
+ = Racc
2
+
3
+ * http://i.loveruby.net/en/projects/racc/
4
+ * http://racc.rubyforge.org/
5
+
6
+ == DESCRIPTION:
7
+
8
+ Racc is a LALR(1) parser generator.
9
+ It is written in Ruby itself, and generates Ruby program.
10
+
11
+ NOTE: Ruby 1.8.x comes with Racc runtime module. You
12
+ can run your parsers generated by racc 1.4.x out of the
13
+ box.
14
+
15
+
16
+ == Requirement
17
+
18
+ * Ruby 1.8.x or later.
19
+ (*) make and C compiler.
20
+
21
+
22
+ == Installation
23
+
24
+ gem install:
25
+
26
+ $ gem install racc
27
+
28
+ setup.rb install:
29
+
30
+ Type this in the top directory of the extracted archive:
31
+
32
+ $ ruby setup.rb config
33
+ $ ruby setup.rb setup
34
+ ($ su)
35
+ # ruby setup.rb install
36
+
37
+ You can install Racc into your favorite directory by giving
38
+ options to setup.rb. e.g.
39
+
40
+ $ ruby setup.rb config --prefix=/usr
41
+
42
+ For details, try "ruby setup.rb --help".
43
+
44
+
45
+ If you don't have C Compiler
46
+ ----------------------------
47
+
48
+ You can install Racc without C compilers. Type following
49
+ command in config phase.
50
+
51
+ $ ruby setup.rb config --without-ext
52
+
53
+
54
+ == Testing Racc
55
+
56
+ Racc comes with simple calculator. To compile this, on shell:
57
+
58
+ $ racc -o calc calc.y
59
+
60
+ This process costs few seconds (or less). Then type:
61
+
62
+ $ ruby calc
63
+
64
+ ... Does it works?
65
+ For details of Racc, see HTML documents placed under 'doc.en/'
66
+ and sample grammer files under 'sample/'.
67
+
68
+
69
+ == License
70
+
71
+ Racc is distributed under the terms of the GNU Lesser General
72
+ Public License version 2. Note that you do NOT need to follow
73
+ LGPL for your own parser (racc outputs). You can provide those
74
+ files under any licenses you want.
75
+
76
+
77
+ == Bug Reports
78
+
79
+ Any kind of bug reports are welcome.
80
+ If you find a bug of Racc, please email me. Your grammer file,
81
+ debug output genereted by "racc -g", are helpful.
82
+
83
+
84
+ Minero Aoki
85
+ aamine@loveruby.net
86
+ http://i.loveruby.net
@@ -0,0 +1,96 @@
1
+ = Racc
2
+
3
+ * http://i.loveruby.net/en/projects/racc/
4
+ * http://racc.rubyforge.org/
5
+
6
+ == DESCRIPTION:
7
+
8
+ Racc は LALR(1) パーサジェネレータです。
9
+ yacc の Ruby 版に相当します。
10
+
11
+ NOTE:
12
+ Ruby 1.8.0 からは Racc のランタイムが標準添付されているので、
13
+ Racc で生成したパーサを安心して配布できます。また Ruby 1.6 系に
14
+ 対応させたい場合は racc -E で生成してください。
15
+
16
+
17
+ == 必要環境
18
+
19
+ * Ruby 1.8 以降
20
+ (*) C コンパイラと make
21
+
22
+
23
+ == インストール
24
+
25
+ gem インストール:
26
+
27
+ $ gem install racc
28
+
29
+ setup.rb インストル:
30
+
31
+ パッケージのトップディレクトリで次のように入力してください。
32
+ ($ は通常ユーザ、# はルートのプロンプトです)
33
+
34
+ $ ruby setup.rb config
35
+ $ ruby setup.rb setup
36
+ ($ su)
37
+ # ruby setup.rb install
38
+
39
+ これで通常のパスに Racc がインストールされます。自分の好き
40
+ なディレクトリにインストールしたいときは、setup.rb config に
41
+ 各種オプションをつけて実行してください。オプションのリストは
42
+
43
+ $ ruby setup.rb --help
44
+
45
+ で見られます。
46
+
47
+
48
+ コンパイラがない場合
49
+ --------------------
50
+
51
+ config を以下のようにすれば、拡張モジュールなしで
52
+ インストールできます。
53
+
54
+ $ ruby setup.rb config --without-ext
55
+
56
+
57
+ == テスト
58
+
59
+ sample/ 以下にいくつか Racc の文法ファイルのサンプルが用意
60
+ してあります。動くのも動かないのもありますが、少なくとも
61
+ calc-ja.y は動くのでこれを処理してみましょう。Racc をインス
62
+ トールしたあと
63
+
64
+ $ racc -ocalc.rb calc-ja.y
65
+
66
+ として下さい。処理は一瞬から数秒で終わるので、
67
+
68
+ $ ruby calc.rb
69
+
70
+ を実行してください。ちゃんと動いてますか?
71
+
72
+ Racc の文法など詳しいことは doc.ja/ ディレクトリ以下の HTML を
73
+ 見てください。
74
+
75
+
76
+ == ライセンス
77
+
78
+ このパッケージに付属するファイルの著作権は青木峰郎が保持します。
79
+ ライセンスは GNU Lesser General Public License (LGPL) version 2
80
+ です。ただしユーザが書いた規則ファイルや、Racc がそこから生成し
81
+ た Ruby スクリプトはその対象外です。好きなライセンスで配布して
82
+ ください。
83
+
84
+
85
+ == バグなど
86
+
87
+ Racc を使っていてバグらしき現象に遭遇したら、下記のアドレスまで
88
+ メールをください。作者にはバグを修正する義務はありませんがその
89
+ 意思はあります。また、そのときはできるだけバグを再現できる文法
90
+ ファイルを付けてください。
91
+
92
+
93
+ 青木峰郎(あおきみねろう)
94
+ aamine@loveruby.net
95
+ http://i.loveruby.net
96
+
@@ -0,0 +1,15 @@
1
+ require 'rake'
2
+ require 'rake/gempackagetask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/testtask'
5
+ require 'rake/clean'
6
+
7
+ require 'lib/racc/parser'
8
+
9
+ require 'tasks/file'
10
+ require 'tasks/gem'
11
+ require 'tasks/test'
12
+ require 'tasks/doc'
13
+ require 'tasks/email'
14
+
15
+ task :default => :test
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ * check 'error' token handling.
2
+ * interactive transition table monitor.
3
+ * support backtracking.
4
+ * output Ruby extention library?
5
+ * LL(k)? (But it should not be called Racc)
@@ -0,0 +1,308 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # $Id$
4
+ #
5
+ # Copyright (c) 1999-2006 Minero Aoki
6
+ #
7
+ # This program is free software.
8
+ # You can distribute/modify this program under the terms of
9
+ # the GNU LGPL, Lesser General Public License version 2.1.
10
+ # For details of LGPL, see the file "COPYING".
11
+ #
12
+
13
+ require 'racc/static'
14
+ require 'optparse'
15
+
16
+ def main
17
+ output = nil
18
+ debug_parser = false
19
+ make_logfile = false
20
+ logfilename = nil
21
+ make_executable = false
22
+ rubypath = nil
23
+ embed_runtime = false
24
+ debug_flags = Racc::DebugFlags.new
25
+ line_convert = true
26
+ line_convert_all = false
27
+ omit_action_call = true
28
+ superclass = nil
29
+ check_only = false
30
+ verbose = false
31
+ profiler = RaccProfiler.new(false)
32
+
33
+ parser = OptionParser.new
34
+ parser.banner = "Usage: #{File.basename($0)} [options] <input>"
35
+ parser.on('-o', '--output-file=PATH',
36
+ 'output file name [<input>.tab.rb]') {|name|
37
+ output = name
38
+ }
39
+ parser.on('-t', '--debug', 'Outputs debugging parser.') {|fl|
40
+ debug_parser = fl
41
+ }
42
+ parser.on('-g', 'Equivalent to -t (obsolete).') {|fl|
43
+ $stderr.puts "racc -g is obsolete. Use racc -t instead." if $VERBOSE
44
+ debug_parser = fl
45
+ }
46
+ parser.on('-v', '--verbose',
47
+ 'Creates <filename>.output log file.') {|fl|
48
+ make_logfile = fl
49
+ }
50
+ parser.on('-O', '--log-file=PATH',
51
+ 'Log file name [<input>.output]') {|path|
52
+ make_logfile = true
53
+ logfilename = path
54
+ }
55
+ parser.on('-e', '--executable [RUBYPATH]', 'Makes executable parser.') {|path|
56
+ executable = true
57
+ rubypath = (path == 'ruby' ? nil : path)
58
+ }
59
+ parser.on('-E', '--embedded', "Embeds Racc runtime in output.") {
60
+ embed_runtime = true
61
+ }
62
+ parser.on('--line-convert-all', 'Converts line numbers of user codes.') {
63
+ line_convert_all = true
64
+ }
65
+ parser.on('-l', '--no-line-convert', 'Never convert line numbers.') {
66
+ line_convert = false
67
+ line_convert_all = false
68
+ }
69
+ parser.on('-a', '--no-omit-actions', 'Never omit actions.') {
70
+ omit_action_call = false
71
+ }
72
+ parser.on('--superclass=CLASSNAME',
73
+ 'Uses CLASSNAME instead of Racc::Parser.') {|name|
74
+ superclass = name
75
+ }
76
+ parser.on('--runtime=FEATURE',
77
+ "Uses FEATURE instead of 'racc/parser'") {|feat|
78
+ runtime = feature
79
+ }
80
+ parser.on('-C', '--check-only', 'Checks syntax and quit immediately.') {|fl|
81
+ check_only = fl
82
+ }
83
+ parser.on('-S', '--output-status', 'Outputs internal status time to time.') {
84
+ verbose = true
85
+ }
86
+ parser.on('-P', 'Enables generator profile') {
87
+ profiler = RaccProfiler.new(true)
88
+ }
89
+ parser.on('-D flags', "Flags for Racc debugging (do not use).") {|flags|
90
+ debug_flags = Racc::DebugFlags.parse_option_string(flags)
91
+ }
92
+ #parser.on('--no-extensions', 'Run Racc without any Ruby extension.') {
93
+ # Racc.const_set :Racc_No_Extentions, true
94
+ #}
95
+ parser.on('--version', 'Prints version and quit.') {
96
+ puts "racc version #{Racc::Version}"
97
+ exit 0
98
+ }
99
+ parser.on('--runtime-version', 'Prints runtime version and quit.') {
100
+ printf "racc runtime version %s (rev. %s); %s\n",
101
+ Racc::Parser::Racc_Runtime_Version,
102
+ Racc::Parser::Racc_Runtime_Revision,
103
+ if Racc::Parser.racc_runtime_type == 'ruby'
104
+ sprintf('ruby core version %s (rev. %s)',
105
+ Racc::Parser::Racc_Runtime_Core_Version_R,
106
+ Racc::Parser::Racc_Runtime_Core_Revision_R)
107
+ else
108
+ sprintf('c core version %s (rev. %s)',
109
+ Racc::Parser::Racc_Runtime_Core_Version_C,
110
+ Racc::Parser::Racc_Runtime_Core_Revision_C)
111
+ end
112
+ exit 0
113
+ }
114
+ parser.on('--copyright', 'Prints copyright and quit.') {
115
+ puts Racc::Copyright
116
+ exit 0
117
+ }
118
+ parser.on('--help', 'Prints this message and quit.') {
119
+ puts parser.help
120
+ exit 1
121
+ }
122
+ begin
123
+ parser.parse!
124
+ rescue OptionParser::ParseError => err
125
+ $stderr.puts err.message
126
+ $stderr.puts parser.help
127
+ exit 1
128
+ end
129
+ if ARGV.empty?
130
+ $stderr.puts 'no input'
131
+ exit 1
132
+ end
133
+ if ARGV.size > 1
134
+ $stderr.puts 'too many input'
135
+ exit 1
136
+ end
137
+ input = ARGV[0]
138
+
139
+ begin
140
+ $stderr.puts 'Parsing grammar file...' if verbose
141
+ result = profiler.section('parse') {
142
+ parser = Racc::GrammarFileParser.new(debug_flags)
143
+ parser.parse(File.read(input), File.basename(input))
144
+ }
145
+ if check_only
146
+ $stderr.puts 'syntax ok'
147
+ exit 0
148
+ end
149
+
150
+ $stderr.puts 'Generating LALR states...' if verbose
151
+ states = profiler.section('nfa') {
152
+ Racc::States.new(result.grammar).nfa
153
+ }
154
+
155
+ $stderr.puts "Resolving #{states.size} states..." if verbose
156
+ profiler.section('dfa') {
157
+ states.dfa
158
+ }
159
+
160
+ $stderr.puts 'Creating parser file...' if verbose
161
+ params = result.params.dup
162
+ # Overwrites parameters given by a grammar file with command line options.
163
+ params.superclass = superclass if superclass
164
+ params.omit_action_call = true if omit_action_call
165
+ # From command line option
166
+ if make_executable
167
+ params.make_executable = true
168
+ params.interpreter = rubypath
169
+ end
170
+ params.debug_parser = debug_parser
171
+ params.convert_line = line_convert
172
+ params.convert_line_all = line_convert_all
173
+ params.embed_runtime = embed_runtime
174
+ profiler.section('generation') {
175
+ generator = Racc::ParserFileGenerator.new(states, params)
176
+ generator.generate_parser_file(output || make_filename(input, '.tab.rb'))
177
+ }
178
+
179
+ if make_logfile
180
+ profiler.section('logging') {
181
+ $stderr.puts 'Creating log file...' if verbose
182
+ logfilename ||= make_filename(output || File.basename(input), '.output')
183
+ File.open(logfilename, 'w') {|f|
184
+ Racc::LogFileGenerator.new(states, debug_flags).output f
185
+ }
186
+ }
187
+ end
188
+ if debug_flags.status_logging
189
+ log_useless states.grammar
190
+ log_conflict states
191
+ else
192
+ report_useless states.grammar
193
+ report_conflict states
194
+ end
195
+
196
+ profiler.report
197
+ rescue Racc::Error, Errno::ENOENT, Errno::EPERM => err
198
+ raise if $DEBUG or debug_flags.any?
199
+ lineno = err.message.slice(/\A\d+:/).to_s
200
+ $stderr.puts "#{File.basename $0}: #{input}:#{lineno} #{err.message.strip}"
201
+ exit 1
202
+ end
203
+ end
204
+
205
+ def make_filename(path, suffix)
206
+ path.sub(/(?:\..*?)?\z/, suffix)
207
+ end
208
+
209
+ def report_conflict(states)
210
+ if states.should_report_srconflict?
211
+ $stderr.puts "#{states.n_srconflicts} shift/reduce conflicts"
212
+ end
213
+ if states.rrconflict_exist?
214
+ $stderr.puts "#{states.n_rrconflicts} reduce/reduce conflicts"
215
+ end
216
+ end
217
+
218
+ def log_conflict(states)
219
+ logging('w') {|f|
220
+ f.puts "ex#{states.grammar.n_expected_srconflicts}"
221
+ if states.should_report_srconflict?
222
+ f.puts "sr#{states.n_srconflicts}"
223
+ end
224
+ if states.rrconflict_exist?
225
+ f.puts "rr#{states.n_rrconflicts}"
226
+ end
227
+ }
228
+ end
229
+
230
+ def report_useless(grammar)
231
+ if grammar.useless_nonterminal_exist?
232
+ $stderr.puts "#{grammar.n_useless_nonterminals} useless nonterminals"
233
+ end
234
+ if grammar.useless_rule_exist?
235
+ $stderr.puts "#{grammar.n_useless_rules} useless rules"
236
+ end
237
+ if grammar.start.useless?
238
+ $stderr.puts 'fatal: start symbol does not derive any sentence'
239
+ end
240
+ end
241
+
242
+ def log_useless(grammar)
243
+ logging('a') {|f|
244
+ if grammar.useless_nonterminal_exist?
245
+ f.puts "un#{grammar.n_useless_nonterminals}"
246
+ end
247
+ if grammar.useless_rule_exist?
248
+ f.puts "ur#{grammar.n_useless_rules}"
249
+ end
250
+ }
251
+ end
252
+
253
+ def logging(mode, &block)
254
+ File.open("log/#{File.basename(ARGV[0])}", mode, &block)
255
+ end
256
+
257
+ class RaccProfiler
258
+ def initialize(really)
259
+ @really = really
260
+ @log = []
261
+ unless ::Process.respond_to?(:times)
262
+ # Ruby 1.6
263
+ @class = ::Time
264
+ else
265
+ @class = ::Process
266
+ end
267
+ end
268
+
269
+ def section(name)
270
+ if @really
271
+ t1 = @class.times.utime
272
+ result = yield
273
+ t2 = @class.times.utime
274
+ @log.push [name, t2 - t1]
275
+ result
276
+ else
277
+ yield
278
+ end
279
+ end
280
+
281
+ def report
282
+ return unless @really
283
+ f = $stderr
284
+ total = cumulative_time()
285
+ f.puts '--task-----------+--sec------+---%-'
286
+ @log.each do |name, time|
287
+ f.printf "%-19s %s %3d%%\n", name, pjust(time,4,4), (time/total*100).to_i
288
+ end
289
+ f.puts '-----------------+-----------+-----'
290
+ f.printf "%-20s%s\n", 'total', pjust(total,4,4)
291
+ end
292
+
293
+ private
294
+
295
+ def cumulative_time
296
+ t = @log.inject(0) {|sum, (name, time)| sum + time }
297
+ t == 0 ? 0.01 : t
298
+ end
299
+
300
+ def pjust(num, i, j)
301
+ m = /(\d+)(\.\d+)?/.match(num.to_s)
302
+ str = m[1].rjust(i)
303
+ str.concat m[2].ljust(j+1)[0,j+1] if m[2]
304
+ str
305
+ end
306
+ end
307
+
308
+ main