I am trying to use javacc to achieve/perform a few operations. For now, I want to read in a file that would look something like:
a is 6
b is 5
+
My program should then be able to parse this file and create/assign two variables a and b with the above values. It would then sum these two values as the third line in the file is a +
Right now, I have a program that can perform basic arithmetic like so:
PARSER_BEGIN(Evaluator)
public class Evaluator {
public static void main(String[] args) throws Exception {
int result = new Evaluator(new java.io.StringReader(args[0])).S();
System.out.println(result);
}
}
PARSER_END(Evaluator)
SKIP: { " " | "\t" | "\n" | "\r" }
TOKEN: { "(" | ")" | "+" | "-" | "*" | "/" | <NUM: (["0"-"9"])+> }
int S(): {int sum;}
{
sum=E() <EOF> {return sum;}
}
int E(): {int sum, x;}
{
sum=T() ("+" x=T() {sum += x;} )* {return sum;}
}
int T(): {int sum, x;}
{
sum=F() ("*" x=F() {sum *= x;} )* {return sum;}
}
int F(): {int x; Token n;}
{
n=<NUM> {return Integer.parseInt(n.image);}
|
"(" x=E() ")" {return x;}
}
To use the above, you would create a Grammar file MyFile.jj and run javacc MyFile.jj - this would then generate the relevant Java classes. Then running javac *.java would compile them and finally, you can then run java Evaluator 2+3 which would then outpt 5.
In Java, I know you can read in a file by using the Scanner class and running java MyClass < file.txt
So with the above, I have the following:
PARSER_BEGIN(FileParser)
import java.util.Scanner;
import java.io.*;
public class FileParser {
public static void main(String[] args) throws Exception {
// int result = new Evaluator(new java.io.StringReader(args[0])).Start();
// System.out.println(result);
Scanner scanner = new Scanner(System.in);
// Read input from the console using Scanner
StringBuilder inputBuilder = new StringBuilder();
while (scanner.hasNextLine()) {
String line = scanner.nextLine();
inputBuilder.append(line).append("\n");
}
// Pass the input string to the parser
String input = inputBuilder.toString();
try {
FileParser parser = new FileParser(new ByteArrayInputStream(input.getBytes()));
parser.Start();
} catch (ParseException e) {
e.printStackTrace();
}
}
}
PARSER_END(FileParser)
SKIP: { " " | "\t" | "\r" }
//TOKEN: { "(" | ")" | "+" | "-" | "*" | "/" | <NUMBER: (["0"-"9"])+> | <IDENTIFIER: ["a"-"z"] ["a"-"z"] > | <EOL: "\n" > }
TOKEN: {
<IDENTIFIER: (["a"-"z"] ["a"-"z"])* > |
<NUMBER: (["0"-"9"])+ > |
<ASSIGN: "is" > |
<EOL: "\n" >
}
int Start(): {int sum;}
{
// sum = Expression() <EOF> { return sum; }
Assignment()
Assignment()
Expression()
}
void Assignment(): {int a, b;}
{
<IDENTIFIER> "is" <NUMBER> <EOL>
{
String variableName = ((Token)jjtGetChild(0)).image;
int value = Integer.parseInt(((Token)jjtGetChild(2)).image);
if (variableName.equals("a")) {
a = value;
} else if (variableName.equals("b")) {
b = value;
}
}
}
int Expression(): {int a, b;}
{
// sum = Term() ("+" x = Term() { sum += x; })* { return sum; }
"+"
{
int result = a + b;
System.out.println("Sum of a and b: " + result);
}
}
int Term(): {int product, factor;}
{
product = Factor() ("*" factor = Factor() { product *= factor; })* { return product; }
}
int Factor(): {int value; Token numToken;}
{
numToken = <NUMBER> { return Integer.parseInt(numToken.image); }
|
"(" value = Expression() ")" { return value; }
}
This compiles fine with javacc however when I go to compile the Java classes I get the following:
FileParser.java:43: error: cannot find symbol
String variableName = ((Token)jjtGetChild(0)).image;
^
symbol: method jjtGetChild(int)
location: class FileParser
FileParser.java:44: error: cannot find symbol
int value = Integer.parseInt(((Token)jjtGetChild(2)).image);
^
symbol: method jjtGetChild(int)
location: class FileParser
I have not been able to find much on this online. How can I fix this?