Bison允许"?"在它的语法中

时间:2017-12-07 03:42:15

标签: c++ parsing bison flex-lexer

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

$cfg['Servers'][$i]['auth_type'] = 'cookie';
$cfg['Servers'][$i]['user'] = 'root';
$cfg['Servers'][$i]['password'] = 'password';
$cfg['Servers'][$i]['extension'] = 'mysqli';
$cfg['Servers'][$i]['AllowNoPassword'] = true;

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

  

无效字符:`?'

我在COMPILATION_UNIT: PACKAGE_DEC? IMPORT_DECS? TYPE_DECS?

中使用的每个问号

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

请帮忙

2 个答案:

答案 0 :(得分:0)

如您所见,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; }

在许多简单的情况下,它们可以正常工作,但也有许多语法引入了不必要的移位减少冲突。例如,考虑一下:

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

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

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

label_opt

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

答案 1 :(得分:0)

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

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

将允许以下两种情况:

SOME_TOKEN TOKEN_PACKAGE TOKEN_IDENTIFIER
TOKEN_PACKAGE TOKEN_IDENTIFIER