javaparsingantlrantlr4

ANTLR4 Context is empty with correct parsing order


I'm trying to parse conjunctive queries of the form: "Answer(x,y,z):-R(x,y),U(y,z).".

Using Antlr4 in Java (Maven) I built the following grammar

grammar CQgrammar;

// Parser rules
query : head ':-' body;
head : atom;
body : atom (',' atom)* '.';
atom : ATOMNAME '(' term* (',' term)* ')';
term : CONST | VAR;

// Lexer rules
VAR: [a-z];
CONST: '"' [a-zA-Z0-9]+ '"';
TERMS: '(' | ')' | ',' | '.' | ':-';

ATOMNAME: [a-zA-Z0-9]+;

From this, I extend the generated listener class to override

  1. enterQuery
  2. enterHead
  3. enterBody
  4. enterAtom
  5. enterTerm For now, I have simple printlns in these overrides, but the goal is to construct a conjunctive query class from this.

My main function is as follows:

public static void main(String[] args) {
        String query = "Answer(x,y,z):-R(x,y),U(y,z).";
        org.parsing.CQgrammarLexer lexer = new org.parsing.CQgrammarLexer(CharStreams.fromString(query));
        org.parsing.CQgrammarParser parser = new org.parsing.CQgrammarParser(new CommonTokenStream(lexer));

        CQparser listener = new CQparser();
        parser.addParseListener(listener);
        parser.query();
    }

From the printlines in the overrides, I can see that the structure is correct, as in each part of the query is entered in the correct order and there are no errors.

Yet, when I try to access the text in each override with ctx.getText(), It is empty. Even the other getters on the ctx parameter such as ctx.Atom() in enterAtom Is empty.

I believe something is wrong with the lexer part but the documentation is not very clear to me on this. Does anyone know what I could do to fix this?

Thank you in advance!


Solution

  • You generally use a ParseTreeWalker to walk the parse tree. A quick demo:

    public class CQgrammarDemo {
        public static void main(String[] args) {
            String query = "Answer(x,y,z):-R(x,y),U(y,z).";
            CQgrammarLexer lexer = new CQgrammarLexer(CharStreams.fromString(query));
            CQgrammarParser parser = new CQgrammarParser(new CommonTokenStream(lexer));
            ParseTreeWalker.DEFAULT.walk(new DemoListener(), parser.query());
        }
    }
    
    class DemoListener extends CQgrammarBaseListener {
        @Override
        public void enterTerm(CQgrammarParser.TermContext ctx) {
            System.out.println("const: " + ctx.CONST() + ", var: " + ctx.VAR());
        }
    }
    

    prints:

    const: null, var: x
    const: null, var: y
    const: null, var: z
    const: null, var: x
    const: null, var: y
    const: null, var: y
    const: null, var: z