7

Suppose I have the following:

variableDeclaration: Identifier COLON Type SEMICOLON;
Type: T_INTEGER | T_CHAR | T_STRING | T_DOUBLE | T_BOOLEAN;

where those T_ names are just defined as "integer", "char" etc.

Now suppose I'm in the exitVariableDeclaration method of a test program called LittleLanguage. I can refer to LittleLanguageLexer.T_INTEGER (etc.) but I can't see how determine which of these types was found through the context.

I had thought it would be context.Type().getSymbol().getType() but that doesn't return the right value. I know that I COULD use context.Type().getText() but I really don't want to be doing string comparisons.

What am I missing?

Thanks

Pavel Smirnov
  • 4,611
  • 3
  • 18
  • 28
David
  • 5,991
  • 5
  • 33
  • 39

1 Answers1

10

You are loosing information in the lexer by combining the tokens prematurely. Better to combine in a parser rule:

variableDeclaration: Identifier COLON type SEMICOLON;
type: T_INTEGER | T_CHAR | T_STRING | T_DOUBLE | T_BOOLEAN;

Now, type is a TerminalNode whose underlying token instance has a unique type:

variableDeclarationContext ctx = .... ;
TerminalNode typeNode = (TerminalNode) ctx.type().getChild(0);

switch(typeNode.getSymbol().getType()) {
  case YourLexer.T_INTEGER:
     ...
GRosenberg
  • 5,843
  • 2
  • 19
  • 23
  • First of all, thanks for responding. Secondly, shoot me now --- while you described exactly why it was broken, the actual "bug" was that I wrote Type instead of type, forgetting that the first character determines whether the rule is handled by lexer or parser! I never intended it to be a lexer rule. – David Oct 19 '15 at 11:47
  • Having said that, I'm still having a problem. There is no "getSymbol()" method available. "type" shows up as a typeContext, not as a terminal node. There's no getSymbol() available at that point. I can type things like context.type().T_INTEGER().getSymbol() but then I have to know it's already an integer. – David Oct 19 '15 at 11:47
  • By the way, I do know that I can write things like "if context.type().TINTEGER() != null" but that seems like a very sloppy approach. There must be a way to ask the context for the actual token – David Oct 19 '15 at 14:22
  • Code updated: within any chosen _instance_ of a context of type `variableDeclarationContext`, `type()` returns a TerminalNode, which wraps a single token that is the singular token _instance_ that matched in the `type` rule. The token cannot be null. – GRosenberg Oct 19 '15 at 20:30
  • In my VariableDeclarationContext , that type() method returns a value of type "TypeContext, not "TerminalNode". In other words, ctx.type() is NOT a TerminalNode on my system – David Oct 19 '15 at 21:49
  • My bad -- fixed. The `type` context will have a single child node. – GRosenberg Oct 19 '15 at 22:47
  • Thanks -- and I understand exactly why that works. Still not familiar enough with ANTRL to realize that TerminalNode extends ParseTree otherwise I probably would have gotten there eventually :-) Really appreciate the feedback. – David Oct 20 '15 at 00:16