Processing a String with ANTLR4
Asked Answered
S

2

16

I'm trying to convert my grammar from v3 to v4 and having some trouble finding all the right pieces.

In v3 to process a String, I used:

public static DataExtractor create(String dataspec) {
    CharStream stream = new ANTLRStringStream(dataspec);
    DataSpecificationLexer lexer = new DataSpecificationLexer(stream);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    DataSpecificationParser parser = new DataSpecificationParser(tokens);

    return parser.dataspec();
}

How do I change this to work in v4?

Salivate answered 7/8, 2013 at 17:45 Comment(0)
S
17

The changes that were made are:

  • ANTLRStringStream has been replaced with a constructor in ANTLRInputStream that takes a String
  • parser rules now return a context object which has a public field named according to the returns clause of your rule.

So if the dataspec rule says "returns [DataExtractor extractor]", v4 the method becomes:

public static DataExtractor create(String dataspec) {
    CharStream stream = new ANTLRInputStream(dataspec);
    DataSpecificationLexer lexer = new DataSpecificationLexer(stream);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    DataSpecificationParser parser = new DataSpecificationParser(tokens);

    return parser.dataspec().extractor;
}
Salivate answered 7/8, 2013 at 17:45 Comment(0)
F
28

For ANTLR 4.7 the API was changed a little (ANTLRInputStream is deprecated):

InputStream stream = new ByteArrayInputStream(input.getBytes(StandardCharsets.UTF_8));
lexer.setInputStream(CharStreams.fromStream(stream, StandardCharsets.UTF_8));
parser.setInputStream(new CommonTokenStream(lexer));

Hint: if you want to re-use the parser+lexer instances, call their 'reset()' methods after setting their input streams.

Farro answered 4/6, 2017 at 15:42 Comment(1)
There is also a CharStreams#fromString in the class. This helps even more if one only got a String and wants it to be lexed and parsed. But thank you for the hint :)Leal
S
17

The changes that were made are:

  • ANTLRStringStream has been replaced with a constructor in ANTLRInputStream that takes a String
  • parser rules now return a context object which has a public field named according to the returns clause of your rule.

So if the dataspec rule says "returns [DataExtractor extractor]", v4 the method becomes:

public static DataExtractor create(String dataspec) {
    CharStream stream = new ANTLRInputStream(dataspec);
    DataSpecificationLexer lexer = new DataSpecificationLexer(stream);
    CommonTokenStream tokens = new CommonTokenStream(lexer);
    DataSpecificationParser parser = new DataSpecificationParser(tokens);

    return parser.dataspec().extractor;
}
Salivate answered 7/8, 2013 at 17:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.