Reputation: 33
I have been getting the mismatch error recently and I was wondering if anyone could review and see any flaws in my code.
Heres my grammar file:
grammar foo;
program: codeBlock EOF;
codeBlock : 'begin' statement* 'end';
statement : print|variableDec|changeValue|ifState;
variableDec : Var ID IS (STRING|NUMBER);
print : Output (STRING|ID);
changeValue : ID IS (ID|NUMBER|STRING);
ifState: IF expressionState block;
block: '{' statement+ '}';
expressionState : (NUMBER|ID|STRING) EXPRESSION (NUMBER|ID|STRING);
EXPRESSION :
'>'|
'<'|
'=='|
'>='|
'<='
;
IF: 'if';
Var: 'var';
Output : 'output';
IS: '=';
ID : [A-z]+;
NUMBER : [0-9]+ ;
STRING : ["] ( ~["\r\n\\] | '\\' ~[\r\n] )* ["] | ['] ( ~['\r\n\\] | '\\' ~[\r\n] )* ['];
WS : [ \n\t]+ -> skip;
Comment: '**' ~( '\r' | '\n' )* -> skip;
After compiling with this code:
begin
var b = 5
var c = 4
var a = "Hello World"
output a
end
I get this output:
run:
Hello World
line 10:0 mismatched input '<EOF>' expecting 'begin'
BUILD SUCCESSFUL (total time: 0 seconds)
Finally here's my visitor class:
public class FooVisitor extends fooBaseVisitor{
private Map<String, Object> variable;
@Override
public Object visitIfState(fooParser.IfStateContext ctx)
{
//do if statement later... use .clear and .accept functions
return true;
}
@Override
public Object visitVariableDec(fooParser.VariableDecContext ctx)
{
String name = ctx.ID(0).getText();
Object value = null;
if(ctx.NUMBER() != null)
{
value = Integer.parseInt(ctx.NUMBER().getText());
}
if(ctx.STRING() != null)
{
value = ctx.STRING().getText();
}
if(ctx.ID(1) != null)
{
value = variable.get(ctx.ID(1).getText());
}
return variable.put(name, value);
}
@Override
public Object visitChangeValue(fooParser.ChangeValueContext ctx)
{
String varName = ctx.ID(0).getText();
if(ctx.ID(1) != null)
{
variable.put(varName, variable.get(ctx.ID(1).getText()));
}
if(ctx.STRING() != null)
{
variable.put(varName, ctx.STRING().getText());
}
if(ctx.NUMBER() != null)
{
variable.put(varName, Integer.parseInt(ctx.NUMBER().getText()));
}
return null;
}
@Override
public Object visitPrint(fooParser.PrintContext ctx)
{
String printText = null;
if(ctx.ID() != null)
{
printText = variable.get(ctx.ID().getText()).toString();
if(variable.get(ctx.ID().getText()) instanceof String)
{
printText = printText.replace("\"", "");
}
}else
{
printText = ctx.STRING().getText();
}
System.out.println(printText);
return printText;
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException {
fooLexer lexer = new fooLexer(new ANTLRFileStream(args[0]));
fooParser parser = new fooParser(new CommonTokenStream(lexer));
ParseTree tree = parser.program();
FooVisitor vistor = new FooVisitor();
vistor.visit(tree);
// Start parsing
parser.program();
}
public FooVisitor() {
//init the variables
this.variable = new HashMap<>();
}
}
If anyone could find any flaws in my code or the grammar file, please point it out. Thanks.
Edit: added the visitor class.
Upvotes: 0
Views: 480
Reputation: 370162
You're calling parser.program()
twice (third and eigth line of the main
method). Since the first call consumes all the input (and you don't reset the input stream in between), the second run of the parser starts at the end of file and fails. That's why it's expecting a begin
on line 8.
Remove the second call and it will work fine.
Upvotes: 1