我有一种语言我正在制作一个包含函数调用的解析器。保留了一些函数名称,我想在我的语法中以不同的方式处理它们。在EBNF中它看起来像
FunctionCall ::= FunctionName '(' ')'
SpecialFunctionCall :: SpecialName '(' ')'
FunctionName ::= VariableName - SpecialFunctionName
SpecialFunctionName ::= "special_function_a" | "special_function_b"
我的问题是将例外运算符从 EBNF 转换为flex。
FunctionName {Letter}{LetterOrDigit}
是一组超强的 SpecialFunctionName ,这是一个硬编码的字符串
SpecialFunctionName "special_function_a" | "special_function_b"
因此我收到野牛的警告说 SpecialFunction 永远不会匹配。我应该合并标记并比较解析器中的字符串,还是有建议的方法来解决flex中的这种歧义?
答案 0 :(得分:3)
处理此问题的常用方法是让词法分析器识别特殊名称并为特殊名称返回正确的标记类型(SpecialName),并为其他标记返回常规标识符标记(显然是FunctionName)。
然而,它通常需要词法分析器的一定程度的预见性来说一个特定的(非保留的,非特殊的)单词是一个函数名而不是一个简单的标识符(也可能是一个简单变量 - 除非你沿着Perl使用符号来识别函数变量的路线。
答案 1 :(得分:0)
只要您将SpecialFunction
规则FIRST放在词法分析器文件中:
{SpecialFunctionName} { return SpecialName; }
{FunctionName} { return FunctionName; }
任何匹配这两种模式的标识符都会触发第一条规则,从而返回SpecialName
而不是FunctionName
。