Flex处理二义性模式的方法
大多数flex程序都具有二义性,相同的输入可能被多种不同的模式匹配。
flex使用以下规则来解决这个问题:
词法分析器匹配输入时匹配尽可能多的字符串。
如果两个模式都可以匹配的话,匹配在程序中更早出的模式。
也就是说:flex生成的词法分析器总是选择更长的的匹配,
而且如果两个模式都匹配的话,flex生成的词法分析器会选择在程序里面首先出现的模式。
Flex处理二义性模式的实例
以C语言编译器所需的一个简单的词法分析器为例,[A-Za-z_][A-Za-z0-9_]*
为匹配变量名的正则表达式
,"if"
是为匹配C语言的保留字(关键字)if的正则表达式
。
Flex处理二义性模式实例程序
匹配关键字的规则放在匹配变量名的规则前面
/*lexer.l*/
%{
#include <stdio.h>
%}
%%
"if" {printf("IF\n");}
[A-Za-z_][A-Za-z0-9_]* {printf("Varname\n");}
. {printf("Error Characters !\n");}
%%
匹配关键字的规则放在匹配变量名的规则后面
/*lexer.l*/
%{
#include <stdio.h>
%}
%%
[A-Za-z_][A-Za-z0-9_]* {printf("Varname\n");}
"if" {printf("IF\n");}
. {printf("Error Characters !\n");}
%%
生成词法分析器并测试
flex lexer.l
gcc lex.yy.c -o lexer.out -lfl
./lexer.out
测试样例
ifif
if
Flex处理二义性模式实例测试结果
匹配关键字的规则放在匹配变量名的规则前面
测试结果
分析
- 由于
flex生成的词法分析器总是选择更长的的匹配
,ifif会被[A-Za-z_][A-Za-z0-9_]*
规则匹配。 - if可以被
"if"
规则匹配,也可以被[A-Za-z_][A-Za-z0-9_]*
规则匹配。两个规则可以匹配的字符串长度一致
,flex生成的词法分析器会选择在程序里面首先出现的模式
,即"if"
规则。
匹配关键字的规则放在匹配变量名的规则后面
测试结果
分析
- 由于
flex生成的词法分析器总是选择更长的的匹配
,ifif会被[A-Za-z_][A-Za-z0-9_]*
规则匹配。 - if可以可以被
[A-Za-z_][A-Za-z0-9_]*
规则匹配,也被"if"
规则匹配。两个规则可以匹配的字符串长度一致
,flex生成的词法分析器会选择在程序里面首先出现的模式
,即[A-Za-z_][A-Za-z0-9_]*
规则。