Racc
语法文件参考¶ ↑
全局结构¶ ↑
类块和用户代码块¶ ↑
在顶层有两个块。一个是“类”块,另一个是“用户代码”块。“用户代码”块必须放在“类”块之后。
注释¶ ↑
你可以在所有地方插入注释。可以使用两种注释风格,Ruby 风格的“#.….”和 C 风格的“/*.…..*/”。
类块¶ ↑
类块的格式如下
class CLASS_NAME [precedence table] [token declarations] [expected number of S/R conflicts] [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)
当找到 (token) 时,将执行 (action)。(action) 是一个 ruby 代码块,它用大括号括起来
{ print val[0] puts val[1] }
请注意,你不能在 action 中使用“%”字符串、here document、“%r”正则表达式。
可以省略动作。当省略时,使用“”(空字符串)。
action 的返回值是左侧值 ($$) 的值。它是结果值,或者由 'return' 语句返回的值。
这是整个语法块的示例。
rule goal: definition rules source { result = val } definition: /* none */ { result = [] } | definition startdesig { result[0] = val[1] } | definition precrule # this line continues from upper line { result[1] = val[1] } startdesig: START TOKEN
你可以在 action 中使用以下特殊局部变量
-
结果 ($$)
左侧 (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” 指令。
# Example class MyParser expect 3 rule : :
此指令声明 “预期” 的移位/规约冲突的数量。如果 “预期” 数量等于实际的冲突数量,Racc
不会打印冲突警告消息。
声明标记¶ ↑
通过声明标记,你可以避免许多无意义的错误。如果声明的标记不存在,或者存在的标记未声明,Racc
会输出警告。声明语法为
token TOKEN_NAME AND_IS_THIS ALSO_THIS_IS AGAIN_AND_AGAIN THIS_IS_LAST
选项¶ ↑
options OPTION OPTION ...
选项为
-
omit_action_call
是否省略空 action 调用。
-
result_var
是否使用局部变量 “result”。
你可以使用 'no_' 前缀来反转它们的含义。
转换标记符号¶ ↑
默认情况下,标记符号是
* naked token string in Racc file (TOK, XFILE, this_is_token, ...) --> symbol (:TOK, :XFILE, :this_is_token, ...) * quoted string (':', '.', '(', ...) --> same string (':', '.', '(', ...)
你可以通过 “convert” 块来更改此默认值。这是一个例子
convert PLUS 'PlusClass' # We use PlusClass for symbol of `PLUS' MIN 'MinusClass' # We use MinusClass for symbol of `MIN' end
我们可以使用几乎所有 ruby 值作为标记符号,除了 “false” 和 “nil”。这些会导致意外的解析错误。
如果你想使用 String 作为标记符号,则需要特别注意。例如
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 : :
如果行首存在四个 “-”,则 Racc
会将其视为用户代码块的开始。用户代码块的名称必须是一个单词。