aboutsummaryrefslogtreecommitdiff
path: root/calculator-javacc
diff options
context:
space:
mode:
authorMaël Gassmann <mael.gassmann@students.bfh.ch>2021-06-12 18:07:13 +0200
committerMaël Gassmann <mael.gassmann@students.bfh.ch>2021-06-12 18:07:13 +0200
commit3bc2064a0999f1b635028156be43190da439be13 (patch)
tree7afa5270b32aff413506a5007698c46d09769d70 /calculator-javacc
parent4d18d279ad449d2e748d88e31beeaa85f1e42a8c (diff)
[~] Handling illegal tokens and writing correct error messages
Diffstat (limited to 'calculator-javacc')
-rw-r--r--calculator-javacc/Calculator.jj336
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