c - Flex 默认规则

标签 c tokenize lex flex-lexer

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

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

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

是否可以将匹配最长的行为更改为首先匹配?如果是这样,我会做这样的事情
default               (.|\n)*

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

编辑

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

[a-c]{-}[b-z]

最佳答案

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

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

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

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

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

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

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

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

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

将实现相当于
 sed -e 's/foo/bar/g'

关于c - Flex 默认规则,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10267307/

相关文章:

c - 将 "*()"作为参数传递给 bash 中的程序

c++ - 我可以从 MSVC 编译的 exe 文件中删除 *.exe.manifest 文件吗?

c++ - 有没有实现流式分词器的 C++ 库?

c++ - (F)莱克斯 : get text not matched by rules/get default output

c - lex 程序错误

c++ - 柔性/莱克斯 : Regular Expression matches double characters

c - getdate 和 strptime 什么时候不包含在 time.h 中?

c - C 中 void * 转为 char 或 int

java - 可选择使用 String.split(),在分隔符的最后一次出现处拆分字符串

python-3.x - 对中英文文本进行分词不正确地将英文单词拆分为字母