Compiler construction yacc中的回文
我写了一个yacc中数字回文的语法。但它不接受输入字符串。 这是我的语法:Compiler construction yacc中的回文,compiler-construction,yacc,palindrome,Compiler Construction,Yacc,Palindrome,我写了一个yacc中数字回文的语法。但它不接受输入字符串。 这是我的语法: T: PAL '\n' {printf("Accepted\n");return 0;}; PAL: "1" PAL "1"| "2" PAL "2"| "3" PAL "3"| "4" PAL "4"| "5" PAL "5"| "6" PAL "6"| "7" PAL "7"| "8" PAL "8"|"1"|"2"|"3"|"4"|"5"|"6"
T: PAL '\n' {printf("Accepted\n");return 0;};
PAL: "1" PAL "1"|
"2" PAL "2"|
"3" PAL "3"|
"4" PAL "4"|
"5" PAL "5"|
"6" PAL "6"|
"7" PAL "7"|
"8" PAL "8"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"|"0"|;
当我输入数字时,它将显示错误消息
这是我的yacc文件内容
朋友
请帮帮我 @Ron是对的。yacc只能解析先行左-右(LALR)语法,回文不是LALR语法。这是因为要确定它是否是回文,需要的不仅仅是一次前瞻。yacc解析LALR(1)语言,这是上下文无关语言(CFL)的一个子类,设计用于在 线性时间。要解析回文,解析器必须能够确定它何时到达回文的中间。只需向前看一眼 (或任何固定数字)这是不可能的
查看此页了解更多详细信息。最流行的yacc(在linux和许多其他系统中)之一是Bison,yacc的gnu版本有一些额外的功能。 除了LALR(1),它还可以生成LR(1)、GLR GLR算法可用于该问题 当GLR解析器遇到冲突时,它会分裂 转换为多个解析器,每个解析器对应一个可能的移位或缩减。 然后,这些解析器照常进行,在锁定步骤中使用令牌。 某些堆栈可能会遇到其他冲突并进一步分裂, 结果是一个野牛GLR代替了一系列的状态 解析堆栈实际上是一个状态树 在以下内容中,您将看到一个使用的示例:
选择glr解析器算法%glr parse
伪非终端(处理“无效”)错误
- 更改了
,类似于“1”
“1”
%{
#include <stdio.h>
int i=0;
%}
%glr-parser
%%
S : pal '\n' {i=1; return 1 ;}
| error '\n' {i=0; return 1 ;}
pal: '0' pal '0'
| '1' pal '1'
...
| '0'
| '1'
|
;
%%
#include "lex.yy.c"
int main() {
yyparse();
if(i==1) printf("Valid\n");
else printf("inValid\n");
return 0;
}
int yyerror(char* s) { return 0; }
%{
#包括
int i=0;
%}
%glr解析器
%%
S:pal'\n'{i=1;返回1;}
|错误'\n'{i=0;返回1;}
好友:“0”好友“0”
|“1”朋友“1”
...
| '0'
| '1'
|
;
%%
#包括“lex.yy.c”
int main(){
yyparse();
如果(i==1)printf(“有效\n”);
else printf(“无效\n”);
返回0;
}
int yyerror(char*s){返回0;}
请将获得的结果与原始版本和此版本进行比较,例如与
1
11
111
101101
以及一些无效表达式进行比较。我在yacc文件中给出的错误消息。LR无法解析回文,不是吗?这并不是说你的语法是回文。除非你是这么说的。:-)你的意见是什么?(最好使用所述输入的十六进制转储)此外,由于语法认为它只会看到数字和“\n”,因此,如果您的lexer反对其他字符,而不是将所有非法标记传递给解析器,这将有助于证明。或者,改变错误以显示“不接受”的内容。但最有可能的是,问题不在于理解回文在LR解析能力之外。。。考虑输入“11”。你有一个问题并不是真正问题的核心:<代码> 1”/代码>与<代码> 1 的输入不匹配。在Y文件中,你需要使用<代码> '1' <代码>来匹配单个字符令牌。在.y文件中使用双引号(“
)在大多数情况下会产生非常不直观和无用的效果。@ChrisDodd,谢谢你的重要评论。我一直避免使用”。。。“
bison中的代币,因为我不知道从lexer中返回它们的好方法:我认为,你发表评论作为答案以澄清这个棘手的陷阱是很重要的☺@朗伯克,我明白你大部分观察的要点。如果你有时间,请检查我的回答是否有意义。清楚全面(+1)!尽管如此,我还是使用野牛的“新”功能添加了一个额外的答案——请检查这是否有意义。
%{
#include "y.tab.h"
%}
%%
\n {return *yytext;}
. {return *yytext;}
%%
%option noyywrap
%%
[0-9\n] {return yytext[0]; }
. {fprintf(stderr, "Error\n"); exit(1);}
%%
%{
#include <stdio.h>
int i=0;
%}
%glr-parser
%%
S : pal '\n' {i=1; return 1 ;}
| error '\n' {i=0; return 1 ;}
pal: '0' pal '0'
| '1' pal '1'
...
| '0'
| '1'
|
;
%%
#include "lex.yy.c"
int main() {
yyparse();
if(i==1) printf("Valid\n");
else printf("inValid\n");
return 0;
}
int yyerror(char* s) { return 0; }