问题描述
假设一种语言将两个数学Unicode字母数字符号的邻接定义为一个运算符。比方说,𝑥𝑦+1表示𝑥%adj𝑦+1,其中%adj表示运算符邻接定义的任何内容,在本例中为乘法。我在想,现有的任何词汇分析工具都能处理这个问题吗?推荐答案
不可见运算符无法通过词法分析识别,原因应该或多或少是显而易见的。您只能通过分析语法上下文来推断是否存在不可见运算符,这是解析器的角色。
当然,大多数词法分析工具允许为每个识别的标记执行任意代码,因此没有什么可以阻止您在词法扫描器中构建状态机,甚至是完整的解析器。这很少是好的设计。如果你的语言是明确的,那么在你的语法中处理邻接是没有问题的。但必须谨慎行事。例如,您很少希望x-4
被解析为x
和-4
的乘法,而是一种朴素的语法,例如
expr -> term | expr '-' term
term -> factor | term factor | term '*' factor
factor -> ID | NUMBER | '(' expr ')' | '-' factor
将包括这种模棱两可。要解决此问题,您需要禁止使用以一元运算符开头的第二个操作数的邻接乘积:
expr -> term | expr '-' term
term -> factor | term item | term '*' factor
factor -> item | '-' factor
item -> ID | NUMBER | '(' expr ')'
注意term -> term '*' factor
和term -> term base
之间的区别,term -> term '*' factor
允许x * - y
,term -> term base
不允许x - y
(expr -> expr '-' term
将x - y
识别为减法)。
有关允许将邻接作为运算符的上下文无关文法的示例,例如,请参阅AWK和Haskell,其中邻接表示字符串连接,Haskell表示函数应用。
由于这个问题不时被提出,因此已经有一些相关的答案。以下是几个例子:
Parsing a sequence of expressions using yacc。隐形功能应用运算符。使用yacc/bison;包括显式和基于优先级的解决方案
yacc - Precedence of a rule with no operator?不可见的字符串串联运算符。使用PLY(Python解析器生成器)
/li>Concatenation shift-reduce conflict另一个不可见的串联运算符。使用JavaCUP。
Parsing a sequence of expressions using yacc不可见函数应用运算符。使用fsyacc(F#解析器生成器)
Using yacc precedence for rules with no terminals, only non-terminals。在普通数学表达式中的邻接关系。将yacc/bison与优先规则一起使用。
bison/yacc - limits of precedence settings。类Haskell函数应用程序邻接。将yacc/bison与优先规则一起使用。
这篇关于作为运算符的邻接--任何lexer都可以处理它吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!