1

我已经使用 Flex/Bison 大约 6 个小时了,这是我无法解决的第一个问题:

我有以下文件...

 state state1: {
     1-3: 255
     4: 255
 }

...我使用 cat 和 | 将其传递给我的 flex/bison 程序。flex 文件包含这一行:

\bstate\b  { return STATE; }

再往下看:

.*         { fprintf(stderr, "Lexer error on line %d: \"%s\"\n", linenum, yytext); exit(-1); }

人们应该认为 \bstate\b 应该在文件中匹配,但事实并非如此。相反,我得到以下输出:

"exer error on line 1: "state state1: {

这在几个方面很奇怪。首先,Lexer 接缝中的 L 已被替换为 ",但更重要的是,状态没有匹配。为什么???

当然 \bstate\b 在 .* 之前,并且它们在正确的部分。

谢谢你的帮助,简

4

1 回答 1

4

(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; }

在上面的示例中,您放置的顺序do无关紧要double,因为double更长,但我总是觉得您应该按字母顺序放置保留字以保持整洁。但重要的是 ID 模式放在最后,因为它也匹配所有保留字。

现在考虑对以保留字开头的标识符进行词法分析时会发生什么,例如dog. 在这种情况下,DO 模式和 ID 模式都将匹配,但 ID 匹配时间较长,因此它获胜,尽管较晚。

于 2012-10-11T05:47:30.127 回答