【问题标题】:Does Bison allow "?" in its syntax野牛允许“?”在它的语法中
【发布时间】:2017-12-07 03:42:14
【问题描述】:

我正在尝试为 Java 规范编写语法 例如:-

COMPILATION_UNIT: PACKAGE_DEC? IMPORT_DECS? TYPE_DECS?

但它不起作用 我有以下错误:

无效字符:`?'

对于我在file.y 中使用的每个问号

我知道 Bison 有特殊字符,它应该处理它

请帮忙

【问题讨论】:

  • grammar: token | ; 现在,在您的主要规则中包含符号 grammar

标签: c++ parsing bison flex-lexer


【解决方案1】:

Bison 不允许 ?意味着前面的标记是可选的,你必须用可选元素写出语法:

package_decl_opt: %empty
| SOME_TOKEN
;
package: package)_dec_opt TOKEN_PACKAGE TOKEN_IDENTIFIER
;

将允许以下两种情况:

SOME_TOKEN TOKEN_PACKAGE TOKEN_IDENTIFIER
TOKEN_PACKAGE TOKEN_IDENTIFIER

【讨论】:

    【解决方案2】:

    如您所见,bison 没有实现? 正则表达式可选运算符。它也没有实现+* 重复运算符。这是因为上下文无关文法中产生式的右侧不是正则表达式。

    Yacc/bison 上下文无关语法确实允许| 交替运算符,但作为缩写:

    a : b | c
    

    和写完全一样

    a : b
    a : c
    

    而语义动作只适用于指定它们的备选方案,因此

    a : b | c { /* C action; */ }
    

    相当于:

    a : b    { /* Implicit default action*/ }
    a : c    { /* C action; */ }
    

    很容易创建X_opt 非终端来捕获X? 的语义:

    X_opt: X | %empty { $$ = default_value; }
    

    在许多简单的情况下都可以正常工作,但也有许多语法在其中引入了不必要的 shift-reduce 冲突。例如:

    label: IDENT ':'
    label_opt: label | %empty
    statement: label_opt expr
    

    由于expr 可以以标识符开头,因此无法知道IDENT 令牌是否以label 开头,或者它是否在空label_opt 之后开始expr。但是 LR(1) 要求在消耗 IDENT 之前减少空的 label_opt。所以上面的语法是LR(2),不能被LR(1)解析器正确解析。

    如果不使用label_opt 快捷方式,则不会出现该问题:

    label: IDENT ':'
    statement: label expr
             | expr
    

    由于解析器现在在遇到':' 之前没有在labelexpr 之间做出决定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-11
      • 1970-01-01
      相关资源
      最近更新 更多