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'
这样的字符串时,它将失败:hi
和 there
之间的 space 现在将被 [=18 跳过=] 规则。所以 WS
也应该被删除(spaces 将被 OTHER
规则匹配)。但是现在(当然)所有 space 都会乱丢令牌流,您必须在所有解析器规则中考虑它们(这不是真正可行的解决方案)。
总而言之:在这种情况下,我认为 ANTLR 不是合适的工具。您可能会查看解析器生成器,其中标记化和解析之间没有分离。 Google 对于 "PEG" and/or "scannerless parsing".
我一直在使用来自 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'
这样的字符串时,它将失败:hi
和 there
之间的 space 现在将被 [=18 跳过=] 规则。所以 WS
也应该被删除(spaces 将被 OTHER
规则匹配)。但是现在(当然)所有 space 都会乱丢令牌流,您必须在所有解析器规则中考虑它们(这不是真正可行的解决方案)。
总而言之:在这种情况下,我认为 ANTLR 不是合适的工具。您可能会查看解析器生成器,其中标记化和解析之间没有分离。 Google 对于 "PEG" and/or "scannerless parsing".