From 3bc2064a0999f1b635028156be43190da439be13 Mon Sep 17 00:00:00 2001 From: Maƫl Gassmann Date: Sat, 12 Jun 2021 18:07:13 +0200 Subject: [~] Handling illegal tokens and writing correct error messages --- calculator-javacc/Calculator.jj | 336 ++++++++++++++++++++++------------------ 1 file changed, 182 insertions(+), 154 deletions(-) (limited to 'calculator-javacc') diff --git a/calculator-javacc/Calculator.jj b/calculator-javacc/Calculator.jj index cc22b0a..770bf4c 100644 --- a/calculator-javacc/Calculator.jj +++ b/calculator-javacc/Calculator.jj @@ -1,155 +1,183 @@ -options{ - //DEBUG_PARSER = true; DEBUG_TOKEN_MANAGER = true; -} - -PARSER_BEGIN(Calculator) -import java.util.HashMap; - -public class Calculator { - - private static HashMap variables = new HashMap(); - - public static void main(String[] args) { - Calculator parser = new Calculator(System.in); - while (true){ - System.out.print("Type your expression: "); - try{ - double value = parser.evaluateNextLine(); - System.out.println("Returned: " + value); - }catch (ParseException e){ - System.out.println(e.getMessage()); - try{ - parser.passStatement(); // wiping the tokens of the malformed expression - }catch (ParseException ex){ - System.out.println(ex.getMessage()); - } - } - } - } -} -PARSER_END(Calculator) - -SKIP : { - " "|"\t" -} - -TOKEN : { - | - | - | - | - | - | - | - | - | - | - -} - -double statement() : -{ - Token id; - double i = 0.0; -} -{ - { System.exit(0); }| - i=expression() { return i; }| - id= i=expression() - { - variables.put(id.image,i); //Storing the variable - return i; - } -} - -double expression() : -{ - Token op = null; - double l = 0.0; - double r = 0.0; -} -{ - l=term() ((op= | op=) r=term() - { // folding everything in the l variable - if (op != null){ - if (op.image.equals("+")) - l += r; - else - l -= r; - } - - } - )* - { //returning the parsed value - return l; - } -} - -double term() : -{ - Token op = null; - double l = 0.0; - double r = 0.0; -} -{ - l=factor() ((op=
| op=) r=factor() - { // folding everything in the l variable - if (op != null){ - if (op.image.equals("/")) - l /= r; - else - l *= r; - } - - } - )* - { //returning the parsed value - return l; - } -} - -double factor() : -{ - Token t = null; - Token id = null; - double i = 0.0; -} -{ - (t= | id= | (i=expression())? ) - { - if(id != null){ - Object var = variables.get(id.image); - if (var != null) - i = (double) var; - else - throw new ParseException("'" + id.image + "' is not yet defined."); - }else if(t != null) - i = Double.parseDouble(t.image); - return i; - }| - (t= | id= | (i=expression())? ) - { - if(id != null){ - i = (double)variables.get(id.image); - }else if(t != null) - i = Double.parseDouble(t.image); - return i*(-1); - } -} - -double evaluateNextLine() : -{ - double result = 0.0; -} -{ - (result=statement())? {return result;}| - {System.out.println("\nBuffer was closed. Exiting."); System.exit(0);} -} - -void passStatement() : -{} -{ - | - {System.out.println("\nBuffer was closed. Exiting."); System.exit(0);} +options{ + //DEBUG_PARSER = true; DEBUG_TOKEN_MANAGER = true; +} + +PARSER_BEGIN(Calculator) +import java.util.HashMap; + +public class Calculator { + + private static HashMap variables = new HashMap(); + + public static void main(String[] args) { + Calculator parser = new Calculator(System.in); + while (true){ + System.out.print("Type your expression: "); + try{ + double value = parser.evaluateNextLine(); + System.out.println("Returned: " + value); + }catch (ParseException e){ // Now we will parse the exception message to render it in our format. + int index = "Encountered: \"".length(); + String em = e.getMessage().substring(index); + String token = em.substring(1,4); + + if (token.equals("ILL")){ + em = em.substring(7); + index = em.indexOf("\"")-1; + if (index == 0){ // Special case in which the illegal token would be '"' + index = 2; + } + System.out.println("Illegal token: '"+ em.substring(0 , index) +"'."); + }else if(token.equals("EOL")){ + System.out.println("Last read token: '', w"+em.substring(em.indexOf("\nW")+2)); + }else if(em.split("\n").length > 1){ + index = em.indexOf("\""); + if (index == 0){ // Meaning the last token is not but "char" + em = em.substring(1); + index = em.indexOf("\""); + }else{ + index--; + } + System.out.println("Last read token: '"+ em.substring(0 , index)+"', w"+em.substring(em.indexOf("\nW")+2)); + }else{ //Those were error messages created by ourselves, they are one line messages + System.out.println(e.getMessage()); + } + + try{ + parser.passStatement(); // wiping the tokens of the malformed expression + }catch (ParseException ex){ + System.out.println(ex.getMessage()); //not suppose to be possible to end up here + } + } + } + } +} +PARSER_END(Calculator) + +SKIP : { + " "|"\t" +} + +TOKEN : { + | + | + | + | + | + | + | + | + | + | + | + +} + +double statement() : +{ + Token id; + double i = 0.0; +} +{ + { System.exit(0); }| + i=expression() { return i; }| + id= i=expression() + { + variables.put(id.image,i); //Storing the variable + return i; + } +} + +double expression() : +{ + Token op = null; + double l = 0.0; + double r = 0.0; +} +{ + l=term() ((op= | op=) r=term() + { // folding everything in the l variable + if (op != null){ + if (op.image.equals("+")) + l += r; + else + l -= r; + } + + } + )* + { //returning the parsed value + return l; + } +} + +double term() : +{ + Token op = null; + double l = 0.0; + double r = 0.0; +} +{ + l=factor() ((op=
| op=) r=factor() + { // folding everything in the l variable + if (op != null){ + if (op.image.equals("/")) + l /= r; + else + l *= r; + } + + } + )* + { //returning the parsed value + return l; + } +} + +double factor() : +{ + Token t = null; + Token id = null; + double i = 0.0; +} +{ + (t= | id= | (i=expression())? ) + { + if(id != null){ + Object var = variables.get(id.image); + if (var != null) + i = (double) var; + else + throw new ParseException("'" + id.image + "' is not yet defined."); + }else if(t != null) + i = Double.parseDouble(t.image); + return i; + }| + (t= | id= | (i=expression())? ) + { + if(id != null){ + i = (double)variables.get(id.image); + }else if(t != null) + i = Double.parseDouble(t.image); + return i*(-1); + } +} + +double evaluateNextLine() : +{ + double result = 0.0; +} +{ + (result=statement())? {return result;}| + {System.out.println("\nBuffer was closed. Exiting."); System.exit(0);} +} + + +void passStatement() : +{ + } +{ + (||||||
|||||)* | //Skip any token until the next EOL + {System.out.println("\nBuffer was closed. Exiting."); System.exit(0);} } \ No newline at end of file -- cgit v1.2.3