GDL Antlr 文法
GDL Antlr grammar
我需要 Java
中游戏描述语言 (GDL) 的解析器
为此,我目前正在尝试使用 ANTLR4。
我在下面给出的当前语法似乎不正确,或者至少生成的解析器无法识别我还将在下面提供的游戏描述。
ANTLR4-语法:
grammar GDL;
description : (gdlRule | sentence)+ ;
gdlRule : '(' SP? '<=' SP? sentence (SP literal)* SP? ')';
sentence : propLit | ( '(' relLit ')' );
literal : ( '(' SP? (orLit | notLit | distinctLit | relLit) SP? ')' )
| ( '(' (orLit | notLit | distinctLit | relLit) ')' )
| propLit;
notLit : 'not' SP literal | '~' literal;
orLit : 'or' SP literal* ;
distinctLit : 'distinct' SP term SP term;
propLit : constant;
relLit : constant (SP term)+;
term : ( '(' funcTerm ')' ) | varTerm | constTerm;
funcTerm : constant (SP term)*;
varTerm : '?' constant;
constTerm : constant;
constant : ident | number;
/* ident is any string of letters, digits, and underscores */
ident: ID;
number: NR;
NR : [0-9]+;
ID : [a-zA-Z] [a-zA-Z0-9]* ;
SP : ' '+;
COMMENT : ';'[A-Za-z0-9; \r\t]*'\n' -> skip;
WS : [ ;\t\r\n]+ -> skip
;
GDL给出的游戏说明:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Tictictoe
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(role white)
(role black)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(init (cell 1 1 b))
(init (cell 1 2 b))
(init (cell 1 3 b))
(init (cell 2 1 b))
(init (cell 2 2 b))
(init (cell 2 3 b))
(init (cell 3 1 b))
(init (cell 3 2 b))
(init (cell 3 3 b))
(init (step 1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(<= (next (cell ?j ?k x))
(true (cell ?j ?k b))
(does white (mark ?j ?k))
(does black (mark ?m ?n))
(or (distinct ?j ?m) (distinct ?k ?n)))
(<= (next (cell ?m ?n o))
(true (cell ?m ?n b))
(does white (mark ?j ?k))
(does black (mark ?m ?n))
(or (distinct ?j ?m) (distinct ?k ?n)))
(<= (next (cell ?m ?n b))
(true (cell ?m ?n b))
(does white (mark ?m ?n))
(does black (mark ?m ?n)))
(<= (next (cell ?p ?q b))
(true (cell ?p ?q b))
(does white (mark ?j ?k))
(does black (mark ?m ?n))
(or (distinct ?j ?p) (distinct ?k ?q))
(or (distinct ?m ?p) (distinct ?n ?q)))
(<= (next (cell ?m ?n ?w))
(true (cell ?m ?n ?w))
(distinct ?w b))
(<= (next (step ?y))
(true (step ?x))
(succ ?x ?y))
(succ 1 2)
(succ 2 3)
(succ 3 4)
(succ 4 5)
(succ 5 6)
(succ 6 7)
(<= (row ?m ?x)
(true (cell ?m 1 ?x))
(true (cell ?m 2 ?x))
(true (cell ?m 3 ?x)))
(<= (column ?n ?x)
(true (cell 1 ?n ?x))
(true (cell 2 ?n ?x))
(true (cell 3 ?n ?x)))
(<= (diagonal ?x)
(true (cell 1 1 ?x))
(true (cell 2 2 ?x))
(true (cell 3 3 ?x)))
(<= (diagonal ?x)
(true (cell 1 3 ?x))
(true (cell 2 2 ?x))
(true (cell 3 1 ?x)))
(<= (line ?x) (row ?m ?x))
(<= (line ?x) (column ?m ?x))
(<= (line ?x) (diagonal ?x))
(<= nolinex
(not (line x)))
(<= nolineo
(not (line o)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(<= (legal white (mark ?x ?y))
(true (cell ?x ?y b)))
(<= (legal black (mark ?x ?y))
(true (cell ?x ?y b)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(<= (goal white 50)
(line x)
(line o))
(<= (goal white 100)
(line x)
nolineo)
(<= (goal white 0)
nolinex
(line o))
(<= (goal white 50)
nolinex
nolineo)
(<= (goal black 50)
(line x)
(line o))
(<= (goal black 100)
nolinex
(line o))
(<= (goal black 0)
(line x)
nolineo)
(<= (goal black 50)
nolinex
nolineo)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(<= terminal
(true (step 7)))
(<= terminal
(line x))
(<= terminal
(line o))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
生成的解析器的错误输出:
line 24:6 mismatched input '(' expecting {')', SP}
line 27:7 no viable alternative at input '(or'
我不知道我必须更改什么或如何获得正确的语法
如有任何帮助,我们将不胜感激
问题是你对白色的处理space。
您有两个规则,其中一个创建令牌:
SP : ' '+;
还有一个忽略了白色space:
WS : [ ;\t\r\n]+ -> skip
如果白色space 以space 字符开头,将应用第一条规则,您将获得一个SP
标记。如果 whitespace 以换行符或 WS
规则中列出的其他字符开头,whitespace 的整个 运行 将被忽略。
由于您的语法在某些点上坚持使用 SP
个标记,因此忽略的白色 space 将导致语法错误。
我看不出有什么理由用明确的白色来使你的语法复杂化space。我会去掉 SP
,删除语法中对它的所有引用,让 WS
忽略 whitespace.
我还会从 WS
中删除分号以避免与 COMMENT
交互。 [注 1] 我会简化 COMMENT
以便它只忽略 frim 到行尾的分号,而不是给出有效注释字符的列表。 (如果要在评论中加逗号或*怎么办?)
备注
如果文件开头有一个换行符,第 2 行有一行分号,你会看到这个问题。然后 COMMENT
在第一个字符处不匹配,但是 WS
会。然后 WS
将匹配(并忽略)换行符、分号行、下一个换行符、下一行开头的分号以及后面的 space,留下 Tictictoe
被扫描为 ID
,这将导致解析错误。
如果任何其他评论不是一行分号,您也会看到它。这些当前被扫描为 WS
,在评论前用换行符加注星标。这恰好没问题,因为注释只包含分号。但是任何其他非白色 space 字符都会终止 WS
,然后意外地被解析为程序文本。
(至少)3处不正确:
- 您在
WS
规则中包含 ;
并且它是 COMMENT
的开头
- 你的
COMMENT
规则说它需要以换行符结束。但是,换行符已经包含在 WS
规则中,它会禁止以 EOF
结尾的注释(没有换行符)
不需要 SP
:空格需要被跳过并且不包含在您的解析器规则中
试试这样的方法:
grammar GDL;
description : (gdlRule | sentence)+ ;
gdlRule : '(' '<=' sentence literal* ')';
sentence : propLit | ( '(' relLit ')' );
literal
: ( '(' (orLit | notLit | distinctLit | relLit) ')' )
| ( '(' (orLit | notLit | distinctLit | relLit) ')' )
| propLit
;
notLit : 'not' literal | '~' literal;
orLit : 'or' literal* ;
distinctLit : 'distinct' term term;
propLit : constant;
relLit : constant (term)+;
term : ( '(' funcTerm ')' ) | varTerm | constTerm;
funcTerm : constant (term)*;
varTerm : '?' constant;
constTerm : constant;
constant : ident | number;
ident: ID;
number: NR;
NR : [0-9]+;
ID : [a-zA-Z] [a-zA-Z0-9]*;
COMMENT : ';'[A-Za-z0-9; \r\t]* -> skip;
WS : [ \t\r\n]+ -> skip;
我需要 Java
中游戏描述语言 (GDL) 的解析器为此,我目前正在尝试使用 ANTLR4。
我在下面给出的当前语法似乎不正确,或者至少生成的解析器无法识别我还将在下面提供的游戏描述。
ANTLR4-语法:
grammar GDL;
description : (gdlRule | sentence)+ ;
gdlRule : '(' SP? '<=' SP? sentence (SP literal)* SP? ')';
sentence : propLit | ( '(' relLit ')' );
literal : ( '(' SP? (orLit | notLit | distinctLit | relLit) SP? ')' )
| ( '(' (orLit | notLit | distinctLit | relLit) ')' )
| propLit;
notLit : 'not' SP literal | '~' literal;
orLit : 'or' SP literal* ;
distinctLit : 'distinct' SP term SP term;
propLit : constant;
relLit : constant (SP term)+;
term : ( '(' funcTerm ')' ) | varTerm | constTerm;
funcTerm : constant (SP term)*;
varTerm : '?' constant;
constTerm : constant;
constant : ident | number;
/* ident is any string of letters, digits, and underscores */
ident: ID;
number: NR;
NR : [0-9]+;
ID : [a-zA-Z] [a-zA-Z0-9]* ;
SP : ' '+;
COMMENT : ';'[A-Za-z0-9; \r\t]*'\n' -> skip;
WS : [ ;\t\r\n]+ -> skip
;
GDL给出的游戏说明:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Tictictoe
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(role white)
(role black)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(init (cell 1 1 b))
(init (cell 1 2 b))
(init (cell 1 3 b))
(init (cell 2 1 b))
(init (cell 2 2 b))
(init (cell 2 3 b))
(init (cell 3 1 b))
(init (cell 3 2 b))
(init (cell 3 3 b))
(init (step 1))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(<= (next (cell ?j ?k x))
(true (cell ?j ?k b))
(does white (mark ?j ?k))
(does black (mark ?m ?n))
(or (distinct ?j ?m) (distinct ?k ?n)))
(<= (next (cell ?m ?n o))
(true (cell ?m ?n b))
(does white (mark ?j ?k))
(does black (mark ?m ?n))
(or (distinct ?j ?m) (distinct ?k ?n)))
(<= (next (cell ?m ?n b))
(true (cell ?m ?n b))
(does white (mark ?m ?n))
(does black (mark ?m ?n)))
(<= (next (cell ?p ?q b))
(true (cell ?p ?q b))
(does white (mark ?j ?k))
(does black (mark ?m ?n))
(or (distinct ?j ?p) (distinct ?k ?q))
(or (distinct ?m ?p) (distinct ?n ?q)))
(<= (next (cell ?m ?n ?w))
(true (cell ?m ?n ?w))
(distinct ?w b))
(<= (next (step ?y))
(true (step ?x))
(succ ?x ?y))
(succ 1 2)
(succ 2 3)
(succ 3 4)
(succ 4 5)
(succ 5 6)
(succ 6 7)
(<= (row ?m ?x)
(true (cell ?m 1 ?x))
(true (cell ?m 2 ?x))
(true (cell ?m 3 ?x)))
(<= (column ?n ?x)
(true (cell 1 ?n ?x))
(true (cell 2 ?n ?x))
(true (cell 3 ?n ?x)))
(<= (diagonal ?x)
(true (cell 1 1 ?x))
(true (cell 2 2 ?x))
(true (cell 3 3 ?x)))
(<= (diagonal ?x)
(true (cell 1 3 ?x))
(true (cell 2 2 ?x))
(true (cell 3 1 ?x)))
(<= (line ?x) (row ?m ?x))
(<= (line ?x) (column ?m ?x))
(<= (line ?x) (diagonal ?x))
(<= nolinex
(not (line x)))
(<= nolineo
(not (line o)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(<= (legal white (mark ?x ?y))
(true (cell ?x ?y b)))
(<= (legal black (mark ?x ?y))
(true (cell ?x ?y b)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(<= (goal white 50)
(line x)
(line o))
(<= (goal white 100)
(line x)
nolineo)
(<= (goal white 0)
nolinex
(line o))
(<= (goal white 50)
nolinex
nolineo)
(<= (goal black 50)
(line x)
(line o))
(<= (goal black 100)
nolinex
(line o))
(<= (goal black 0)
(line x)
nolineo)
(<= (goal black 50)
nolinex
nolineo)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(<= terminal
(true (step 7)))
(<= terminal
(line x))
(<= terminal
(line o))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
生成的解析器的错误输出:
line 24:6 mismatched input '(' expecting {')', SP}
line 27:7 no viable alternative at input '(or'
我不知道我必须更改什么或如何获得正确的语法
如有任何帮助,我们将不胜感激
问题是你对白色的处理space。
您有两个规则,其中一个创建令牌:
SP : ' '+;
还有一个忽略了白色space:
WS : [ ;\t\r\n]+ -> skip
如果白色space 以space 字符开头,将应用第一条规则,您将获得一个SP
标记。如果 whitespace 以换行符或 WS
规则中列出的其他字符开头,whitespace 的整个 运行 将被忽略。
由于您的语法在某些点上坚持使用 SP
个标记,因此忽略的白色 space 将导致语法错误。
我看不出有什么理由用明确的白色来使你的语法复杂化space。我会去掉 SP
,删除语法中对它的所有引用,让 WS
忽略 whitespace.
我还会从 WS
中删除分号以避免与 COMMENT
交互。 [注 1] 我会简化 COMMENT
以便它只忽略 frim 到行尾的分号,而不是给出有效注释字符的列表。 (如果要在评论中加逗号或*怎么办?)
备注
如果文件开头有一个换行符,第 2 行有一行分号,你会看到这个问题。然后
COMMENT
在第一个字符处不匹配,但是WS
会。然后WS
将匹配(并忽略)换行符、分号行、下一个换行符、下一行开头的分号以及后面的 space,留下Tictictoe
被扫描为ID
,这将导致解析错误。如果任何其他评论不是一行分号,您也会看到它。这些当前被扫描为
WS
,在评论前用换行符加注星标。这恰好没问题,因为注释只包含分号。但是任何其他非白色 space 字符都会终止WS
,然后意外地被解析为程序文本。
(至少)3处不正确:
- 您在
WS
规则中包含;
并且它是COMMENT
的开头
- 你的
COMMENT
规则说它需要以换行符结束。但是,换行符已经包含在WS
规则中,它会禁止以EOF
结尾的注释(没有换行符)
不需要 SP
:空格需要被跳过并且不包含在您的解析器规则中
试试这样的方法:
grammar GDL;
description : (gdlRule | sentence)+ ;
gdlRule : '(' '<=' sentence literal* ')';
sentence : propLit | ( '(' relLit ')' );
literal
: ( '(' (orLit | notLit | distinctLit | relLit) ')' )
| ( '(' (orLit | notLit | distinctLit | relLit) ')' )
| propLit
;
notLit : 'not' literal | '~' literal;
orLit : 'or' literal* ;
distinctLit : 'distinct' term term;
propLit : constant;
relLit : constant (term)+;
term : ( '(' funcTerm ')' ) | varTerm | constTerm;
funcTerm : constant (term)*;
varTerm : '?' constant;
constTerm : constant;
constant : ident | number;
ident: ID;
number: NR;
NR : [0-9]+;
ID : [a-zA-Z] [a-zA-Z0-9]*;
COMMENT : ';'[A-Za-z0-9; \r\t]* -> skip;
WS : [ \t\r\n]+ -> skip;