Parsing Antlr Matlab语法词法冲突

Parsing Antlr Matlab语法词法冲突,parsing,antlr4,lexical-analysis,Parsing,Antlr4,Lexical Analysis,我一直在使用Antlr Matlab语法 我发现我需要实现“Matlab操作符”。它是运算符,用作运算符 result = input' 我尝试了一个简单的解决方案,将其添加到一元表达式中,作为选项postfix\u expression'\'' 但是,当在一行上使用多个运算符时,解析失败 这是一个大大简化的语法版本,仍然显示出确切的问题: grammar Grammar; unary_expression : IDENTIFIER | unary_expression '\''

我一直在使用Antlr Matlab语法

我发现我需要实现“Matlab操作符”。它是运算符,用作运算符

result = input'
我尝试了一个简单的解决方案,将其添加到一元表达式中,作为选项
postfix\u expression'\''

但是,当在一行上使用多个运算符时,解析失败

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

grammar Grammar;

unary_expression
   : IDENTIFIER
   | unary_expression '\''
   ;

translation_unit : unary_expression CR ;

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

IDENTIFIER : [a-zA-Z] ;

CR : [\r\n] + ;
被解析为翻译单元的测试用例:

"x''\n" //fails getNumberOfSyntaxErrors returns 1
"x'\n" //passes
故障还将消息
第1行:1外部输入''''打印到stderr,期望CR

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

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


我能对语法做些什么使它正确工作?我认为这是词法分析的一个问题,因为删除字符串或使其无法匹配
'
会使它消失。

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

x' + y';
虽然这些是字符串:

x = 'x' + ' + y';
?

也许您可以做一些类似的事情,比如在ECMAScript中,
/
可以是除法运算符或正则表达式分隔符。在这个语法中,由一个使用some来检查这个的

如果上面的内容不可能实现,我认为除了向解析器“提升”字符串的创建之外没有其他方法。这意味着删除
STRING\u LITERAL
,并引入与以下内容匹配的解析器规则:

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

// Needed to match characters inside strings
OTHER
 : .
 ;
但是,当遇到像
'hi there'
这样的字符串时,这将失败:
hi
there
之间的空格现在将被
WS
规则跳过。因此,
WS
也应该被删除(空格将被
其他
规则匹配)。但是现在(当然)所有的空间都将丢弃令牌流,您必须在所有解析器规则中考虑它们(这不是一个真正可行的解决方案)


总而言之:在这种情况下,我不认为ANTLR是合适的工具。您可以查看语法分析器生成器,其中标记化和语法分析之间没有分离。谷歌搜索“PEG”和/或“scannerless parsing”。

这是一个好问题,也是Antlr的问题之一——解析器没有一个很好的方法来影响lexer。在这里,您需要上下文将其标记为单引号或字符串文字。您可以尝试将解析器状态传递给lexer,但它可能不足以让lexer做出决定。或者,您可以尝试在解析器中将字符串文字和复杂共轭转置运算符规则强制转换为规则。我忘了提到,您可以在lexer中查看单引号以收集上下文并决定返回哪个标记。@kaby76您是否碰巧有这两种情况的示例?理想情况下,语法(例如,来自语法repo)需要并执行这两种语法中的任何一种?我没有示例,因此我使用Matlab语法并添加代码来检查语法分析器的转置状态。看见如果解析器中存在回溯(例如,由于其他语义谓词),那么这可能不起作用。在考虑将字符串文本拉到解析器中之后,您可能不喜欢这样做——您必须启动lexer模式来返回单个字符。我认为在grammars-v4中的Antlr语法本身就有类似的东西。在这两种方法中,您都必须拆分语法,并将字符串文本推送到lexer中。lexer中的谓词似乎工作得非常好,解析不再像
x'+y'
那样拖泥带水,并生成预期的解析树。考虑到我不想重做我的整个项目,这可能是最接近理想的。转置问题在SMOP中得到了解决,显然是成功的。查看其代码可能会有所帮助。你可以从这里开始:谷歌把我带到这里是因为@Bart对Matlab和PEG的评论。我有一个相关的问题。有没有一种简单的方法可以转换现有的语法,如Antlr Matlab语法或SMOP中的语法:并将它们转换为PEG形式?我并不知道@Robbw这里还有一个基于它的SMOP分支,它解决了这里的转置问题: