diff options
author | Maël Gassmann <mael.gassmann@students.bfh.ch> | 2021-06-12 18:07:13 +0200 |
---|---|---|
committer | Maël Gassmann <mael.gassmann@students.bfh.ch> | 2021-06-12 18:07:13 +0200 |
commit | 3bc2064a0999f1b635028156be43190da439be13 (patch) | |
tree | 7afa5270b32aff413506a5007698c46d09769d70 /calculator-javacc | |
parent | 4d18d279ad449d2e748d88e31beeaa85f1e42a8c (diff) |
[~] Handling illegal tokens and writing correct error messages
Diffstat (limited to 'calculator-javacc')
-rw-r--r-- | calculator-javacc/Calculator.jj | 336 |
1 files changed, 182 insertions, 154 deletions
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 : { - <EOL: "\n"|"\r">| - <PAL: "(">| - <PAR: ")">| - <ADD: "+">| - <SUB: "-">| - <MUL: "*">| - <DIV: "/">| - <EQU: "=">| - <LET: "let">| - <END: "exit">| - <NUM: (["0"-"9"])+("."((["0"-"9"])+))?>| - <ID: (["a"-"z"]|["A"-"Z"])+> -} - -double statement() : -{ - Token id; - double i = 0.0; -} -{ - <END> { System.exit(0); }| - i=expression() { return i; }| - <LET> id=<ID> <EQU> 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=<ADD> | op=<SUB>) 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=<DIV> | op=<MUL>) 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=<NUM> | id=<ID> | <PAL> (i=expression())? <PAR>) - { - 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; - }| - <SUB> (t=<NUM> | id=<ID> | <PAL> (i=expression())? <PAR>) - { - 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())? <EOL> {return result;}| - <EOF>{System.out.println("\nBuffer was closed. Exiting."); System.exit(0);} -} - -void passStatement() : -{} -{ - <EOL>| - <EOF>{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: '<EOL>', 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 <TOK> 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 : {
+ <EOL: "\n"|"\r">|
+ <PAL: "(">|
+ <PAR: ")">|
+ <ADD: "+">|
+ <SUB: "-">|
+ <MUL: "*">|
+ <DIV: "/">|
+ <EQU: "=">|
+ <LET: "let">|
+ <END: "exit">|
+ <NUM: (["0"-"9"])+("."((["0"-"9"])+))?>|
+ <ID: (["a"-"z"]|["A"-"Z"])+>|
+ <ILL: ~[]>
+}
+
+double statement() :
+{
+ Token id;
+ double i = 0.0;
+}
+{
+ <END> { System.exit(0); }|
+ i=expression() { return i; }|
+ <LET> id=<ID> <EQU> 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=<ADD> | op=<SUB>) 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=<DIV> | op=<MUL>) 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=<NUM> | id=<ID> | <PAL> (i=expression())? <PAR>)
+ {
+ 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;
+ }|
+ <SUB> (t=<NUM> | id=<ID> | <PAL> (i=expression())? <PAR>)
+ {
+ 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())? <EOL> {return result;}|
+ <EOF>{System.out.println("\nBuffer was closed. Exiting."); System.exit(0);}
+}
+
+
+void passStatement() :
+{
+ }
+{
+ (<ILL>|<PAL>|<PAR>|<ADD>|<SUB>|<MUL>|<DIV>|<EQU>|<LET>|<END>|<NUM>|<ID>)* <EOL>| //Skip any token until the next EOL
+ <EOF>{System.out.println("\nBuffer was closed. Exiting."); System.exit(0);}
}
\ No newline at end of file |