nTn
nTn

Reputation: 13

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!

Upvotes: 0

Views: 118

Answers (1)

Bart Kiers
Bart Kiers

Reputation: 170308

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

Upvotes: 0

Related Questions