3

IBM i 控制语言 (CL) 语句以\n(newline) 结尾,并在下一行使用+\n-\n继续一个长语句(从下一行-的位置 1 继续,从下一行+的第一个非空白字符继续)。我在书中使用了 ANTLR4 RC1 "Fun with Python Newlines" 示例,这是一个非常接近的匹配并且工作正常,前提是+or-继续字符不会拆分标记文本。例如,这在 CL 中有效:

    chg+                                                   
    var +                                                
    &x (&-                                             
    x++                                                    
       1) /* "Change variable" statement resulting in: chgvar &X (&X+1) */

-或者-

    chgvar &y (&a || 'some +
    stuff') /* result: chgvar &y (&a || 'some stuff') */

这是一个简单的测试装置的语法,仅支持ID-作为换行符:

注意:基于 lexmagic/SimplePy.g4

    grammar CL;
    pgm       :   stat+ EOF ;
    stat      :   ID NEWLINE ;
    ID        :   [a-zA-Z_] [a-zA-Z_0-9]* ;
    NEWLINE   :   '\r'? '\n' ;
    WS        :   [ \t]+ -> skip ;
    LINE_ESC  :   '-' '\r'? '\n' -> skip ;

这是运行它的方法(在终端需要所有导出和别名之后):

    antlr4 CL.g4
    javac *.java
    grun CL pgm -tree
    abc- (Return once)
    def (Return, CTRL-D)
    line 2:0 extraneous input 'def' expecting NEWLINE
    (pgm (stat abc def \n) <EOF>)

ANTLR4 将ID视为两个令牌abcdef而不是abcdef,我理解为什么(当 Lexer 看到-\n它发出ID令牌时abc,丢弃-\ndef作为新令牌开始。)。解析器看到abc def\n而不是abcdef\n.

问题是,有没有办法让解析器将abc-\ndef\n其视为一个令牌而不是两个?

另一方面,如果源代码 =abc -\ndef\n那么它应该合法地发出 2 个令牌,因为 和 之间有abc空格-\n

4

1 回答 1

2

我倾向于使用自定义CharStream实现来隐藏词法分析器中的延续字符,它的工作方式类似于标准流,除了:

您可能需要执行额外的步骤来确保与您的标记关联的行号和列号是正确的,因为词法分析器不会看到每个输入符号。

于 2013-01-22T00:18:20.873 回答