سؤال

Wondering why the expression "setvalue(2@)' is happily accepted by the lexer (and parser) given my grammar/visitor. I am sure I am doing something wrong.

Below is a small sample that should illustrate the problem.

Any help is much appreciated.

grammar ExpressionEvaluator;

parse
 : block EOF
 ;

block
 : stat*
 ;

stat
 : assignment
 ;

assignment
: SETVALUE OPAR expr CPAR
;


expr
 : atom                       #atomExpr
 ;

atom
 : OPAR expr CPAR #parExpr
 | (INT | FLOAT)  #numberAtom
 | ID             #idAtom
 ;

OPAR : '(';
CPAR : ')';
SETVALUE : 'setvalue';

ID
 : [a-zA-Z_] [a-zA-Z_0-9]*
 ;

INT
 : [0-9]+
 ;

FLOAT
 : [0-9]+ '.' [0-9]* 
 | '.' [0-9]+
 ;


STRING
 : '"' (~["\r\n] | '""')* '"'
 ;


SPACE
 : [ \t\r\n] -> skip
 ;

Code snippet:

public override object VisitParse(ExpressionEvaluatorParser.ParseContext context)
    {
        return this.Visit(context.block());
    }

    public override object VisitAssignment(ExpressionEvaluatorParser.AssignmentContext context)
    {
    // TODO - Set ID Value
        return Convert.ToDouble(this.Visit(context.expr()));
    }

    public override object VisitIdAtom(ExpressionEvaluatorParser.IdAtomContext context)
    {
        string id = context.GetText();

        // TODO - Lookup ID value
        return id;
    }


    public override object VisitNumberAtom(ExpressionEvaluatorParser.NumberAtomContext context)
    {
        return Convert.ToDouble(context.GetText());
    }

    public override object VisitParExpr(ExpressionEvaluatorParser.ParExprContext context)
    {
        return this.Visit(context.expr());
    }
هل كانت مفيدة؟

المحلول

The @ character actually isn't matching anything at all. When the lexer reaches that character, the following happen in order:

  1. The lexer determines that no lexer rule can match the @ character.
  2. The lexer reports an error regarding the failure.
  3. The lexer calls _input.consume() to skip past the bad character.

To ensure errors are reported as easily as possible, always add the following rule as the last rule in your lexer.

ErrChar
  : .
  ;

The parser will report an error when it reaches an ErrChar, so you won't need to add an error listener to the lexer.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top