Skip to content

Instantly share code, notes, and snippets.

@hilbigan
Last active November 3, 2019 16:59
Show Gist options
  • Save hilbigan/119bb577631b5c9a68db0ca05a57b765 to your computer and use it in GitHub Desktop.
Save hilbigan/119bb577631b5c9a68db0ca05a57b765 to your computer and use it in GitHub Desktop.
package parser;
import java.util.List;
public class TokenParser {
private static int maxId = 0;
private static int idx = 0;
private static String nextToken = null;
private static List<String> input = null;
private static final Node ERROR_NODE = makeErrorNode();
private static Node makeErrorNode() {
return makeNode("Illegal");
}
private static Node makeNode(String label){
Node node = new Node(maxId++);
node.setLabel(label);
return node;
}
private static Node makeNodeAndAdd(String label, Node parent){
Node node = makeNode(label);
parent.addChildren(node);
node.setParent(parent);
return node;
}
public static Node functionParser(List<String> input) {
TokenParser.input = input;
next();
Node start = makeNode("start");
try {
stmt_list(start);
} catch(IllegalArgumentException ex){
System.out.println(ex.getMessage());
return ERROR_NODE;
}
if(nextToken.equals("$$")){
start.addChildren(makeNode("$$"));
return start;
} else {
return ERROR_NODE;
}
}
private static void stmt_list(Node node) {
node = makeNodeAndAdd("stmt_list", node);
if (!nextToken.equals("$$")){
stmt(node);
stmt_list(node);
}
}
private static void stmt(Node node) {
node = makeNodeAndAdd("stmt", node);
if(nextToken.equals("read")){
matchAndAdd("read", node);
matchAnyAndAdd(node);
} else if(nextToken.equals("write")){
matchAndAdd("write", node);
expr(node);
} else {
matchAnyAndAdd(node);
matchAndAdd(":=", node);
expr(node);
}
}
private static void expr(Node node) {
node = makeNodeAndAdd("expr", node);
term(node);
term_tail(node);
}
private static void term_tail(Node node) {
if(nextToken.equals("+") || nextToken.equals("-")){
node = makeNodeAndAdd("term_tail", node);
add_op(node);
term(node);
term_tail(node);
}
}
private static void add_op(Node node) {
node = makeNodeAndAdd("add_op", node);
if(nextToken.equals("+") ){
matchAndAdd("+", node);
} else if(nextToken.equals("-")){
matchAndAdd("-", node);
} else {
throw new IllegalArgumentException("add_op");
}
}
private static void term(Node node) {
node = makeNodeAndAdd("term", node);
factor(node);
factor_tail(node);
}
private static void factor_tail(Node node) {
if(nextToken.equals("*") || nextToken.equals("/")){
node = makeNodeAndAdd("factor_tail", node);
mult_op(node);
factor(node);
factor_tail(node);
}
}
private static void mult_op(Node node) {
node = makeNodeAndAdd("mult_op", node);
if(nextToken.equals("*") ){
matchAndAdd("*", node);
} else if(nextToken.equals("/")){
matchAndAdd("/", node);
} else {
throw new IllegalArgumentException("mult_op");
}
}
private static void factor(Node node) {
node = makeNodeAndAdd("factor", node);
if(nextToken.equals("(")){
matchAndAdd("(", node);
expr(node);
matchAndAdd(")", node);
} else {
matchAnyAndAdd(node);
}
}
private static void matchAndAdd(String expected, Node parent) {
if(nextToken == null || !nextToken.equals(expected)){
throw new IllegalArgumentException("Expected " + expected + ", got " + nextToken);
}
parent.addChildren(makeNode(expected));
next();
}
private static void matchAnyAndAdd(Node parent){
if(nextToken == null){
throw new IllegalArgumentException("Expected not null");
}
parent.addChildren(makeNode(nextToken));
next();
}
private static void next(){
if(idx == input.size()){
throw new IllegalArgumentException("Expected not null, got EOF");
}
nextToken = input.get(idx);
idx++;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment