Antlr4 为chess PGN文件生成语法时出错
为了解析Java程序中的PGN,我制作了这个ANTLR4语法,但我无法解决其中的歧义:Antlr4 为chess PGN文件生成语法时出错,antlr4,chess,Antlr4,Chess,为了解析Java程序中的PGN,我制作了这个ANTLR4语法,但我无法解决其中的歧义: 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 #Complet
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
我认为这个错误是因为“[”、“]”和“‘”不能自由使用,无论是在语法上还是在词法上
欢迎提供帮助或建议。查看PGN的规范,我发现其中有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> ::=
18:形式语法
::=
::=
::=
::= [ ]
::=
::=
::=
::=
::=
::= ( )
::= 1-0
0-1
1/2-1/2
*
::=
我强烈建议您让您的ANTLR语法尽可能类似于此。我在Github上用ANTLR 4做了一个小项目,您可以尝试:
语法(无注释):
parse
:pgn_数据库EOF
;
pgn_数据库
:pgn_游戏*
;
pgn_游戏
:标记\u节移动文本\u节
;
tag_段
:标记对*
;
标记对
:左括号标记名称标记值右括号
;
标签名称
:符号
;
标记值
:字符串
;
移动文本单元
:元素\u序列游戏\u终止
;
元素u序列
:(元素|递归变化)*
;
要素
:移动\编号\指示
|圣乌运动
|数字注释符号
;
移动编号指示
:整数周期?
;
圣乌运动
:符号
;
递归变异
:左括号元素右括号
;
游戏结束
:白雪胜
|黑人获胜
|平局
|星号
;
白雪公主赢了
: '1-0'
;
黑人获胜
: '0-1'
;
平局
: '1/2-1/2'
;
行注释的剩余部分
:“;”~[\r\n]*->跳过
;
评论
:'{'~'}'*'}'->跳过
;
逃跑
:{getCharPositionInLine()==0}?'%'~[\r\n]*->跳过
;
空间
:[\t\r\n]+->跳过
;
一串
: '"' ('\\\\' | '\\"' | ~[\\"])* '"'
;
整数
: [0-9]+
;
时期
: '.'
;
星号
: '*'
;
左括号
: '['
;
右括号
: ']'
;
左括号
: '('
;
右括号
: ')'
;
左角括号
: ''
;
数字注释符号
: '$' [0-9]+
;
象征
:[a-zA-Z0-9][a-zA-Z0-9+=:-]*
;
后缀注释
: [?!] [?!]?
;
意外字符
: .
;
对于带有注释的版本,请参见:我想我已经解决了这个问题,将[and]放在字符串literals中,如“[”和“]“。但这一次,我遇到了一个很长的java stackstrace错误。看起来我需要提出一个新问题……非常感谢:)我想我将使用您项目中的pgn语法。我还可以问您它是在哪个许可证下使用的吗?因为我无法识别它。@LaurentBERNABE,没问题,请随意使用它。许可证确实不太好清除:我已经编辑了源文件,以明确我使用了。我已经对Bart的存储库进行了分叉,以便对移动进行更严格的识别。我的分叉位于。
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
: .
;