4

如何自定义 flex 的默认操作。我发现了类似 <*> 的东西,但是当我运行它时,它显示“flex 扫描仪卡住了”?还有 . rule 只添加一个规则,因此它也不起作用。我想要的是

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

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

是否可以将匹配最长的行为更改为首先匹配?如果是这样,我会做这样的事情

default               (.|\n)*

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

编辑

我在手册中找到了 {-} 运算符,但是直接来自手册的这个例子给了我“无法识别的规则”:

[ac]{-}[bz]

4

3 回答 3

8

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

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

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

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

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

无论如何,通常在丢弃坏字符时,您希望针对这种情况发出错误消息,例如“在第 42 行第 3 列跳过无效字符 '~`”。

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

例如,一个仅包含以下规则的 lex 规范:

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

将实现相当于

 sed -e 's/foo/bar/g'
于 2012-04-22T19:30:42.717 回答
1

为什么要加“。” 不做的伎俩?如果没有匹配的金额,您将无法执行操作。如果没有匹配,flex 不会做任何事情,所以要添加一个“默认”规则,只需让它匹配一些东西。

于 2012-04-22T12:42:27.663 回答
1

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

于 2012-04-23T05:49:03.420 回答