1

我有以下词法分析器规则:

let ws = [' ' '\t' '\n']+
... 
| ws                  {Printf.printf "%s" (Lexing.lexeme lexbuf); WS(Lexing.lexeme lexbuf)}

以及以下解析器规则:

%token <string>  WORD WS 
cs               :  LSQRB wsornon choices wsornon RSQRB {$2}
                 ;

wsornon          : /* nothing */
                 | WS {$1}
                 ;

choices          :  choice {$1}
                 |  choices choice {$2}
                 ;

choice           :  CHOICE LCURLYB mainbody RCURLYB {$3}
                 ;

我基本上想wsornon匹配空白或什么都没有。但是cs在没有空格的情况下给出语法错误(对应于空规则)。

我错过了什么吗?

4

1 回答 1

4

即使你解析空流,你也应该有一个生产规则:

wsornon:
  |    { something for nothing }
  | WS { something for whitespace }

请注意,menhir有一个OPTION参数化规则,它对这类事情很好,因此您不必为此编写另一个规则。实际上OPTION(foo)bar option如果 rulefoo返回 type 的内容,则返回 type 的产生式bar,而无论如何您都会忽略它们,所以情况有点不同。

如果您想忽略空格,为什么不在词法分析器步骤中完全放弃它呢?它在你语法的其他地方有用吗?我宁愿稍微破解词法分析器,以便在我知道它们很重要的一些标记之后有一些空白标记,而不是让它们污染我的整个语法。当然,menhir 允许定义可以帮助的参数化规则(下面的示例未经测试):

ws(rule):
| LIST(WS) result = rule LIST(WS) { result }
于 2012-12-28T21:34:27.707 回答