使用Flex和Bison?

使用Flex和Bison?,bison,flex-lexer,Bison,Flex Lexer,处理需要使用flex和bison来检查给定字符串是否使用某种语言的赋值。这只是在看到基本示例之后才出现的,在这些示例中,flex基本上是用来回吐读入的内容的 例如,格式为{a^n b^n c^n}且n>0的字符串将使用该语言。因此字符串aabbcc是有效的 flex是否有办法计算读取的特定字符数?例如,如果字符串aaabbbcc在给定的位置,它将计数3个a、3个b和3个c?或者我应该简单地使用flex检查输入字符串的格式是否正确,然后使用bison中的语法规则检查它是否在语言中 编辑 我已经做了

处理需要使用flex和bison来检查给定字符串是否使用某种语言的赋值。这只是在看到基本示例之后才出现的,在这些示例中,flex基本上是用来回吐读入的内容的

例如,格式为{a^n b^n c^n}且n>0的字符串将使用该语言。因此字符串aabbcc是有效的

flex是否有办法计算读取的特定字符数?例如,如果字符串aaabbbcc在给定的位置,它将计数3个a、3个b和3个c?或者我应该简单地使用flex检查输入字符串的格式是否正确,然后使用bison中的语法规则检查它是否在语言中

编辑
我已经做了一段时间,似乎有一个半工作版本。我现在遇到的问题是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;
%%
%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");
    }
;
野牛鹬

...  
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;
%%
%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");
    }
;

字符串anbncn
既不是规则的,也不是上下文无关的。字符串只能由
上下文敏感语法
非限制语法
生成,具体取决于n的值。因此不能使用FlexBison检查字符串。Flex是一个扫描生成器,它只能检查正则表达式。Bison是一个解析器生成器,它只能检查上下文敏感的语言

字符串anbncn既不是规则的,也不是上下文无关的。字符串只能由
上下文敏感语法
非限制语法
生成,具体取决于n的值。因此不能使用FlexBison检查字符串。Flex是一个扫描生成器,它只能检查正则表达式。Bison是一个解析器生成器,它只能检查上下文敏感的语言

对于您的特定示例,您可以使用状态匹配
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! */        }
%%
%{
int a=0,b=0,c=0;
%}
%x Bstate Cstate
%%
“a”+{a=yyleng;BEGIN(Bstate);}
.                   {/*不是语言;错误!*/}
“b”+{b=yyleng;BEGIN(Cstate);}
.           {/*不是语言;错误!*/}
“c”+{c=yyleng;
如果(a!=b | | a!=c){
/*语言不通;错误*/
}
开始(首字母);}
.           {/*不是语言;错误!*/}
%%
相反,您可以告诉flex匹配
“a”+“b”+“c”+
,然后逐个字符地迭代字符串,但这会使使用flex变得过度


有关状态的更多信息,请参见此处:`

对于您的特定示例,您可以使用状态匹配
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! */        }
%%
%{
int a=0,b=0,c=0;
%}
%x Bstate Cstate
%%
“a”+{a=yyleng;BEGIN(Bstate);}
.                   {/*不是语言;错误!*/}
“b”+{b=yyleng;BEGIN(Cstate);}
.           {/*不是语言;错误!*/}
“c”+{c=yyleng;
如果(a!=b | | a!=c){
/*语言不通;错误*/
}
开始(首字母);}
.           {/*不是语言;错误!*/}
%%
相反,您可以告诉flex匹配
“a”+“b”+“c”+
,然后逐个字符地迭代字符串,但这会使使用flex变得过度


有关状态的更多信息,请参见此处:`

为了完整性,向bison添加计数检查很简单。下面是一个简单的示例(识别或抱怨输入行,以便更容易使用):

我省略了大部分样板文件,包括
main
yyrerror
函数。但我确实加入了一些弹性选项。使用
'a'
来表示“任意数量的
a
s”是在扩展边界;最好将名为
的标记定义为
Bs
Cs
,然后将flex规则拆分为五个不同的规则,等等。这样做比较短。:)

野牛

%{
#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);
                       }

为了完整性,向bison添加计数检查很简单。下面是一个简单的示例(识别或抱怨输入行,以便更容易使用):

我省略了大部分样板文件,包括
main
yyrerror
函数。但我确实加入了一些弹性选项。使用
'a'
来表示“任意数量的
a
s”是在扩展边界;最好将名为
的标记定义为
Bs
Cs
,然后将flex规则拆分为五个不同的规则,等等。这样做比较短。:)

野牛

%{
#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);
                       }
“取决于n的值”是什么意思?如果已知
n
,则该语言是有限的,因此与上下文无关。如果
n
未知,则该语言是上下文敏感的。语言不区分上下文的唯一情况是,只有