我在編譯器構建過程中,我目前的任務是爲我們正在實現的語言編寫詞法分析器。我無法弄清楚如何滿足詞法分析器必須識別串聯令牌的要求。也就是說,令牌不會被空格分開。例如:字符串39if
應該被識別爲數字39
和關鍵字if
。同時,詞法分析器遇到無效輸入時也必須使用exit(1)
。如何讓lex/flex識別不被空格分隔的令牌?
代碼的簡化版本我有:
%{
#include <stdio.h>
%}
%option main warn debug
%%
if |
then |
else printf("keyword: %s\n", yytext);
[[:digit:]]+ printf("number: %s\n", yytext);
[[:alpha:]][[:alnum:]]* printf("identifier: %s\n", yytext);
[[:space:]]+ // skip whitespace
[[:^space:]]+ { printf("ERROR: %s\n", yytext); exit(1); }
%%
當我運行這個(或我的完整版),並通過它的輸入39if
,錯誤匹配規則時,輸出爲ERROR: 39if
,當我想它是:
number: 39
keyword: if
(即相同的,如果我進入39 if
作爲輸入。)
Going by the manual,我有一個預感,原因是錯誤規則匹配比數字和關鍵字規則更長的可能輸入,flex會更喜歡它。這就是說,我不知道如何解決這種情況。編寫一個明確的正則表達式似乎是不可行的,它將拒絕所有非錯誤輸入,並且我不知道爲了處理詞法分析器錯誤還需要編寫一個「全部抓取」規則。
更新:我想我可以只作包羅萬象的規則是. { exit(1); }
,但我想獲得一些更好的調試輸出比「我糊塗了第1行」。
a)您是否運行過簡化版本? b)它做了什麼是錯誤的? –
@IraBaxter對不起,似乎我忘了在最後一段中的猜測中迷失了我的測試用例。答案是** a)**是;和** b)**報告詞法分析器錯誤,而不是兩個標記。 (我也將它們添加到問題中。) – millimoose
啊。好的,是的,你的「^空間」規則會吃掉任何非空間序列,從而消耗「39if」。祕密:避免正則表達式重疊的規則,除非較長的規則首先安全。在你的情況下,我會用(我不是一個lex-pert)替換:^ space:那是「不是數字,不是字母,也不是空格」。 ... –