Flex默认规则

时间:2012-04-22 10:50:26

标签: c tokenize lex flex-lexer

如何自定义flex的默认操作。我找到了类似< *>的内容但是,当我运行它时,它说“弹性扫描仪卡住了”?还有。规则只添加一个规则,因此它也不起作用。我想要的是

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

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

是否可以更改匹配最长的行为以匹配第一个?如果是这样我会做这样的事情

default               (.|\n)*

但是因为这几乎总是会给出更长的匹配,所以它会隐藏评论规则。

修改

我在手册中找到了{ - }操作符,但是这个直接来自手册的例子给了我“未经认可的规则”:

[A-C] { - } [B-Z]

3 个答案:

答案 0 :(得分:5)

弹性默认规则匹配单个字符并将其打印在标准输出上。如果您不想要该操作,请编写一个与单个字符匹配的显式规则,并执行其他操作。

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

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

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

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

无论如何,通常在丢弃一个坏字符时,你想为这种情况发出一条错误信息,比如“在第42行,第3列中跳过无效字符'〜”。

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

例如,一个lex规范只包含规则:

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

将实现等效的

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

答案 1 :(得分:1)

没有这样的事情。这听起来像是XY problem - 你已经问我们如何自定义flex的默认动作(Y),但是你真的希望它能够实现其他目的,X。

什么是X?

回复:你的问题,为什么要添加“。”不行吗?在没有匹配金额的情况下,您无法执行操作,因此提出的问题可能毫无意义。如果没有匹配,flex将不会执行任何操作,因此要添加“默认”规则,只需使其匹配即可。

答案 2 :(得分:0)

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