ANTLR v4语法用于识别Java代码中的jQuery块

时间:2015-05-09 00:01:50

标签: parsing antlr grammar antlr4

我很难在java代码之间尝试实现语法来解析jQuery块。

我不需要实现java语法。这将成为一名翻译。我只需要按原样输出java并将jQuery转换为java ...

jQuery块被以下标记包围:/*@jQ ... */。可以有多个块,但不允许嵌套。这是一个例子:

package test;

public class Test {

    public static void main(String[] args) {
        System.out.println("Hello world!");

        /*@jQ

        */

        System.out.println("Good bye world!");
    }

}

对于这种特殊情况,翻译器的期望输出将是:

package test;

public class Test {

    public static void main(String[] args) {
        System.out.println("Hello world!");

        System.out.println("Good bye world!");
    }

}

问题是在找到/*@jQ之前我无法读取java。以下是我到目前为止的摘录:

main
:
    java
    (
        jQueryBlock+ java
    )*
;

java
:
    .*?

;

jQueryBlock
:
    JQUERYBLOCKSTART
    (
        jQueryStatement SINGLE_LINE_COMMENT?
    )* JQUERYBLOCKEND
;

和...

JQUERYBLOCKSTART
:
    '/*@jQ'
;

虽然生成的解析树在某种程度上是可以接受的(见下文),但我得到了几个token recognition error ... enter image description here

JjQuery::main:3:22: token recognition error at: '{'
JjQuery::main:5:44: token recognition error at: '{'
JjQuery::main:6:12: token recognition error at: '.'
JjQuery::main:6:16: token recognition error at: '.'
JjQuery::main:6:37: token recognition error at: '!"'
JjQuery::main:12:12: token recognition error at: '.'
JjQuery::main:12:16: token recognition error at: '.'
JjQuery::main:12:40: token recognition error at: '!"'
JjQuery::main:13:5: token recognition error at: '}'
JjQuery::main:15:4: token recognition error at: '}'

提前致谢!

更新

我按照建议修改了我的语法,但我仍然遇到了一些问题。这是一个示例输入,生成的解析树,下面是抛出的错误。

enter image description here

warning(155): Lexer.g4:22:28: rule SINGLE_LINE_COMMENT contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output
warning(155): Lexer.g4:28:25: rule WS contains a lexer command with an unrecognized constant value; lexer interpreters may produce incorrect output
Parser::src:1:3: extraneous input '\n\n' expecting {<EOF>, '/*@jQ', JAVA}
Parser::src:3:5: token recognition error at: '\n'
Parser::src:4:0: token recognition error at: '\n'
Parser::src:5:2: token recognition error at: ' '
Parser::src:5:8: token recognition error at: '\n'
Parser::src:6:0: token recognition error at: '\n'
Parser::src:7:2: extraneous input '\n\n' expecting {<EOF>, '/*@jQ', JAVA}

以下是当前Lexer.g4

lexer grammar Lexer;

@lexer::members {
    public static final int WHITESPACE = 1;
    public static final int COMMENTS = 2;
}

// Default mode rules (the SEA)

JQBegin
:
    '/*@jQ' -> pushMode ( JQUERY )
;

JAVA
:
    .
;

WS
:
    [ \t\r\n]+ -> channel ( WHITESPACE ) // channel(1)

;

SINGLE_LINE_COMMENT
:
    '//' .*? '\n' -> channel ( COMMENTS ) // channel(2)

;

mode JQUERY;

JQEnd
:
    '*/' -> popMode
;

IN
:
    'in'
;

OUT
:
    'out'
;

ID
:
    [a-zA-Z_] [a-zA-Z0-9_]*
;

SEMICOLON
:
    ';'
;

Parser.g4

parser grammar Parser;

options {
    tokenVocab = Lexer;
} // use tokens from ModeTagsLexer.g4

src
:
    (
        JAVA
        | jQuery
    )+ EOF
;

jQuery
:
    JQBegin
    (
        in
        | out
    )* JQEnd
;

in
:
    IN ID SEMICOLON
;

out
:
    OUT ID SEMICOLON
;

1 个答案:

答案 0 :(得分:2)

使用词法模式分别处理JQuery和Java块(即使Java块在您的情况下是微不足道的)。请注意,词法分析器模式仅适用于Lexer语法,而不适用于组合语法。

此外,Java catchall必须一次匹配一个字符。否则它可以使用JQuery开始序列(这可能是您看到的错误的来源)。

main:  ( JAVA | jqBlock )+ EOF ;

jqBlock: JQBegin 
         ( ... | ... | ... ) // your JQuery rules
         JQEnd 
         ;
JQBegin: '/*@jQ' -> pushMode(JQ) ;

JAVA : . ;

mode JQ;
...                             // your JQuery specific rules
BlockComment : '/*' .*? '*/' ;  // handle any possibly ambiguous 
                                // sequences that otherwise might 
                                // cause early exits
JQEnd: '*/' -> popMode()  ;