我在L文件中在flex中编写定义时遇到问题。出于某种原因,flex无法识别我给正则表达式的名称,例如
LETTER [A-Za-z]
DIGIT[0-9]
SPACE (" ") +
ID {LETTER} ({LETTER} | {DIGIT})* (("."| "#"|"$" | "_")? ({LETTER} | {DIGIT})+)?
NUM ({DIGIT} + | {DIGIT}+ "." {DIGIT} *)(((E |e) (+|-)? {DIGIT} +))?
%%
{LETTER} {printf("letter");}
%%
但除非我这样写,否则它不会执行规则:
[A-Za-z] {printf("letter");}
任何人都可以告诉我为什么会这样吗?谢谢
答案 0 :(得分:0)
此flex程序中有几个错误,但它们都不是您要问的问题。也许你对你所看到的错误的原因和症状感到困惑。
我可以确认您所询问的内容适用于所有版本的flex:
LETTER [A-Za-z]
%%
{LETTER} {printf("letter");}
%%
错误在其他正则表达式中,在您的示例中未引用。如果你确实引用它们,那么它确实会产生你可能无意中对字母模式做出贡献的错误。让我们通过对其他模式采取行动来检查为什么会这样:
LETTER [A-Za-z]
DIGIT[0-9]
SPACE (" ") +
ID {LETTER} ({LETTER} | {DIGIT})* (("."| "#"|"$" | "_")? ({LETTER} | {DIGIT})+)?
NUM ({DIGIT} + | {DIGIT}+ "." {DIGIT} *)(((E |e) (+|-)? {DIGIT} +))?
%%
{LETTER} {printf("letter");}
{SPACE} {printf("space");}
{ID} {printf("id");}
{NUM} {printf("num");}
%%
我们从flex获得此回复:
SO.l:8: unrecognized rule
SO.l:9: unrecognized rule
SO.l:10: unrecognized rule
这是因为正则表达式中存在错误。你犯了把空白放在里面的错误。在大多数代码中,空格被忽略,但初学者在flex(以及使用正则表达式的其他工具)中常见的错误是增加间距以提高可读性。这不是一个好主意,因为它通常会导致指定空格应该出现在模式中!因此,假设您的规范需要{space}
模式中的两个空格,并且该空格出现在{ID}
和{NUM}
中。
删除我们最终的空格:
LETTER [A-Za-z]
DIGIT [0-9]
SPACE (" ")+
ID {LETTER}({LETTER}|{DIGIT})*(("."|"#"|"$"|"_")?({LETTER}|{DIGIT})+)?
NUM ({DIGIT}+|{DIGIT}+"."{DIGIT}*)(((E|e)(+|-)?{DIGIT}+))?
%%
{LETTER} {printf("letter");}
{SPACE} {printf("space");}
{ID} {printf("id");}
{NUM} {printf("num");}
%%
这解决了大多数错误,再留下一个:
SO.l:11: unrecognized rule
这是由NUM模式中的错误引起的。模式中使用了+
符号来显示符号在数字中的使用位置。但是,加号在正则表达式中用于表示重复一个或多个。 +
需要加上引号:
LETTER [A-Za-z]
DIGIT [0-9]
SPACE (" ")+
ID {LETTER}({LETTER}|{DIGIT})*(("."|"#"|"$"|"_")?({LETTER}|{DIGIT})+)?
NUM ({DIGIT}+|{DIGIT}+"."{DIGIT}*)(((E|e)("+"|"-")?{DIGIT}+))?
%%
{LETTER} {printf("letter");}
{SPACE} {printf("space");}
{ID} {printf("id");}
{NUM} {printf("num");}
%%
此代码现在可以构建,甚至可以使用gcc进行编译。我们可以在一些例子上运行代码:
a123
id
123
num
123.456
num
123.456e-78
num
space
a
letter
aa
id
您还应该注意,拥有{LETTER}
规则和{ID}
规则可能会出现问题。单个字母与LETTER
匹配,但多个字符与“ID”匹配。这是因为flex尝试实现最长匹配。如果您尝试更改匹配顺序以优先使用ID,则会因flex诊断出这种情况而出现错误:
LETTER [A-Za-z]
DIGIT [0-9]
SPACE (" ")+
ID {LETTER}({LETTER}|{DIGIT})*(("."|"#"|"$"|"_")?({LETTER}|{DIGIT})+)?
NUM ({DIGIT}+|{DIGIT}+"."{DIGIT}*)(((E|e)("+"|"-")?{DIGIT}+))?
%%
{SPACE} {printf("space");}
{ID} {printf("id");}
{NUM} {printf("num");}
{LETTER} {printf("letter");}
%%
给出了:
SO.l:10: warning, rule cannot be matched
这是初学者的另一个常见错误来源,有一个匹配多个模式的字符串。