Search code examples
javaparsingantlrantlr4datalog

GDL Antlr grammar


I need a parser for Game Description Language (GDL) in Java

For this I am currently trying to use ANTLR4.

my current grammar given in the following does seem to be not correct or at least the generated parser does not recognize a game description which i will also provide below.

The ANTLR4-Grammar:

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
;

The game description given in 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))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

The error output of the generated parser:

line 24:6 mismatched input '(' expecting {')', SP}
line 27:7 no viable alternative at input '(or'

I don't know what i have to change or how to get a correct grammar

Any help would be appreciated


Solution

  • (At least) 3 things are incorrect:

    • you include ; in your WS rule and its the start of your COMMENT
    • your COMMENT rule says it needs to end with a line break. However, line breaks are already included in the WS rule, and it would disallow comments that end with EOF (without a line break)
    • SP is not needed: spaces need to be skipped and not included in your parser rules

    Try something like this instead:

    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;