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
     :
     :