我必须解析多个文件,每个案例都有不同的规则。那就是:我需要一些规则来处理文件,然后被禁用。
我可以简单地使用全局变量来跟踪程序的状态,让我的规则在他们的身体内决定是否做任何有用的事情,如下所示:
%{
static int state;
%}
%%
{something} {
if (state == SOMETHING_STATE) ...
}
{something_else} {
if (state == SOMETHING_ELSE_STATE) ...
}
%%
但是,我猜测有更好的方法可以做到这一点。有吗?
答案 0 :(得分:1)
你想要开始状态 - 基本上lex有一个内置state
变量,你可以将规则注释为仅在某些状态下触发
%s state1
%s state2
%s state3
%%
<state1>{something} { // this rule matches only in state1
// change to state2
BEGIN(state2); }
<state1,state3>{something_else} { // this rule matches in state1 or state 3 }
{more_stuff} { // this rule matches in all states }
您可以在任何lex或flex book中或online flex documentation
中找到相关文档答案 1 :(得分:1)
假设你使用的是Flex而不是原来的lex,你可以使用start states
。当您解析改变解析方式的内容时,您将输入一个状态来执行该解析,并使用该状态标记相应的规则。当您解析该状态结束的任何标记时,您将再做一次:
{state_signal} { BEGIN(STATE2); }
<STATE2>{something} { handle_something(); }
<STATE2>{state3_signal} { BEGIN(STATE3); }
<STATE3>{something} {handle_something2(); }
<STATE3>{whatever} { BEGIN(START); }
答案 2 :(得分:0)
使用Flex和Yacc,您还可以构建不同的单独解析器并调整makefile,以便将它们编译为单个可执行文件。我相信你只使用Flex,但这也应该是可能的。
我现在无法确切地知道如何做到这一点,但是我已经实际上已经完成了它,所以如果你环顾四周你会找到一种方法。基本上,你必须使用不同的前缀(-P)编译每个解析器,这将生成不同名称的解析函数和不同命名的全局变量供解析器使用。