Недавно я получил ошибку несоответствия, и мне было интересно, может ли кто-нибудь просмотреть и увидеть какие-либо недостатки в моем коде.
Вот мой файл грамматики:
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;
После компиляции с этим кодом:
begin
var b = 5
var c = 4
var a = "Hello World"
output a
end
Я получаю этот вывод:
run:
Hello World
line 10:0 mismatched input '<EOF>' expecting 'begin'
BUILD SUCCESSFUL (total time: 0 seconds)
Наконец, вот мой класс для посетителей:
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<>();
}
}
Если кто-то может найти какие-либо недостатки в моем коде или файле грамматики, пожалуйста, укажите это. Спасибо.
Редактировать: добавлен класс посетителей.