Flex 匹配错误的规则
Flex matching wrong rule
我正在为 mini-L 语言编写一个编译器。我几乎完成了扫描部分。这是您基本上可以在输入中找到标记的地方。我的问题是,当我输入“函数”时,它会将其作为标识符进行匹配。我真的说不出哪里不对。
ident [a-zA-Z][a-zA-Z0-9_]+[^_]
%{
#include <stdio.h>
#include <stdlib.h>
int col = 0;
int row = 0;
%}
%%
"function" {printf("FUNCTION\n"); col += yyleng;}
{ident} {printf("IDENT %s\n", yytext); col += yyleng;}
. {printf("Error at line %d, column %d: unrecognized symbol \"%s\"\n", row, col, yytext);}
%%
int main(int argc, char** argv){
if(argc > 1){
FILE *fp = fopen(argv[1], "r");
if(fp){
yyin = fp;
}
}
printf("Give me the input:\n");
yylex();
}
我尝试重新排列规则,但没有用,而且这似乎也不是问题所在。我认为这是我的正则表达式的问题。非常感谢任何帮助。
这是您的 ident
模式:[a-zA-Z][a-zA-Z0-9_]+[^_]
。让我们分解一下:
[a-zA-Z]
一个字母。
[a-zA-Z0-9_]+
一个或多个 (+
) 字母、数字或 _
[^_]
_
以外的任何值。任何事物。比如一个space.
一个简单的观察是模式不能匹配少于三个字符。另一方面,最后一个几乎可以是任何东西。可以是一封信。但它也可以是逗号,或 space,甚至是换行符。只是不是下划线。
因此不会匹配通常被认为是有效标识符的 x
。但它将匹配 function
。 (也就是说,单词 function
后跟一个 space。)因为它比 function
长,标识符模式将获胜,除非你碰巧写了 function_
.
所以这可能不是您想要的。
请注意,如果要避免标识符以下划线结尾,则必须处理两个问题。
明显的模式[[:alpha:]][[:alnum:]_]*[[:alnum:]]
不能匹配单个字母。所以你需要 [[:alpha:]]([[:alnum:]_]*[[:alnum:]])?
.
如果您的标识符模式与尾随下划线不匹配,则下划线将保留在下一个标记中。也许你对此没有意见。但最好匹配下划线并发出错误消息。或者重新考虑限制。
注意:模式语法是 documented in the Flex manual,包括我上面使用的内置字符集。
我正在为 mini-L 语言编写一个编译器。我几乎完成了扫描部分。这是您基本上可以在输入中找到标记的地方。我的问题是,当我输入“函数”时,它会将其作为标识符进行匹配。我真的说不出哪里不对。
ident [a-zA-Z][a-zA-Z0-9_]+[^_]
%{
#include <stdio.h>
#include <stdlib.h>
int col = 0;
int row = 0;
%}
%%
"function" {printf("FUNCTION\n"); col += yyleng;}
{ident} {printf("IDENT %s\n", yytext); col += yyleng;}
. {printf("Error at line %d, column %d: unrecognized symbol \"%s\"\n", row, col, yytext);}
%%
int main(int argc, char** argv){
if(argc > 1){
FILE *fp = fopen(argv[1], "r");
if(fp){
yyin = fp;
}
}
printf("Give me the input:\n");
yylex();
}
我尝试重新排列规则,但没有用,而且这似乎也不是问题所在。我认为这是我的正则表达式的问题。非常感谢任何帮助。
这是您的 ident
模式:[a-zA-Z][a-zA-Z0-9_]+[^_]
。让我们分解一下:
[a-zA-Z]
一个字母。[a-zA-Z0-9_]+
一个或多个 (+
) 字母、数字或_
[^_]
_
以外的任何值。任何事物。比如一个space.
一个简单的观察是模式不能匹配少于三个字符。另一方面,最后一个几乎可以是任何东西。可以是一封信。但它也可以是逗号,或 space,甚至是换行符。只是不是下划线。
因此不会匹配通常被认为是有效标识符的 x
。但它将匹配 function
。 (也就是说,单词 function
后跟一个 space。)因为它比 function
长,标识符模式将获胜,除非你碰巧写了 function_
.
所以这可能不是您想要的。
请注意,如果要避免标识符以下划线结尾,则必须处理两个问题。
明显的模式
[[:alpha:]][[:alnum:]_]*[[:alnum:]]
不能匹配单个字母。所以你需要[[:alpha:]]([[:alnum:]_]*[[:alnum:]])?
.如果您的标识符模式与尾随下划线不匹配,则下划线将保留在下一个标记中。也许你对此没有意见。但最好匹配下划线并发出错误消息。或者重新考虑限制。
注意:模式语法是 documented in the Flex manual,包括我上面使用的内置字符集。