flex + bison,具有不同语法的部分

时间:2015-06-29 15:56:53

标签: bison flex-lexer

我正在使用flex& amp;中的解析器bison应该解析具有不同语法的不同部分的源代码。

想到php,这只是&#34;愚蠢的&#34;转储所有内容,直到找到 <?php,然后它进入一个实际解析东西的语法部分,当它找到?>时,它会回到转储。

所以当我在&#34;倾销&#34;部分,扫描仪应该只提供原始字符串。有意义的标记(WHILE,OPENPARENTHESIS,IDENTIFIER等)只应在句法部分提供,并且\开始一个句法部分。

我发现你可以赋予flex规则不同的"start conditions", 所以我基本上可以在不同的扫描仪之间切换,如

%x semantic
%x dump
%%
<dump>"\\"        { BEGIN(semantic); }
<dump>.           { (*yylval).stringvalue = yytext; return yy::parser::token::CHAR;}
<semantic>"while" {return yy::parser::token::WHILE;}

这就是我真正需要的。

我的问题是语法部分的结尾不能用正则表达式来描述,所以这个决定不能在扫描程序中完成,它必须由解析器完成。我基本上希望它回到转储模式&#34;在规则和#34;之间。所以我想做一些像

这样的事情
CODEELEMENT: FOR OPEN STATEMENT SEMICOLON BOOL SEMICOLON STATEMENT CLOSE <<GO TO DUMP MODE>> ELEMENT

你可能会说,这应该成为C语言中的for-loop之类的规则,但是&#34; body&#34; (ELEMENT)应该再次作为转储读取(这将只提供一个字符,除非您将多个字符与{和}再次组合在一起)

我知道野牛可以执行代码&#34;在规则和#34;之间,我试图声明一个全局变量(ugh)&#34; dumpmode&#34;,将{dumpmode = true;}放入像这样的规则

CODEELEMENT: FOR OPEN STATEMENT SEMICOLON BOOL SEMICOLON STATEMENT CLOSE {dumpmode = true;} ELEMENT

并放

if(dumpmode)
{
    BEGIN(dump);
    dumpmode = false;
}
在弹性规则前面的

(这类似于我上面链接的页面上的例子)

但是这不起作用,它实际上是有道理的 - AFAIK野牛已经需要最终的ELEMENT令牌来决定使用该规则(因此代码不会在令牌到来之前执行),但这个令牌只会由转储模式生成,该模式在该过程中的该点处不活动。

你知道这样做的方法吗?从规则之间的野牛代码切换flexer的开始条件?也许我需要像

那样打破野牛规则
CODEELEMENT: FOR1 FOR2
    ;
FOR1: FOR OPEN STATEMENT SEMICOLON BOOL SEMICOLON STATEMENT CLOSE {dumpmode = true;}
    ;
FOR2: ELEMENT
    ;

但我不认为这种方法适用于if-then-else结构......

1 个答案:

答案 0 :(得分:2)

您是否尝试过函数void yy_pop_state (),从Bison部分调用它?