模块 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

调用所有 actions,即使 action 为空。

–version

打印 Racc 版本并退出。

–copyright

打印版权并退出。

–help

打印用法并退出。

使用 Racc 生成 Parser

要编译 Racc 语法文件,只需键入

$ racc parse.y

这将创建 Ruby 脚本文件“parse.tab.y”。-o 选项可以更改输出文件名。

编写 Racc 语法文件

如果您想要自己的解析器,则必须编写语法文件。语法文件包含解析器类的名称、解析器的语法、用户代码以及其他任何内容。在编写语法文件时,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,而是从任何迭代器中获取 token。

例如,yyparse(obj, :scan) 会导致调用 +obj#scan+,您可以通过从 +obj#scan+ 中 yield 它们来返回 token。

调试

调试时,“-v” 或/和“-g”选项很有帮助。

“-v” 创建详细的日志文件 (.output)。“-g”创建一个“Verbose Parser”。Verbose Parser 在解析时打印内部状态。但它不是自动的。您必须使用 -g 选项并将 +@yydebug+ 设置为 true 才能获得输出。-g 选项仅创建 verbose 解析器。

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 许可证,但您的解析器不是。您自己的解析器完全属于您。

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

调用所有 actions,即使 action 为空。

–version

打印 Racc 版本并退出。

–copyright

打印版权并退出。

–help

打印用法并退出。

使用 Racc 生成 Parser

要编译 Racc 语法文件,只需键入

$ racc parse.y

这将创建 Ruby 脚本文件“parse.tab.y”。-o 选项可以更改输出文件名。

编写 Racc 语法文件

如果您想要自己的解析器,则必须编写语法文件。语法文件包含解析器类的名称、解析器的语法、用户代码以及其他任何内容。在编写语法文件时,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,而是从任何迭代器中获取 token。

例如,yyparse(obj, :scan) 会导致调用 +obj#scan+,您可以通过从 +obj#scan+ 中 yield 它们来返回 token。

调试

调试时,“-v” 或/和“-g”选项很有帮助。

“-v” 创建详细的日志文件 (.output)。“-g”创建一个“Verbose Parser”。Verbose Parser 在解析时打印内部状态。但它不是自动的。您必须使用 -g 选项并将 +@yydebug+ 设置为 true 才能获得输出。-g 选项仅创建 verbose 解析器。

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 许可证,但您的解析器不是。您自己的解析器完全属于您。

常量

VERSION
版本