Ошибка при создании грамматики для шахматных файлов PGN

Я сделал эту грамматику ANTLR4, чтобы проанализировать PGN внутри моей программы на Java, но мне не удалось решить в ней двусмысленность:

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
        ;

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

TAG_TYPE:   LETTER+;
TAG_VALUE:  .*;

MOVE_NUMBER: DIGIT+;
MOVE_DESC: .*;  

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

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

И это вывод ошибки:

$ antlr4 Pgn.g4 
error(50): Pgn.g4:6:6: syntax error: 'TAG_TYPE "TAG_VALUE"' came as a complete surprise to me while matching alternative

Я думаю, что ошибка связана с тем, что "[", "]" и '" ' нельзя использовать свободно ни в Grammar, ни в Lexer.

Помощь или советы приветствуются.


person loloof64    schedule 24.12.2013    source источник
comment
Я думаю, что решил проблему, поместив [ и ] в строковые литералы, например '[' и ']'. Но на этот раз я получаю довольно длинную ошибку java stackstrace. Похоже, мне нужно открыть новый вопрос...   -  person loloof64    schedule 24.12.2013


Ответы (1)


Глядя на спецификации для PGN, http://www.thechessdrum.net/PGN_Reference.txt, Я вижу, что там есть формальное определение формата PGN:

18: Formal syntax

<PGN-database> ::= <PGN-game> <PGN-database>
                   <empty>

<PGN-game> ::= <tag-section> <movetext-section>

<tag-section> ::= <tag-pair> <tag-section>
                  <empty>

<tag-pair> ::= [ <tag-name> <tag-value> ]

<tag-name> ::= <identifier>

<tag-value> ::= <string>

<movetext-section> ::= <element-sequence> <game-termination>

<element-sequence> ::= <element> <element-sequence>
                       <recursive-variation> <element-sequence>
                       <empty>

<element> ::= <move-number-indication>
              <SAN-move>
              <numeric-annotation-glyph>

<recursive-variation> ::= ( <element-sequence> )

<game-termination> ::= 1-0
                       0-1
                       1/2-1/2
                       *
<empty> ::=

Я настоятельно рекомендую вам сделать так, чтобы ваша грамматика ANTLR была максимально похожа на эту. Я сделал небольшой проект с ANTLR 4 на Github, который вы можете попробовать: https://github.com/bkiers/PGN-parser

Грамматика (без комментариев):

parse
 : pgn_database EOF
 ;

pgn_database
 : pgn_game*
 ;

pgn_game
 : tag_section movetext_section
 ;

tag_section
 : tag_pair*
 ;

tag_pair
 : LEFT_BRACKET tag_name tag_value RIGHT_BRACKET
 ;

tag_name
 : SYMBOL
 ;

tag_value
 : STRING
 ;

movetext_section
 : element_sequence game_termination
 ;

element_sequence
 : (element | recursive_variation)*
 ;

element
 : move_number_indication
 | san_move
 | NUMERIC_ANNOTATION_GLYPH
 ;

move_number_indication
 : INTEGER PERIOD?
 ;

san_move
 : SYMBOL
 ;

recursive_variation
 : LEFT_PARENTHESIS element_sequence RIGHT_PARENTHESIS
 ;

game_termination
 : WHITE_WINS
 | BLACK_WINS
 | DRAWN_GAME
 | ASTERISK
 ;

WHITE_WINS
 : '1-0'
 ;

BLACK_WINS
 : '0-1'
 ;

DRAWN_GAME
 : '1/2-1/2'
 ;

REST_OF_LINE_COMMENT
 : ';' ~[\r\n]* -> skip
 ;

BRACE_COMMENT
 : '{' ~'}'* '}' -> skip
 ;

ESCAPE
 : {getCharPositionInLine() == 0}? '%' ~[\r\n]* -> skip
 ;

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

STRING
 : '"' ('\\\\' | '\\"' | ~[\\"])* '"'
 ;

INTEGER
 : [0-9]+
 ;

PERIOD
 : '.'
 ;

ASTERISK
 : '*'
 ;

LEFT_BRACKET
 : '['
 ;

RIGHT_BRACKET
 : ']'
 ;

LEFT_PARENTHESIS
 : '('
 ;

RIGHT_PARENTHESIS
 : ')'
 ;

LEFT_ANGLE_BRACKET
 : '<'
 ;

RIGHT_ANGLE_BRACKET
 : '>'
 ;

NUMERIC_ANNOTATION_GLYPH
 : '$' [0-9]+
 ;

SYMBOL
 : [a-zA-Z0-9] [a-zA-Z0-9_+#=:-]*
 ;

SUFFIX_ANNOTATION
 : [?!] [?!]?
 ;

UNEXPECTED_CHAR
 : .
 ;

Версию с комментариями см. по адресу: https://github.com/bkiers/PGN-parser/blob/master/src/main/antlr4/nl/bigo/pp/PGN.g4

person Bart Kiers    schedule 30.12.2013
comment
Большое спасибо :) Думаю, воспользуюсь грамматикой pgn из вашего проекта. Могу я также спросить вас, под какой лицензией он? Потому что я не мог его распознать. - person loloof64; 30.12.2013
comment
@LaurentBERNABE, нет проблем, не стесняйтесь использовать его. Лицензия действительно была не слишком ясной: я отредактировал исходные файлы, чтобы было ясно, что я использовал MIT. лицензия. - person Bart Kiers; 31.12.2013
comment
Я разветвил репозиторий Барта, чтобы добавить более строгое распознавание движений. Моя вилка находится по адресу github.com/cgarciam/PGN-parser. - person gamoz; 11.05.2021