处理需要使用flex和bison检查给定字符串是否使用某种语言的作业。只有在看到基本的例子之后才会出现这种情况,其中使用flex来基本上吐出读回来的内容。
作为示例,格式为{a ^ n b ^ n c ^ n}的字符串,其中n> 0将使用该语言。所以字符串aabbcc是有效的。
有没有办法让flex计算读取的特定字符?举个例子,如果给出的字符串aaabbbcc,它会计算3个a,3个b和3个c?或者我应该只使用flex来检查输入字符串是否只是正确的格式,然后在野牛中使用语法规则检查它是否在语言中?
修改
我已经研究了一段时间,似乎有一个半工作版本。我现在遇到的问题是yyparse()似乎永远不会退出,当给出无效字符串时,它会遇到语法错误。举个例子:
字符串“aabbcc”应该在我所谓的L2中。我将得到以下输出:
grammar recognizer result:
L2 recognized
然后它就会停止并永远不会完成。另外,字符串“hjnkll”不应被识别,但我输入类似的东西时只会出现语法错误 Flex
...
A [a]*
B [b]*
C [c]*
D [d]*
E [e]*
Z [^a-e\n][.]*
%%
{A} {a = yyleng;} return A;
{B} {b = yyleng;} return B;
{C} {c = yyleng;} return C;
{D} {d = yyleng;} return D;
{E} {e = yyleng;} return E;
{Z} {z = yyleng;} return Z;
\n return NL;
%%
Bison Snipets
%token A
%token B
%token C
%token D
%token E
%token Z
%token NL
%%
/*grammer rules*/
transunit: L1 | L2 | L5 | L6
{
printf("\n*****Congratulations; Parse Successful*****\n");
}
;
L2: A B C NL
{
/*Language 2 : L(G2) = {a^nb^nc^n} with n > 0*/
if(a==b && b==c && d==0 && e==0 && a!=0 && z==0){
printf("\nLG2 recognized\n");
} else {
printf("\nSorry language not recognized\n");
}
}
;
/*None of the above : not recognized*/
L6: Z NL
{
printf("\nSorry language not recognized\n");
}
;
答案 0 :(得分:1)
为了完整起见,向Bison添加计数检查很简单。这是一个简单的例子(它识别或抱怨输入行,以便更容易玩):
我遗漏了大部分样板内容,包括main
和yyerror
函数。但我确实提出了一些弹性选项。使用'a'
来表示“任意数量的a
s”正在扩大边界;最好定义名为As
,Bs
和Cs
的标记,然后将弹性规则分为五个不同的规则等等。这个更短。 :)
<强>野牛强>
%{
#include <stdio.h>
%}
%%
start: line
| start line
;
line: 'a' 'b' 'c' '\n' { if ($1 == $2 && $2 == $3)
fputs("Good!\n", stderr);
else
fputs("Bad!\n", stderr);
}
<强>柔性强>:
%{
extern int yylval;
%}
%option noyywrap noinput nounput
%%
"a"+|"b"+|"c"+|.|\n { yylval = yyleng; return *yytext; }
答案 1 :(得分:0)
字符串 a n b n c n 既不是常规的也不是无上下文的。该字符串只能由Context Sensitive Grammar
或Unrestricted Grammar
生成,具体取决于n的值。因此,无法使用 Flex 或 Bison 检查字符串。 Flex是一个扫描仪生成器,它只能检查正则表达式。 Bison是一个解析器生成器,它只能检查上下文敏感语言。
答案 2 :(得分:0)
对于您的具体示例,您可以使用状态匹配a+b+c+
。然后,只需检查a,b和c的出现次数,并确保它们全部相等。但是,如果您的语言有超过2或3个规则,则此解决方案会迅速呈指数级增长。
%{
int a = 0, b = 0, c = 0;
%}
%x Bstate Cstate
%%
"a"+ { a = yyleng; BEGIN(Bstate); }
. { /* not in language; error! */ }
<Bstate>"b"+ { b = yyleng; BEGIN(Cstate); }
<Bstate>. { /* not in language; error! */ }
<Cstate>"c"+ { c = yyleng;
if(a != b || a != c) {
/* not in language; error! */
}
BEGIN(INITIAL); }
<Cstate>. { /* not in language; error! */ }
%%
相反,您可以告诉flex匹配"a"+"b"+"c"+
然后逐个字符地迭代字符串,但是这会使用flex overkill。
有关州的更多信息,请参见此处:http://aquamentus.com/flex_bison.html#17`