我正在尝试为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有特殊字符,应该处理它
请帮忙
答案 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
之前没有在label
和expr
之间做出决定。
答案 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