2012-04-22 110 views
0

如何自定义flex的默认操作。我发现像< *>,但是当我运行它说“flex scanner jammed”?也是。规则只会添加一条规则,所以它也不起作用。我想要的是Flex默认规则

comment    "/*"[^"*/"]*"*/" 

%% 
{comment}    return 1; 
{default}    return 0; 
<<EOF>>    return -1; 

是否有可能改变匹配最长的行为首先匹配?如果是的话,我会做这样的事情

default    (.|\n)* 

但因为这几乎总是给人一种更匹配它会隐藏注释规则。

编辑

我发现{ - }操作手册中,但是这个例子中,直接从手动给了我 “unrecogized规则”:

[交流] { - } [BZ]

回答

4

flex默认规则匹配单个字符并将其打印在标准输出上。如果你不想要这样的行为,写一个明确的规则来匹配单个字符并做其他事情。

模式(.|\n)*将整个输入文件作为单个令牌进行匹配,因此这是一个非常糟糕的主意。您认为默认应该是长时间匹配,但实际上您希望尽可能短(但不是空的)。

默认规则的用途是在输入语言中任何令牌不匹配时执行某些操作。当lex用于标记语言时,这种情况几乎总是错误的,因为这意味着输入以不是该语言的任何有效标记开始的字符开始。

因此,“捕捉任何字符”规则被编码为错误恢复的形式。这个想法是放弃坏字符(只有一个),然后尝试从该字符后面的字符开始标记。这只是一个猜测,但这是一个很好的猜测,因为它是基于已知的:即输入中有一个坏字符。

恢复规则可能是错误的。例如,假设语言的标记不以@开头,程序员想写字符串文字"@abc"。只是,她忘记了开头"并写了@abc"。正确的解决方法是插入缺失的",而不是放弃@。但是这需要在词法分析器中有一套更聪明的规则。

无论如何,通常当丢弃一个不好的字符时,您希望为这种情况发出一条错误消息,如“在第42行第3列中跳过无效字符〜”。

将lex用于文本过滤时,将不匹配字符复制到标准输出的默认规则/操作很有用。然后,默认规则带来了正则表达式搜索的语义(与正则表达式匹配相反):想法是在输入中搜索词法分析器的令牌识别状态机的匹配,同时打印该搜索所跳过的所有材料。

因此,举例来说,仅包含规则的法规范:

"foo" { printf("bar"); } 

将实施

sed -e 's/foo/bar/g' 
1

没有这样的事情。这听起来像一个XY problem - 你问我们如何定制flex的默认动作(Y),但你真的想要它实现一些其他的目标,X.

什么是X?

Re:你的问题,为什么要加“。”不要做诡计?如果没有匹配的数量,你不能执行一个动作,所以所问的问题可能没有意义。如果没有匹配,flex将不会执行任何操作,因此要添加“默认”规则,只需使其匹配。

0

我解决了这个问题改为手动,如果试图规则的补充匹配相当于。这很好,因为在这种情况下涉及的匹配模式非常简单。