Antlr4でトークンを無効にする方法

Jドレス:

私は多くのデータブロックで構成antlr4テキストファイルを解析する必要があり、各データブロックは、データブロックヘッダー(1行)と複数でDataRow、(1 .. *)のラインを持っています。

データブロックのヘッダーは、常にいくつかの英数字フィールドに続いて、行の最初の位置に「1」で主演します。

DataRowはまた、英数字フィールド(dataFields)から構成され、文字「1」は、第1のデータフィールドであるが、ラインの拳位置にあることはできません。

これは、解析への入力のサンプルです:

1   DataHeaderField1 datafield2 DataBlock1
    DB1_Row1_F1 DB1_Row1_F2    DB1_Row1_F3  DataBlock1
    DB1_Row2_F1 DB1_Row2_F2    DB1_Row2_F3  DataBlock1

1   DataHeaderField1 datafield2 DataBlock2
    DB2_Row1_F1 DB2_Row1_F2    DB2_Row1_F3  DataBlock2
    DB2_Row2_F1 DB2_Row2_F2    DB2_Row2_F3  DataBlock2
    DB2_Row3_F1 DB2_Row3_F2    DB2_Row3_F3  DataBlock2

....

私が試した文法は次のとおりです。

grammar ReadDataBlocks;
start_parsing: dataBlock+ EOF;
dataBlock: commonHeader  row+;
commonHeader: ONE_AT_FIRST_POS APLHANUMERIC* NL ;
row: APLHANUMERIC+ NL;

ONE_AT_FIRST_POS:   '1' {getCharPositionInLine() == 1}?;

APLHANUMERIC : (LETTER
                |
                DIGIT)+;
DIGIT: [0-9];
LETTER: [a-zA-Z];
NL: '\r'? '\n';
ESPACES : [ \t]+ -> skip;

私の文法に示すように、私はレクサーで失活したトークンを持つファイルを解析するには、DIGITのトークンの前にトークンONE_AT_FIRSTを指定することで、そのいずれかの時点で「1」は最初postionで検出されたDIGITとして解析してはなりません。

問題は、次のメッセージを投げるONE_AT_FIRST_POSように、「1」の任意の他の位置にスルーパーサランが依然として識別することです。

IntelliJのアイデアANTLRプラグインからの出力

バートKiers:

実行した後:

public class Main {

    public static void main(String[] args) {

        String source = "1   headerData1 headData2 HeadDataN\n    row1Data Row2Data 1 333 rowNData";
        Lexer lexer = new ReadDataBlocksLexer(CharStreams.fromString(source));
        CommonTokenStream tokens = new CommonTokenStream(lexer);
        tokens.fill();

        for (Token t : tokens.getTokens()) {
            System.out.printf("%-20s `%s`\n", ReadDataBlocksLexer.VOCABULARY.getSymbolicName(t.getType()), t.getText());
        }
    }
}

私は、次のような出力が得られます。

ONE_AT_FIRST_POS     `1`
APLHANUMERIC         `headerData1`
APLHANUMERIC         `headData2`
APLHANUMERIC         `HeadDataN`
NL                   `
`
APLHANUMERIC         `row1Data`
APLHANUMERIC         `Row2Data`
APLHANUMERIC         `1`
APLHANUMERIC         `333`
APLHANUMERIC         `rowNData`
EOF                  `<EOF>`

私はあなたが述語を追加した後、パーサークラスを再生成するために忘れてしまったと思います。

おすすめ

転載: http://43.154.161.224:23101/article/api/json?id=277055&siteId=1