【问题标题】:Include commentary to the matlab grammar using antlr4使用 antlr4 包括对 matlab 语法的注释
【发布时间】:2021-12-11 17:38:28
【问题描述】:

谁能帮我解决这两个问题?

第一个问题几乎解决了我的问题 regular expression for multiline commentary in matlab ,但我不知道我应该如何使用 ^.*%\{(?:\R(?!.*%\{).*)*\R\h*%\}$ 或者如果我想在语法中使用 antlr4。我一直在使用this源的matlab语法。

第二个与matlab中的另一种类型的注释相关,即a = 3 % type any ascii I want...。在这种情况下有效,当我以这种形式插入规则上下文 unary_expression 的标签替代项时:

unary_expression
: postfix_expression
| unary_operator postfix_expression
| postfix_expression COMMENT
;

其中COMMENT: '%' [ a-zA-Z0-9]*;,但是当我使用[\x00-\x7F] 而不是[ a-zA-Z0-9]*(我发现here)时解析出错,请参见下面的示例:

INPUT FOR PARSER: a = 3 %  $£ K JFKL£J"!"OIJ+2432 3K3KJ£$K M£"Kdsa
ANTLR OUTPUT : Exception in thread "main" java.lang.RuntimeException: set is empty
               at org.antlr.v4.runtime.misc.IntervalSet.getMaxElement(IntervalSet.java:421)
               at org.antlr.v4.runtime.atn.ATNSerializer.serialize(ATNSerializer.java:169)
               at org.antlr.v4.runtime.atn.ATNSerializer.getSerialized(ATNSerializer.java:601)
               at org.antlr.v4.Tool.generateInterpreterData(Tool.java:745)
               at org.antlr.v4.Tool.processNonCombinedGrammar(Tool.java:400)
               at org.antlr.v4.Tool.process(Tool.java:361)
               at org.antlr.v4.Tool.processGrammarsOnCommandLine(Tool.java:328)
               at org.antlr.v4.Tool.main(Tool.java:172)
               line 1:9 token recognition error at: '$'
               line 1:20 token recognition error at: '"'
               line 1:21 token recognition error at: '!'
               line 1:22 token recognition error at: '"'
               line 1:38 token recognition error at: '$'
               line 1:43 token recognition error at: '"'
               line 1:10 missing {',', ';', CR} at 'L'
               line 1:32 missing {',', ';', CR} at '3'

谁能告诉我我做错了什么?这个问题的最佳实践是什么? (我不完全是正则表达式的人......)

【问题讨论】:

    标签: matlab comments antlr4 grammar


    【解决方案1】:

    我们先来个简单的。

    这看起来(对我来说)就像一个典型的“评论所有内容到行尾”的评论。

    假设我是正确的,那么最好不要考虑可能包含的所有有效字符是什么,而是考虑不使用什么。

    试试:COMMENT: '%' ~[\r\n]* '\r'? '\n';

    (我注意到您的规则中没有包含任何内容以在行尾终止它,所以我添加了它)。

    这基本上是说:一旦我看到 % 消耗所有不是 \r 或 `nand stop when you see an option\rfollowed by a required\n' 的东西。

    通常,cmets 几乎可以出现在语法结构中的任何位置,因此将它们“推到一边”而不是在语法中允许它们的任何地方注入它们是非常有用的。

    所以,一个简短的语法:

    grammar test
        ;
    
    test: ID EQ INT;
    
    EQ:      '=';
    INT:     [0-9]+;
    COMMENT: '%' ~[\r\n]* '\r'? '\n' -> channel(HIDDEN);
    ID:      [a-zA-Z]+;
    WS:      [ \t\r\n]+ -> skip;
    

    您会注意到我从test 规则中删除了COMMENT 元素。

    测试文件:

    a = 3 %  $£ K JFKL£J"!"OIJ+2432 3K3KJ£$K M£"Kdsa
    

    (一定要包含\n

    ➜ grun test test -tree -tokens < test.txt
    [@0,0:0='a',<ID>,1:0]
    [@1,2:2='=',<'='>,1:2]
    [@2,4:4='3',<INT>,1:4]
    [@3,6:48='%  $£ K JFKL£J"!"OIJ+2432 3K3KJ£$K M£"Kdsa\n',<COMMENT>,channel=1,1:6]
    [@4,49:48='<EOF>',<EOF>,2:0]
    (test a = 3)
    

    你仍然会得到一个COMMENT 令牌,它只是在匹配解析器规则时被忽略。

    现在是多行 cmets:

    ANTLR 对 Lexer 规则使用了一种“类似正则表达式”的语法,但是,不要被愚弄,它不是(它实际上更强大,因为它可以配对嵌套括号等)

    通过快速阅读,MatLab 多行标记以 %{ 开头并使用所有内容,直到 %}. This is very similar to the prior rule, it just doesn't care about \ror\n`),所以:

    MLCOMMENT: '%{' .*? '%}'    -> channel(HIDDEN);
    

    包含在语法中:

    grammar test
        ;
    
    test: ID EQ INT;
    
    EQ:        '=';
    INT:       [0-9]+;
    COMMENT:   '%' ~[\r\n]* '\r'? '\n' -> channel(HIDDEN);
    MLCOMMENT: '%{' .*? '%}'           -> channel(HIDDEN);
    ID:        [a-zA-Z]+;
    WS:        [ \t\r\n]+ -> skip;
    

    输入文件:

    a = 3 %  $£ K JFKL£J"!"OIJ+2432 3K3KJ£$K M£"Kdsa
    
    %{
        A whole bunch of stuff
        on several
        lines
    %}
    
    ➜ grun test test -tree -tokens < test.txt
    [@0,0:0='a',<ID>,1:0]
    [@1,2:2='=',<'='>,1:2]
    [@2,4:4='3',<INT>,1:4]
    [@3,6:48='%  $£ K JFKL£J"!"OIJ+2432 3K3KJ£$K M£"Kdsa\n',<COMMENT>,channel=1,1:6]
    [@4,50:106='%{\n    A whole bunch of stuff\n    on several\n    lines\n%}',<MLCOMMENT>,channel=1,3:0]
    [@5,108:107='<EOF>',<EOF>,8:0]
    (test a = 3)
    

    【讨论】:

    • 迈克,非常感谢。这对我来说非常有效,而且我不知道在匹配解析器规则时可能会得到被忽略的令牌。简直完美!
    • 一段时间后发现使用 {comment: '%' ~[\r\n]*} 没有终止行尾更适合 matlab 语法。当我尝试输入 a = 1 % hey "newline" b = 2 时,如果 Mike 的评论是这样的:第 2:0 行在 'b' 处缺少 {',', ';', CR},解析器会抛出我。如果您包含来自 eostmt 上下文的任何内容,但没有终止行 {'\r'? '\n'} 它不会抛出警告消息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 2022-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多