使用Flex和Bison?

时间:2013-09-15 18:26:54

标签: bison flex-lexer

处理需要使用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");
    }
;

3 个答案:

答案 0 :(得分:1)

为了完整起见,向Bison添加计数检查很简单。这是一个简单的例子(它识别或抱怨输入行,以便更容易玩):

我遗漏了大部分样板内容,包括mainyyerror函数。但我确实提出了一些弹性选项。使用'a'来表示“任意数量的a s”正在扩大边界;最好定义名为AsBsCs的标记,然后将弹性规则分为五个不同的规则等等。这个更短。 :)

<强>野牛

%{
#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 GrammarUnrestricted 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`