我的Antlr4语法编译,但pgn文件解析很糟糕

时间:2013-12-25 15:00:45

标签: grammar antlr4 chess

我制作了自己的语法以解析国际象棋PGN文件,它编译得很好(使用antlr4命令)但是我无法用它来解析pgn文件。

Pgn.g4(antlr4语法,可用here

grammar Pgn;

file:       game (NEWLINE+ game)*;
game:       (tag+ NEWLINE+)? notation;

tag:        '['TAG_TYPE TAG_VALUE']';
notation: move+ END_RESULT?;
move:   MOVE_NUMBER\. MOVE_DESC MOVE_DESC                   #CompleteMove
        |   MOVE_NUMBER'.' MOVE_DESC                        #OnlyWhiteMove
        |   MOVE_NUMBER'...' MOVE_DESC                      #OnlyBlackMove
        |   MOVE_NUMBER\. MOVE_DESC MOVE_DESC '(' move+ ')' #CompleteMoveWithVariant
        |   MOVE_NUMBER'.' MOVE_DESC                        #OnlyWhiteMoveWithVariant
        |   MOVE_NUMBER'...' MOVE_DESC                      #OnlyBlackMoveWithVariant
        ;

END_RESULT: '1-0'
            | '0-1'
            | '1/2-1/2'
            | '*'
            ;

TAG_TYPE:   LETTER+;
TAG_VALUE:  '"'[:print:]*'"';

MOVE_NUMBER: DIGIT+;
MOVE_DESC: [:print:];   

NEWLINE:    '\r'? '\n';
SPACES:     [ \t]+ -> skip;

fragment LETTER: [a-zA-Z];
fragment DIGIT: [0-9];

我的测试文件(Launcher.java):

package com.gmail.bernabe.laurent.j2se.parsing_pgn_test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.tree.ParseTree;

import com.gmail.bernabe.laurent.j2se.parsing_pgn_test.pgn.PgnLexer;
import com.gmail.bernabe.laurent.j2se.parsing_pgn_test.pgn.PgnParser;

public class Launcher {
    public static void main(String[] args) throws FileNotFoundException, IOException {
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setAcceptAllFileFilterUsed(false);
        fileChooser.addChoosableFileFilter(new FileNameExtensionFilter(
                "Portable Game Notation (*.pgn)", new String[]{"pgn"}));

        if (fileChooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION){
            ANTLRInputStream inStream = new ANTLRInputStream(
                    new FileInputStream(fileChooser.getSelectedFile())
            );
            PgnLexer lexer = new PgnLexer(inStream);
            CommonTokenStream tokenStream = new CommonTokenStream(lexer);
            PgnParser parser = new PgnParser(tokenStream);

            ParseTree tree = parser.file();
            System.out.println(tree.toStringTree(parser));
        }
   }
}

我测试了两个样本pgn(使用chessX程序生成),但为了完整性我做了4:DebutUltraSimple.pgnFinaleUltraSimple.pgn(剩下的测试pgn是Scandinave.pgntest.pgn)。

DebutUltraSimple.pgn给出的错误输出:

line 1:7 token recognition error at: '"?'
line 1:9 token recognition error at: '"]'
line 1:11 mismatched input '\n' expecting TAG_VALUE
line 2:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 2:6 token recognition error at: '"?'
line 2:8 token recognition error at: '"]'
line 3:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 3:6 token recognition error at: '"?'
line 3:8 token recognition error at: '?'
line 3:9 token recognition error at: '?'
line 3:10 token recognition error at: '?'
line 3:12 token recognition error at: '?'
line 3:13 token recognition error at: '?'
line 3:15 token recognition error at: '?'
line 3:16 token recognition error at: '?'
line 3:17 token recognition error at: '"]'
line 4:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 4:7 token recognition error at: '"?'
line 4:9 token recognition error at: '"]'
line 5:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 5:7 token recognition error at: '"?'
line 5:9 token recognition error at: '"]'
line 6:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 6:7 token recognition error at: '"?'
line 6:9 token recognition error at: '"]'
line 7:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 7:8 token recognition error at: '"*'
line 7:10 token recognition error at: '"]'
line 8:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 8:5 token recognition error at: '"C'
line 8:9 token recognition error at: '"]'
line 10:3 no viable alternative at input '1.e'
(file (game (tag [ Event) \n [ Site \n [ Date . . \n [ Round \n [ White \n [ Black \n [ Result \n [ ECO (notation move (move 40))) \n \n (game (notation move (move 1 . e) move (move 4 e) move (move 5) (move 2 . Nf) move (move 3 Nc) move (move 6) *)))

FinaleUltraSimple.pgn给出的错误输出:

line 1:7 token recognition error at: '"tra'
line 1:16 token recognition error at: '"]'
line 1:11 mismatched input 'ining' expecting TAG_VALUE
line 2:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 2:6 token recognition error at: '"?'
line 2:8 token recognition error at: '"]'
line 3:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 3:6 token recognition error at: '"?'
line 3:8 token recognition error at: '?'
line 3:9 token recognition error at: '?'
line 3:10 token recognition error at: '?'
line 3:12 token recognition error at: '?'
line 3:13 token recognition error at: '?'
line 3:15 token recognition error at: '?'
line 3:16 token recognition error at: '?'
line 3:17 token recognition error at: '"]'
line 4:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 4:7 token recognition error at: '"?'
line 4:9 token recognition error at: '"]'
line 5:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 5:7 token recognition error at: '"w'
line 5:13 token recognition error at: '_'
line 5:21 token recognition error at: '"]'
line 6:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 6:7 token recognition error at: '"b'
line 6:13 token recognition error at: '_'
line 6:21 token recognition error at: '"]'
line 7:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 7:8 token recognition error at: '"1'
line 7:10 token recognition error at: '/'
line 7:12 token recognition error at: '-'
line 7:14 token recognition error at: '/'
line 7:16 token recognition error at: '"]'
line 8:5 token recognition error at: '"4'
line 8:7 mismatched input 'k' expecting TAG_VALUE
line 8:9 token recognition error at: '/'
line 8:11 token recognition error at: '/'
line 8:16 token recognition error at: '/'
line 8:18 token recognition error at: '/'
line 8:20 token recognition error at: '/'
line 8:22 token recognition error at: '/'
line 8:24 token recognition error at: '/'
line 8:29 token recognition error at: '-'
line 8:31 token recognition error at: '-'
line 8:36 token recognition error at: '"]'    
line 9:0 extraneous input '[' expecting {MOVE_NUMBER, NEWLINE}
line 9:7 token recognition error at: '"1'
line 9:9 token recognition error at: '"]'
line 11:5 no viable alternative at input '1...Kf'
line 11:35 token recognition error at: '='
(file (game (tag [ Event ining) \n [ Site \n [ Date . . \n [ Round \n [ White hite trainer \n [ Black lack trainer \n [ Result (notation move (move 2) (move 1) (move 2))) \n (game (tag [ FEN k 3 8 4 KP 2 8 8 8 8 8 b 0 1) \n [ Setup \n \n (notation move (move 1 ... Kf) move (move 8) (move 2 . f) move (move 7 Kg) move (move 7) (move 3 . Ke) move (move 7 Kg) move (move 6) (move 4 . f) move (move 8 Q) 1/2-1/2)))

生成的源代码上的一些链接:

Pgn.tokens

PgnBaseListener.java

PgnLexer.java

PgnLexer.tokens

PgnListener.java

PgnParser.java

我用eclipse project(压缩)来测试。

将非常感谢帮助和建议。

1 个答案:

答案 0 :(得分:1)

你在哪里发现这个结构“[:print:]”?
你可以这样使用:

TAG_VALUE:  '"' (~[\"])* '"';

你当然也必须为令牌MOVE_DESC更改它。

你在这里有一些问题,因为你的“标签”以“NEWLINE”结尾,但在pgn文件中“notation”之前有超过1个“标签”:

game:       (tag+ NEWLINE+)? notation;
tag:        '['TAG_TYPE TAG_VALUE']';

最好使用ANTRLWorks2来调试语法文件。