我正在处理我的flex / bison lexer / parser中的棘手问题。
以下是罗马数字和任意标识符的一些弹性规则:
"I"|"II"|"III"|"IV"|"V"|"VI"|"VII"|"i"|"ii"|"iii"|"iv"|"v"|"vi"|"vii" { return NUMERAL; }
"foobar" { return FOOBAR; }
[A-Za-z0-9_]+ { return IDENTIFIER; }
现在,考虑一下这个简单的语法:
%token <numeral> NUMERAL
%token <foobar> FOOBAR
%token <identifier> IDENTIFIER
program
: numeral foobar { }
;
最后,这是一个示例输入:
IVfoobar
我打算将此作为数字IV,然后是FOOBAR。但是,如何使用标识符“Vfoobar”或只是标识符“IVfoobar”,这两个都无效,可以防止这种情况出现?
答案 0 :(得分:0)
如果你真的想在词法分析器级别处理它,那么你必须确保IDENTIFIER的规则不匹配以罗马数字开头的字符串(I,II,... vii ...)。
那是因为Lex选择了匹配最长输入的规则。
也许从IDENTIFIER的第一个字符中排除罗马数字字母会产生一组令人满意的有效标识符?
{?i:[a-z0-9_]{-}[ivxlcdm]}{?i:[a-z0-9_]}* { return IDENTIFIER; }