public static Node ParseStatement() { //Console.WriteLine("parsing expression"); //Diagram rules //1st - Identfier //identifier - = //= - expression //1st - print //print - expression //1st - statements Node root; //TODO- condense this code by replacing similar code with some functions (expect line end for example) switch (tokens.actual.type) { case "END": return(new NoOp()); case "IDENTIFIER": // IDENTIFIER - = - EXPRESSION // get identifier Identifier ident = new Identifier((string)tokens.actual.value); tokens.SelectNext(); if (tokens.actual.type != "EQUAL") //expecting a EQUAL { throw new SystemException($"Identifier with no assignment ({tokens.actual.value}) (position {tokens.position}) [Line: {CurrentLine}]"); } root = new BinOp(); //create the assign biop node root.value = '='; root.children[0] = ident; //left is the identfier tokens.SelectNext(); root.children[1] = ParseExpression(); //right is a expression if (tokens.actual.type != "LINEBREAK") //expect linebreak after the expression; { throw new SystemException($"No LINEBREAK after assignment (position {tokens.position}) [Line: {CurrentLine}]"); } CurrentLine++; tokens.SelectNext(); //go to next token after linebreak return(root); case "PRINT": //print - expression root = new UnOp(); root.value = "print"; tokens.SelectNext(); root.children[0] = ParseExpression(); if (tokens.actual.type != "LINEBREAK") //expect linebreak after the expression; { throw new SystemException($"No LINEBREAK after PRINT (position {tokens.position}) [Line: {CurrentLine}]"); } CurrentLine++; tokens.SelectNext(); //go to next token after linebreak return(root); case "WHILE": root = new WhileNode(); tokens.SelectNext(); root.children[0] = ParseRelExpression(); if (tokens.actual.type != "LINEBREAK") //expect linebreak after the expression; { throw new SystemException($"No LINEBREAK after Relative Expression (position {tokens.position}) [Line: {CurrentLine}]"); } CurrentLine++; tokens.SelectNext(); //go to next token after linebreak root.children[1] = ParseStatements(); //already goes to next line, no select next required return(root); case "IF": root = new IfNode(); tokens.SelectNext(); root.children[0] = ParseRelExpression(); if (tokens.actual.type != "THEN") //expect THEN after the rel expression; { throw new SystemException($"THEN is required after an IF's Relative Expression (position {tokens.position}) [Line: {CurrentLine}]"); } tokens.SelectNext(); if (tokens.actual.type != "LINEBREAK") //expect linebreak after THEN; { throw new SystemException($"No LINEBREAK after Relative Expression (position {tokens.position}) [Line: {CurrentLine}]"); } CurrentLine++; tokens.SelectNext(); //go to next token after linebreak root.children[1] = ParseStatements(); //already goes to next line, no select next required if (tokens.actual.type == "ELSE") { tokens.SelectNext(); if (tokens.actual.type != "LINEBREAK") //expect linebreak after ELSE; { throw new SystemException($"No LINEBREAK after ELSE (position {tokens.position}) [Line: {CurrentLine}]"); } CurrentLine++; tokens.SelectNext(); //go to next token after linebreak root.children[2] = ParseStatements(); //left the token after the END, so it is probably on IF (END IF\n) } if (tokens.actual.type != "IF") //expect IF after the statements END for END IF\n construction; { throw new SystemException($"IF section end symbol not found, found END instead of END IF (position {tokens.position}) [Line: {CurrentLine}]"); } tokens.SelectNext(); if (tokens.actual.type != "LINEBREAK") //expect linebreak after THEN; { throw new SystemException($"No LINEBREAK after Relative Expression (position {tokens.position}) [Line: {CurrentLine}]"); } CurrentLine++; tokens.SelectNext(); //go to next token after linebreak return(root); default: return(new NoOp()); } }
//public static Node ParseStatements(string poi){ // return ParseStatements("none"); // } public static Node ParseStatement() { //Console.WriteLine("parsing expression"); Node root; //TODO- condense this code by replacing similar code with some functions (expect line end for example) switch (tokens.actual.type) { case "END": return(new NoOp()); //assing, start wuth put case "PUT": root = new BinOp(); root.value = "="; tokens.SelectNext(); root.children[1] = ParseRelExpression(); Expect("IN", true); Expect("IDENTIFIER", false); Identifier ident = new Identifier((string)tokens.actual.value); root.children[0] = ident; tokens.SelectNext(); return(root); /*case "IDENTIFIER": * // IDENTIFIER - = - EXPRESSION * // get identifier * Identifier ident = new Identifier((string)tokens.actual.value); * tokens.SelectNext(); * if(tokens.actual.type != "EQUAL"){ //expecting a EQUAL * throw new SystemException ($"Identifier with no assignment ({tokens.actual.value}) (position {tokens.position}) [Line: {CurrentLine}]"); * } * root = new BinOp(); //create the assign biop node * root.value = '='; * root.children[0] = ident; //left is the identfier * tokens.SelectNext(); * root.children[1] = ParseRelExpression(); //right is a relative expression * * if(tokens.actual.type != "LINEBREAK"){ //expect linebreak after the expression; * throw new SystemException ($"No LINEBREAK after assignment (position {tokens.position}) [Line: {CurrentLine}]"); * } * CurrentLine++; * tokens.SelectNext(); //go to next token after linebreak * return root;*/ case "DO": tokens.SelectNext(); Expect("IDENTIFIER", false); FuncCall call = new FuncCall(); call.value = (string)tokens.actual.value; tokens.SelectNext(); if (tokens.actual.type == "WITH") { tokens.SelectNext(); do { if (tokens.actual.type == "COMMA") { tokens.SelectNext(); } call.Add(ParseRelExpression()); }while (tokens.actual.type == "COMMA"); } return(call); case "TO": tokens.SelectNext(); return(ParseFunction()); /* * case "CALL": * tokens.SelectNext(); * Expect("IDENTIFIER",false); * * FuncCall call = new FuncCall(); * call.value = (string)tokens.actual.value; * * tokens.SelectNext(); * Expect("POPEN",true); * if(tokens.actual.type != "PCLOSE"){ * do{ * if(tokens.actual.type == "COMMA"){ * tokens.SelectNext(); * } * call.Add(ParseRelExpression()); * }while (tokens.actual.type == "COMMA"); * } * Expect("PCLOSE",true); * return call; */ case "PRINT": //print - expression root = new UnOp(); root.value = "print"; tokens.SelectNext(); root.children[0] = ParseRelExpression(); return(root); //cl change /* * if(tokens.actual.type != "LINEBREAK"){ //expect linebreak after the expression; * throw new SystemException ($"No LINEBREAK after PRINT (position {tokens.position}) [Line: {CurrentLine}]"); * } * CurrentLine++; * tokens.SelectNext(); //go to next token after linebreak * return root; */ case "WHILE": root = new WhileNode(); tokens.SelectNext(); root.children[0] = ParseRelExpression(); Expect("DO", true); root.children[1] = ParseStatements("while"); Expect("PERIOD", true); return(root); /* * root = new WhileNode(); * tokens.SelectNext(); * root.children[0] = ParseRelExpression(); * if(tokens.actual.type != "LINEBREAK"){ //expect linebreak after the expression; * throw new SystemException ($"No LINEBREAK after Relative Expression (position {tokens.position}) [Line: {CurrentLine}]"); * } * CurrentLine++; * tokens.SelectNext(); //go to next token after linebreak * root.children[1] = ParseStatements("while"); //already goes to next line, no select next required * return root; */ /* * case "DIM": * root = new BinOp(); * root.value = "vardec"; * tokens.SelectNext(); * * if(tokens.actual.type != "IDENTIFIER"){ * throw new SystemException ($"IDENTIFIER is required after an variable declaration declaration (position {tokens.position}) [Line: {CurrentLine}]"); * } * root.children[0] = new NoOp(); * root.children[0].value = (string)tokens.actual.value; * tokens.SelectNext(); * * if(tokens.actual.type != "AS"){ * throw new SystemException ($"'As' is required in an variable declaration (position {tokens.position}) [Line: {CurrentLine}]"); * } * tokens.SelectNext(); * * root.children[1] = parseType(); * * if(tokens.actual.type != "LINEBREAK"){ //expect linebreak after the expression; * throw new SystemException ($"No LINEBREAK after Variable declaration(position {tokens.position}) [Line: {CurrentLine}]"); * } * CurrentLine++; * tokens.SelectNext(); //go to next token after linebreak * * return root; */ case "IF": root = new IfNode(); tokens.SelectNext(); root.children[0] = ParseRelExpression(); Expect("DO", true); root.children[1] = ParseStatements("if"); Expect("PERIOD", true); if (tokens.actual.type == "ELSE") { tokens.SelectNext(); root.children[2] = ParseStatements("else"); } return(root); /* * if(tokens.actual.type != "THEN"){ //expect THEN after the rel expression; * throw new SystemException ($"THEN is required after an IF's Relative Expression (position {tokens.position}) [Line: {CurrentLine}]"); * } * tokens.SelectNext(); * * if(tokens.actual.type != "LINEBREAK"){ //expect linebreak after THEN; * throw new SystemException ($"No LINEBREAK after Relative Expression (position {tokens.position}) [Line: {CurrentLine}]"); * } * CurrentLine++; * tokens.SelectNext(); //go to next token after linebreak * * root.children[1] = ParseStatements("if"); //already goes to next line, no select next required * * if(tokens.actual.type == "ELSE"){ * tokens.SelectNext(); * if(tokens.actual.type != "LINEBREAK"){ //expect linebreak after ELSE; * throw new SystemException ($"No LINEBREAK after ELSE (position {tokens.position}) [Line: {CurrentLine}]"); * } * CurrentLine++; * tokens.SelectNext(); //go to next token after linebreak * root.children[2] = ParseStatements("else"); //left the token after the END, so it is probably on IF (END IF\n) * } * * if(tokens.actual.type != "IF"){ //expect IF after the statements END for END IF\n construction; * throw new SystemException ($"IF section end symbol not found, found END instead of END IF (position {tokens.position}) [Line: {CurrentLine}]"); * } * tokens.SelectNext(); * * if(tokens.actual.type != "LINEBREAK"){ //expect linebreak after THEN; * throw new SystemException ($"No LINEBREAK after Relative Expression (position {tokens.position}) [Line: {CurrentLine}]"); * } * CurrentLine++; * tokens.SelectNext(); //go to next token after linebreak * * return root; */ default: return(new NoOp()); } }