Jan*_*Jan 1 regex bison flex-lexer
我现在已经使用 Flex/Bison 工作了大约 6 个小时,这是我无法解决的第一个问题:
我有以下文件...
state state1: {
1-3: 255
4: 255
}
Run Code Online (Sandbox Code Playgroud)
...我使用 cat 和 | 将其传递给我的 flex/bison 程序。Flex 文件包含这一行:
\bstate\b { return STATE; }
Run Code Online (Sandbox Code Playgroud)
再往下看这一点:
.* { fprintf(stderr, "Lexer error on line %d: \"%s\"\n", linenum, yytext); exit(-1); }
Run Code Online (Sandbox Code Playgroud)
人们应该认为 \bstate\b 应该在文件中匹配,但事实并非如此。相反,我得到以下输出:
"exer error on line 1: "state state1: {
Run Code Online (Sandbox Code Playgroud)
这在几个方面都很奇怪。首先,Lexer 中的 L 接缝已被“替换”,但更重要的是,状态没有匹配。为什么???
当然,\bstate\b 位于 .* 之前,并且它们位于正确的部分。
谢谢你的帮助,简
(F)Lex 不会在输入中搜索匹配项。它会尝试当前输入位置的所有模式,并选择与最多文本匹配的模式,或者如果多个模式与相同数量的文本匹配,则选择最早的模式。下一场 lex 匹配将从上一场结束的地方开始。
.*与该行的其余部分匹配。\bstate\b只能匹配七个字符。这样.*就赢了。但\bstate\b实际上并不匹配,因为这是 lex,而不是 <在此处插入您最喜欢的正则表达式语法> 并且\b意味着退格键,就像在 C 程序中一样。
字母 L 被引号覆盖的原因可能是您的输入文件是在 Windows 上创建的,并且行尾有 \r\n 。.*将匹配 包括\r,这是一个回车符。因此,当您 printf 时"%s"\n,字符串中替换 %s 的最后一个字符是回车符,这会导致光标移动到当前行的第一个位置,直到该时间点为止,其中都有一个 L。然后 " 打印在 L 的顶部,最后打印换行符,这将开始一个新行。
Lex 中没有与单词边界断言等效的东西\b,但这很少会成为问题。几乎所有编程语言的词法扫描器都必须解决保留字也将与标识符模式匹配的问题;然而,最长匹配和首次匹配规则的结合使得做到这一点很容易。简而言之,始终将保留字模式放在第一位。例如:
do { return DO; }
double { return DOUBLE; }
if { return IF; }
/* ... */
[a-z][a-z0-9]* { return ID; }
Run Code Online (Sandbox Code Playgroud)
do在上面的示例中,放置和 的顺序double并不重要,因为double它更长,但我总觉得您应该按字母顺序放置保留字以保持整洁。但重要的是 ID 模式放在最后,因为它也匹配所有保留字。
现在考虑一下当对以保留字开头的标识符进行词法分析时会发生什么,例如dog. 在这种情况下,DO 模式和 ID 模式都将匹配,但 ID 匹配更长,因此尽管较晚,但它会获胜。