我正在 GNU-Bison 中编写一个解析器,以解析捕获的专有协议数据位。解析器具有以下标记:
H
.......标头D
.......数据T
.......终结者和五个数字D
,即数据令牌组成了 批量 B
即
B : DDDDD
;
理想情况下,输入形式应为
H DDDDD DDDDD DDDDD ... DDDDD T
aka
H B B B ... B T
所以我写了以下语法:
%%
CAPTURE : H PAYLOAD T { printf("[OK]");}
;
PAYLOAD : B
| PAYLOAD B
;
B : DDDDDD
%%
现在,要满足一些实际条件,例如以下模式:
DD H DDDDD DDDDD ... DDDDD T
(前缀D开头)H DDDDD DDDDD ... DDD T
(最后一个 批量 被截短,仅有3个数据D
)我将语法修改为
%%
CAPTURE : H PAYLOAD T { printf("[OK]");}
;
PAYLOAD : B
| PAYLOAD B
| D PAYLOAD
| PAYLOAD D
;
B : DDDDDD
%%
但是它给出了shift/reduce conflict
。
需要帮助来纠正语法,以便它也可以识别上述两种情况,并且不会发生移位/减少冲突。
答案 0 :(得分:1)
%%
CAPTURE : OPTD1 H PAYLOAD OPTD2 T { printf("[OK]");}
;
PAYLOAD : B
| PAYLOAD B
;
B : D D D D D
;
OPTD1 :
| OPTD1 D
;
OPTD2 :
| D D D
;
%%
我在第一个产品的右侧添加了两个新的非终结符OPTD1
和OPTD2
,并保持了PAYLOAD
的原始规则。 OPTD1
可以重写为0或多个D
终端符号,OPTD2
可以重写为0或3个D
终端符号。
如果您的令牌,H,T和B分别只是字符“ H”,“ T”和“ B”,则可以使用以下正则表达式轻松识别有效输入:
'^D*H(DDDDD)+(DDD)?T$'
无论如何,您应该能够通过有限状态自动机识别有效输入,而无需使用YACC提供的下推自动机。