2010-11-12 80 views
0

我有一种语言,我正在为其中包含函数调用的解析器。一些函数名称是保留的,我想在我的语法中以不同的方式处理它们。在EBNF它看起来像在flex中分隔保留的标识符

FunctionCall ::= FunctionName '(' ')' 
SpecialFunctionCall :: SpecialName '(' ')' 

FunctionName ::= VariableName - SpecialFunctionName 

SpecialFunctionName ::= "special_function_a" | "special_function_b" 

我的问题是在翻译从EBNF例外操作弯曲。

FunctionName {Letter}{LetterOrDigit} 

是一个超集SpecialFunctionName,这是一个硬编码字符串

SpecialFunctionName "special_function_a" | "special_function_b" 

因此我从野牛警告说,SpecialFunction将永远不会被匹配的。我应该合并令牌并比较解析器中的字符串,还是有建议的方法来解决flex中的这种模糊问题?

回答

3

处理此问题的正常方法是让词法分析器识别特殊名称,并返回特殊名称的正确标记类型(SpecialName)和其他标记的常规标识符标记(显然为FunctionName)。

但是,它通常需要词法分析器的不合理程度的预见,说特定的(非保留的,非特殊的)词是函数名称而不是简单的标识符(它也可以是一个简单的变量 - 除非你使用了sigils来标识函数中的变量的Perl路径)。

+0

“它通常需要不适当程度的预见”,你能否详细说明一下? – Akusete 2010-11-14 23:23:17

+1

@Akusete:在许多语法中,用于变量的标识符和用于函数的标识符之间没有词法上的区别(Perl是它的标记的例外)。因此,为了让词法分析器确定一个特定的名称是一个变量或函数,它必须能够访问一些非词汇信息(符号表信息)。如果所有的变量和函数都必须在使用之前声明/定义,那么必要的信息可能是可用的 - 而且您已经避免了对预测的需要。像C这样的语言在这方面传统上有点草率。 [...继续...] – 2010-11-14 23:31:24

+0

@Akusete:替代方案是词法分析器向前看一些令牌,并根据上下文确定它正在查看的名称必须是函数名称而不是标识符 - 但通常情况下努力避免将这种语法知识带入词法分析器。 – 2010-11-14 23:32:42

0

只要你把SpecialFunction规则首先在词法分析器文件:

{SpecialFunctionName} { return SpecialName; } 
{FunctionName}   { return FunctionName; } 

同时匹配模式将触发的第一个规则,因此返回SpecialName而不是FunctionName任何IDENTIFER。

相关问题