我使用的词法分析器需要能够识别命名变量和关键字之间的区别。
详细说明,在我的.l文件中,我有一些定义,如
"QUIT" {return QUIT;}
"AND" {return AND;}
"XOR" {return XOR;}
我也有一个名称的定义(对于一个变量)
[a-zA-Z][a-zA-Z0-9]* {memcpy(yylval.name, yytext, strlen(yytext) + 1); return NAME;}
我的问题是我的关键字,如QUIT,AND,XOR都满足NAME的规则,让我产生歧义问题。
我该如何解决这个问题?
答案 0 :(得分:2)
将关键字放在第一位。
Flex生成的扫描仪总是选择最长的匹配;如果可以应用多个模式,则选择第一个模式。所以如果你有:
QUIT {return QUIT;}
AND {return AND;}
XOR {return XOR;}
[a-zA-Z][a-zA-Z0-9]* { memcpy(yylval.name, yytext, yyleng + 1); return NAME; }
[[:space:]]+ /* Ignore */
,您的输入是:
QUITAND QUIT AND
然后您的扫描仪将返回三个令牌:NAME
,QUIT
,AND
。如果您先放置NAME
模式,那么您将获得三个NAME
个令牌。 (不需要在flex模式中引用字母数字字符。需要引用的是正则表达式运算符。)
memcpy
不是个好主意。我修改了它以避免对strlen
的冗余调用,这实际上是最不重要的问题。我假设你将它与yylval.name
的声明组合为一个固定长度的字符数组。如果是这样,您应该验证NAME是否太长,以至于不适合所提供的空间。但它仍然是一个坏主意,因为野牛生成的解析器假设堆积值不是太大;当它使生成的代码更方便时,它不会试图避免复制它们。