模块 Racc
Racc
是一个 LALR(1) 解析器生成器。它是用 Ruby 本身编写的,并生成 Ruby 程序。
命令行参考¶ ↑
racc [-o<var>filename</var>] [--output-file=<var>filename</var>] [-e<var>rubypath</var>] [--executable=<var>rubypath</var>] [-v] [--verbose] [-O<var>filename</var>] [--log-file=<var>filename</var>] [-g] [--debug] [-E] [--embedded] [-l] [--no-line-convert] [-c] [--line-convert-all] [-a] [--no-omit-actions] [-C] [--check-only] [-S] [--output-status] [--version] [--copyright] [--help] <var>grammarfile</var>
grammarfile
-
Racc
语法文件。允许任何扩展名。 - -o+outfile+,–output-file=
outfile
-
输出文件的文件名。默认为 <
filename
>.tab.rb - -O+filename+,–log-file=
filename
-
将日志输出放置在文件
filename
中。默认的日志文件名是 <filename
>.output。 - -e+rubypath+,–executable=
rubypath
-
输出可执行文件(模式 755)。其中
path
是 Ruby 解释器。 - -v,–verbose
-
详细模式。创建
filename
.output 文件,类似于 yacc 的 y.output 文件。 - -g,–debug
-
向解析器类添加调试代码。要显示调试信息,请使用此“-g”选项并在解析器类中设置 @yydebug 为 true。
- -E,–embedded
-
输出不需要运行时文件 (racc/parser.rb) 的解析器。
- -F,–frozen
-
输出声明 frozen_string_literals: true 的解析器
- -C,–check-only
-
检查 racc 语法文件的语法并退出。
- -S,–output-status
-
在编译时,不时打印消息。
- -l,–no-line-convert
-
关闭行号转换。
- -c,–line-convert-all
-
转换 actions、inner、header 和 footer 的行号。
- -a,–no-omit-actions
-
调用所有 action,即使 action 为空。
- –version
-
打印
Racc
版本并退出。 - –copyright
-
打印版权并退出。
- –help
-
打印用法并退出。
使用 Racc
生成 Parser
¶ ↑
要编译 Racc
语法文件,只需键入
$ racc parse.y
这将创建 Ruby 脚本文件“parse.tab.y”。-o 选项可以更改输出文件名。
编写 Racc
Grammar
文件¶ ↑
如果您想要自己的解析器,则必须编写语法文件。语法文件包含解析器类的名称、解析器的语法、用户代码以及任何其他内容。编写语法文件时,yacc 的知识很有帮助。如果您以前没有使用过 yacc,那么 Racc
并不太难。
这是一个 Racc
语法文件的示例。
class Calcparser rule target: exp { print val[0] } exp: exp '+' exp | exp '*' exp | '(' exp ')' | NUMBER end
Racc
语法文件类似于 yacc 文件。但是(当然),这是 Ruby 代码。yacc 的 $$ 是 ‘result’,$0,$1… 是一个名为 ‘val’ 的数组,$-1,$-2… 是一个名为 ‘_values’ 的数组。
有关语法文件的更多信息,请参阅语法文件参考。
Parser
¶ ↑
然后,您必须准备解析入口方法。Racc
中有两种类型的解析方法,Racc::Parser#do_parse 和 Racc::Parser#yyparse
Racc::Parser#do_parse 很简单。
它是 yacc 的 yyparse(),Racc::Parser#next_token
是 yylex()。此方法必须返回一个类似于 [TOKENSYMBOL, ITS_VALUE] 的数组。EOF 是 [false, false]。(TOKENSYMBOL 默认是 Ruby 符号(取自 String#intern)。如果要更改此设置,请参阅语法参考。
Racc::Parser#yyparse 有点复杂,但很有用。它不使用 Racc::Parser#next_token
,而是从任何迭代器获取令牌。
例如,yyparse(obj, :scan)
会导致调用 +obj#scan+,并且您可以通过从 +obj#scan+ 中 yield 它们来返回令牌。
调试¶ ↑
调试时,“-v”或/和“-g”选项很有帮助。
“-v”创建详细的日志文件 (.output)。“-g”创建一个“详细解析器”。详细的 Parser
在解析时会打印内部状态。但这不是自动的。您必须使用 -g 选项并将 +@yydebug+ 设置为 true
才能获得输出。-g 选项仅创建详细解析器。
Racc
报告语法错误。¶ ↑
“end”太多了吗?racc 文件的语法在 v0.10 中已更改。
Racc
不使用“%”标记,而 yacc 使用大量的“%”标记。
Racc
报告“XXXX 冲突”。¶ ↑
尝试“racc -v xxxx.y”。它会导致生成 racc 的内部日志文件 xxxx.output。
生成的解析器无法正常工作¶ ↑
尝试“racc -g xxxx.y”。此命令让 racc 生成“调试解析器”。然后在您的解析器中设置 @yydebug=true。它会生成解析器的工作日志。
重新分发 Racc
运行时¶ ↑
由 Racc
创建的解析器需要 Racc
运行时模块:racc/parser.rb。
Ruby 1.8.x 附带 Racc
运行时模块,您不需要分发 Racc
运行时文件。
如果要将 Racc
运行时模块包含在解析器中。这可以通过使用“-E”选项来完成
$ racc -E -omyparser.rb myparser.y
此命令创建 myparser.rb,它“包含”Racc
运行时。您唯一需要做的是分发您的解析器文件 (myparser.rb)。
注意:parser.rb 是 ruby 许可证,但您的解析器不是。您自己的解析器完全属于您。
常量
- 版权
- GrammarFileParser
- PARSER_TEXT
- StateTransitionTable
- VERSION
- 版本