Racc
语法文件参考¶ ↑
全局结构¶ ↑
类块和用户代码块¶ ↑
有两个顶级块:‘class’ 块和 ‘user code’ 块。 ‘user code’ 块必须在 ‘class’ 块之后。
注释¶ ↑
几乎可以在任何地方添加注释。支持两种注释风格:Ruby 风格 (`# ...`) 和 C 风格 (`/* ... */`)。
类块¶ ↑
类块的格式如下
class CLASS_NAME [precedence table] [token declarations] [expected number of S/R conflict] [options] [semantic value conversion] [start rule] rule GRAMMARS
CLASS_NAME 是解析器类的名称。这是生成解析器类的名称。
如果 CLASS_NAME 包含 ‘::’,Racc
将输出模块子句。例如,编写“class M::C”会导致创建以下代码
module M class C : : end end
语法块¶ ↑
语法块描述了解析器要理解的语法。语法为
(token): (token) (token) (token).... (action) (token): (token) (token) (token).... (action) | (token) (token) (token).... (action) | (token) (token) (token).... (action)
(action) 是当找到其 (token) 时执行的操作。(action) 是一个 Ruby 代码块,它被大括号包围
{ print val[0] puts val[1] }
请注意,您不能在 action 中使用 ‘%’ 字符串、here document、‘%r’ 正则表达式。
可以省略操作。省略时,使用 “(空字符串)”。
操作的返回值是左侧值 ($$) 的值。它是结果的值,或者是 “return” 语句返回的值。
以下是整个语法块的示例。
rule goal: definition rules source { result = val } definition: /* none */ { result = [] } | definition startdesig { result[0] = val[1] } | definition precrule # this line continue from upper line { result[1] = val[1] } startdesig: START TOKEN
您可以在 action 中使用以下特殊的局部变量。
* result ($$)
左侧 (lhs) 的值。默认值为 val。
* val ($1,$2,$3...)
右侧 (rhs) 值的数组。
* _values (...$-2,$-1,$0)
值的堆栈。除非您知道自己在做什么,否则请勿修改此堆栈。
运算符优先级¶ ↑
此函数等效于 yacc 中的 ‘%prec’。要指定此块
prechigh nonassoc '++' left '*' '/' left '+' '-' right '=' preclow
‘right’ 是 yacc 的 %right,‘left’ 是 yacc 的 %left。
‘=’ + (symbol) 表示 yacc 的 %prec
prechigh nonassoc UMINUS left '*' '/' left '+' '-' preclow rule exp: exp '*' exp | exp '-' exp | '-' exp =UMINUS # equals to "%prec UMINUS" : :
expect¶ ↑
Racc
支持 Bison 的 “expect” 指令来声明预期的 shift/reduce 冲突数。
class MyParser expect 3 rule : :
只有当冲突的有效数量不同时才会发出警告。
声明标记¶ ↑
声明标记可以避免许多错误。
Racc
会为不存在的已声明标记或未声明的现有标记输出警告。语法为
token TOKEN_NAME AND_IS_THIS ALSO_THIS_IS AGAIN_AND_AGAIN THIS_IS_LAST
选项¶ ↑
您可以在 racc 文件中为 racc 命令编写选项。
options OPTION OPTION ...
选项有
* omit_action_call
是否省略空操作调用。
* result_var
使用/不使用局部变量 “result”
您可以使用 ‘no_’ 前缀来反转其含义。
转换标记符号¶ ↑
标记符号的默认值是
* naked token strings in racc file (TOK, XFILE, this_is_token, ...) --> symbol (:TOK, :XFILE, :this_is_token, ...) * quoted strings (':', '.', '(', ...) --> same string (':', '.', '(', ...)
您可以使用 “convert” 块更改此默认值。这是一个例子
convert PLUS 'PlusClass' # We use PlusClass for symbol of `PLUS' MIN 'MinusClass' # We use MinusClass for symbol of `MIN' end
除了 ‘false’ 和 ‘nil’ 之外,我们可以使用几乎所有可以被标记符号使用的 Ruby 值。这些会导致意外的解析错误。
如果要使用字符串作为标记符号,则需要特别注意。例如
convert class '"cls"' # in code, "cls" PLUS '"plus\n"' # in code, "plus\n" MIN "\"minus#{val}\"" # in code, \"minus#{val}\" end
起始规则¶ ↑
yacc 中的 ‘%start’。这会更改起始符号。
start real_target
用户代码块¶ ↑
“用户代码块” 是复制到输出中的一段 Ruby 源代码。有三个用户代码块,“header”、“inner” 和 “footer”。
用户代码块以一行的开头四个 ‘-’ 引入,后跟一个单字名称
---- header ruby statement ruby statement ruby statement ---- inner ruby statement : :