Antlr Matlab文法词法冲突

Antlr Matlab grammar lexing conflict

我一直在使用来自 Antlr grammars

的 Antlr Matlab 语法

我发现我需要实施 ' Matlab 运算符。它是 complex conjugate transpose 运算符,用作

result = input'

我尝试了一种直接的解决方案,将其作为选项添加到 unary_expression postfix_expression '\''

但是,当在一行中使用多个这些运算符时,解析失败。

这是语法的显着简化版本,仍然显示出确切的问题:

grammar Grammar;

unary_expression
   : IDENTIFIER
   | unary_expression '\''
   ;

translation_unit : unary_expression CR ;

STRING_LITERAL : '\'' [a-z]* '\'' ;

IDENTIFIER : [a-zA-Z] ;

CR : [\r\n] + ;

测试用例,被解析为translation_unit:

"x''\n" //fails getNumberOfSyntaxErrors returns 1
"x'\n" //passes

失败还会将消息 line 1:1 extraneous input '''' expecting CR 打印到标准错误。

如果我删除 STRING_LITERAL,或将 * 更改为 +,故障就会消失。当然,这都不是一个合适的解决方案,因为删除它完全脱离了 table,并且强制非空字符串不太正确,尽管我可能能够接受它。此外,当输入类似于 x' + y' 而不是两次使用运算符时,强制非空字符串对实际用例没有任何帮助。

出于某种原因,从语法中删除 CR 并从测试中删除 \n 也使解析 运行 没有问题,但又不是一个可用的解决方案。

我可以对语法做些什么来使其正常工作?我假设这是词法分析的问题,因为删除 STRING_LITERAL 或使其无法匹配 '' 会使它消失。

我认为词法分析器永远无法感知上下文,但我对 Matlab 的了解不够深,无法确定。您如何在标记化过程中检查这些单引号是运算符:

x' + y';

虽然这些是字符串:

x = 'x' + ' + y';

?

也许你可以做一些类似于在 ECMAScript 中 / 可以是除法运算符或正则表达式定界符的事情。在这个由 predicate in the lexer that uses some target code 处理的语法中检查这个。

如果像上面那样的事情是不可能的,我认为除了 "promote" 为解析器创建字符串之外别无他法。这意味着删除 STRING_LITERAL 并引入一个匹配如下内容的解析器规则:

string_literal
 : QUOTE ~(QUOTE | CR)* QUOTE
 ;

// Needed to match characters inside strings
OTHER
 : .
 ;

但是,当遇到像 'hi there' 这样的字符串时,它将失败:hithere 之间的 space 现在将被 [=18 跳过=] 规则。所以 WS 也应该被删除(spaces 将被 OTHER 规则匹配)。但是现在(当然)所有 space 都会乱丢令牌流,您必须在所有解析器规则中考虑它们(这不是真正可行的解决方案)。

总而言之:在这种情况下,我认为 ANTLR 不是合适的工具。您可能会查看解析器生成器,其中标记化和解析之间没有分离。 Google 对于 "PEG" and/or "scannerless parsing".