So, I just started learning antlr4 and I just made an extremely simple programming language. The language can create variables (int, booleans, and strings), change their values, and output their values. However, I am trying to do an if statement but after many tries, it didn't work. Googling didn't help either since most of the others code is too different to understand and apply it on my own. Most of my code follow this tutorial:
https://progur.com/2016/09/how-to-create-language-using-antlr4.html
Here's my grammar file
grammar valhallap;
program : 'begin' statement+ 'end';
ifState : ifDec 'STARTIF' statement+ 'ENDIF';
statement : createINT|assign|addINT|printVar|createString|print|createBool|;
ifDec: 'if' (NUMBER|ID) EXPRESION (NUMBER|ID) 'then';
createINT : 'new' 'int' ID;
createBool: 'new' 'bool' ID;
createString : 'new' 'string' ID;
addINT : 'addINT' ID NUMBER;
assign : 'set' ID (STRING|BOOL|NUMBER);
print : 'output' 'say' STRING;
printVar : 'output' 'var' ID;
ID : [A-z]+;
NUMBER : [0-9]+ ;
STRING : ["] ( ~["\r\n\\] | '\\' ~[\r\n] )* ["] | ['] ( ~['\r\n\\] | '\\' ~[\r\n] )* ['];
BOOL : 'true' | 'false';
WS : [ \n\t]+ -> skip;
Comment: '**' ~( '\r' | '\n' )* -> skip;
STATEMENT : .;
EXPRESION:
'MORETHAN'
|'LESSTHAN'
|'EQUALS'
|'LESSEQUALS'
|'MOREEQUALS';
Finally here's the listener class
import com.power.valhallap.grammar.*;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CommonTokenStream;
/**
*
* @author admin
*/
public class ValhallaListener extends valhallapBaseListener{
/**
* @param args the command line arguments
*/
private Map<String, Object> variables;
public static boolean ifState = false;
public ValhallaListener()
{
//init all the variables
variables = new HashMap<>();
}
//if statements
@Override
public void exitAssign(valhallapParser.AssignContext ctx)
{
String variable = ctx.ID().getText();
if(variables.get(variable) instanceof String)
{
if(ctx.NUMBER() != null || ctx.BOOL() != null)
{`enter code here`
System.out.println("error expecting string");
}
}
if(variables.get(variable) instanceof Boolean)
{
if(ctx.NUMBER() != null || ctx.STRING() != null)
{
System.out.println("error expecting boolean");
}
}
if(variables.get(variable) instanceof Integer)
{
if(ctx.STRING() != null || ctx.BOOL() != null)
{
System.out.println("error expecting integer");
}
}
if(ctx.STRING() != null)
{
if(variables.get(variable) instanceof String)
{
String finalString = ctx.STRING().getText();
finalString = finalString.replace("\"", "");
variables.put(variable, finalString);
}
}
if(ctx.NUMBER() != null)
{
if(variables.get(variable) instanceof Integer)
{
variables.put(variable, Integer.parseInt(ctx.NUMBER().getText()));
}
}
if(ctx.BOOL() != null)
{
if(variables.get(variable) instanceof Boolean)
{
boolean answer = Boolean.parseBoolean(ctx.BOOL().getText());
variables.put(variable, answer);
}
}
}
@Override
public void exitCreateINT(valhallapParser.CreateINTContext ctx)
{
//get's the variable name of int
String variableName = ctx.ID().getText();
if(!variables.containsKey(variableName))
{
//add the name to the hashmap with the init value of 0
variables.put(variableName, 0);
}
}
@Override
public void exitAddINT(valhallapParser.AddINTContext ctx)
{
//get the var name
String varName = ctx.ID().getText();
//get the value
int first = Integer.parseInt(variables.get(varName).toString());
int addValue = Integer.parseInt(ctx.NUMBER().getText());
int finalValue = first + addValue;
//assign the new value
variables.put(varName, finalValue);
}
@Override
public void exitPrintVar(valhallapParser.PrintVarContext ctx)
{
String varName = ctx.ID().getText();
System.out.println(variables.get(varName));
}
@Override
public void exitPrint(valhallapParser.PrintContext ctx)
{
String output = ctx.STRING().getText();
output = output.replace("\"", "");
System.out.println(output);
}
@Override
public void exitCreateString(valhallapParser.CreateStringContext ctx)
{
String variableName = ctx.ID().getText();
if(!variables.containsKey(variableName))
{
//add the name to the hashmap with the init value of null
variables.put(variableName, "");
}
}
@Override
public void exitCreateBool(valhallapParser.CreateBoolContext ctx)
{
//get's the variable name of int
String variableName = ctx.ID().getText();
if(!variables.containsKey(variableName))
{
//add the name to the hashmap with the init value of false
variables.put(variableName, false);
}
}
public static void main(String[] args) {
try {
ANTLRInputStream input = new ANTLRInputStream(
new FileInputStream(args[0]));
valhallapLexer lexer = new valhallapLexer(input);
valhallapParser parser = new valhallapParser(new CommonTokenStream(lexer));
parser.addParseListener(new ValhallaListener());
// Start parsing
parser.program();
if(ifState)
{
parser.ifState();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
The syntax of the if statement that I want to achieve is:
begin
if 5 MORETHAN 4 then
.....
ENDIF
end
I new to the antlr4 and some of the concepts are new to me, it would be great if anyone could help me thanks!
Aucun commentaire:
Enregistrer un commentaire