diff options
| author | jwansek <eddie.atten.ea29@gmail.com> | 2021-10-18 16:40:56 +0100 | 
|---|---|---|
| committer | jwansek <eddie.atten.ea29@gmail.com> | 2021-10-18 16:40:56 +0100 | 
| commit | e09b0bb865bbb0087c46b4acd90b759f14dfa824 (patch) | |
| tree | 824f93a769d5ae3b38b4f6b3597347b78478e69c /code/simpleSableCCCalulator | |
| parent | 3c3706a8957f27d7bcb553eff6ded1c6dc76fa24 (diff) | |
| download | esotericFORTRAN-e09b0bb865bbb0087c46b4acd90b759f14dfa824.tar.gz esotericFORTRAN-e09b0bb865bbb0087c46b4acd90b759f14dfa824.zip | |
added sableCC calculator
Diffstat (limited to 'code/simpleSableCCCalulator')
8 files changed, 245 insertions, 0 deletions
| diff --git a/code/simpleSableCCCalulator/README.md b/code/simpleSableCCCalulator/README.md new file mode 100644 index 0000000..4c75421 --- /dev/null +++ b/code/simpleSableCCCalulator/README.md @@ -0,0 +1,20 @@ +# simpleSableCCCalculator + +sableCC is a too used to parse .grammar files (containing a BNF, and lexer information) +into a lexer and parser. We can do a depth first traversal of the produced abstract syntax tree +to parse in the correct order. This is in the file `Translation.java`. + +You produce a lexer and parser by running the sablecc .jar file you can download [here](http://downloads.sourceforge.net/sablecc/sablecc-3.7.zip). Then run it with the first argument as the grammar file: + +`java -jar sablecc-3.7/lib/sablecc.jar sableCCCalculator.grammar` + +(changing the paths as appropriate). The produced java files are not included in git since they're unnessicary. We compile the compiler, program stack and translator: + +`javac sableCCCalculator/*.java` + +Then we can run the program. For now it only works by reading files. There are some example maths questions in the examples folder: + +`java sableCCCalculator.Compiler examples/maths.txt` + + + diff --git a/code/simpleSableCCCalulator/examples/maths.txt b/code/simpleSableCCCalulator/examples/maths.txt new file mode 100644 index 0000000..f3b3bd9 --- /dev/null +++ b/code/simpleSableCCCalulator/examples/maths.txt @@ -0,0 +1 @@ +(36/2 + 45) * 3
\ No newline at end of file diff --git a/code/simpleSableCCCalulator/examples/maths2.txt b/code/simpleSableCCCalulator/examples/maths2.txt new file mode 100644 index 0000000..1f1d63e --- /dev/null +++ b/code/simpleSableCCCalulator/examples/maths2.txt @@ -0,0 +1 @@ +sin(45 * 3) / 3
\ No newline at end of file diff --git a/code/simpleSableCCCalulator/examples/maths3.txt b/code/simpleSableCCCalulator/examples/maths3.txt new file mode 100644 index 0000000..e092af1 --- /dev/null +++ b/code/simpleSableCCCalulator/examples/maths3.txt @@ -0,0 +1 @@ +3-1+2
\ No newline at end of file diff --git a/code/simpleSableCCCalulator/sableCCCalculator.grammar b/code/simpleSableCCCalulator/sableCCCalculator.grammar new file mode 100644 index 0000000..426fac1 --- /dev/null +++ b/code/simpleSableCCCalulator/sableCCCalculator.grammar @@ -0,0 +1,35 @@ +Package sableCCCalculator; +Helpers +    digit = ['0' .. '9']; +Tokens +    number = digit+; +    double = ((digit)+ '.' (digit)*) | ((digit)* '.' (digit)+); +    plus = '+'; +    minus = '-'; +    mult = '*'; +    div = '/'; +    mod = '%'; +    l_par = '('; +    r_par = ')'; +    sin = 'sin'; +    blank = (' ' | 13 | 10)+; +Ignored Tokens +    blank; +Productions +    expr = +        {factor} factor | +        {plus} expr plus factor | +        {minus} expr minus factor  +        ; +    factor = +        {term} term | +        {mult} factor mult term | +        {div} factor div term | +        {mod} factor mod term +        ; +    term = +        {number} number | +        {double} double | +        {expr} l_par expr r_par | +        {sine} sin l_par expr r_par +        ;
\ No newline at end of file diff --git a/code/simpleSableCCCalulator/sableCCCalculator/Compiler.java b/code/simpleSableCCCalulator/sableCCCalculator/Compiler.java new file mode 100644 index 0000000..7430cfe --- /dev/null +++ b/code/simpleSableCCCalulator/sableCCCalculator/Compiler.java @@ -0,0 +1,27 @@ +package sableCCCalculator; +import sableCCCalculator.parser.*; +import sableCCCalculator.lexer.*; +import sableCCCalculator.node.*; +import java.io.*; + +public class Compiler +{ +    public static void main(String[] args) +    { +        try +        { +            System.out.println("Using source file: " + args[0]); +            // Create a Parser instance. +            Parser p = new Parser(new Lexer(new PushbackReader(new InputStreamReader(new FileInputStream(args[0])), 1024))); +            // Parse the input. +            Start tree = p.parse(); +            // Apply the translation. +            tree.apply(new Translation()); +            System.out.println(""); +        } +        catch(Exception e) +        { +            System.out.println(e.getMessage()); +        } +    } +}
\ No newline at end of file diff --git a/code/simpleSableCCCalulator/sableCCCalculator/ProgramStack.java b/code/simpleSableCCCalulator/sableCCCalculator/ProgramStack.java new file mode 100644 index 0000000..1875e57 --- /dev/null +++ b/code/simpleSableCCCalulator/sableCCCalculator/ProgramStack.java @@ -0,0 +1,28 @@ +package sableCCCalculator; +import sableCCCalculator.node.*; +import java.util.Stack; + +public class ProgramStack<T extends Token> extends Stack<T> { +     +    public String toString() { +        String out = "Stack is now: ["; +        for (int i = 0; i < this.size(); i++) { +            String theStr = this.elementAt(i).toString(); +            out += String.format("%s, ", theStr.substring(0, theStr.length() - 1)); +        } +        return out.substring(0, out.length() - 2) + "]"; +    } + +    public static void main(String[] args) { +        ProgramStack<Token> myStack = new ProgramStack<>(); +        myStack.add(new TNumber("2")); +        myStack.add(new TNumber("4")); +        myStack.add(new TNumber("6")); +        myStack.add(new TNumber("0")); +        myStack.add(new TNumber("1")); +        myStack.add(new TDouble("24601.10642")); + +        System.out.println(myStack.pop().getText()); +        System.out.println(myStack); +    } +} diff --git a/code/simpleSableCCCalulator/sableCCCalculator/Translation.java b/code/simpleSableCCCalulator/sableCCCalculator/Translation.java new file mode 100644 index 0000000..d8fd74d --- /dev/null +++ b/code/simpleSableCCCalulator/sableCCCalculator/Translation.java @@ -0,0 +1,132 @@ +package sableCCCalculator; +import sableCCCalculator.analysis.*; +import sableCCCalculator.node.*; + +class Translation extends DepthFirstAdapter +{ +    private ProgramStack<Token> programStack = new ProgramStack<>(); + +    public void caseTNumber(TNumber node) +    { +        System.out.println("Pushing " + Integer.parseInt(node.getText()) + " to stack"); +        programStack.push(node); +        System.out.println(programStack); +    } + +    public void caseTDouble(TDouble node) +    { +        System.out.println("Pushing a double: " + Double.parseDouble(node.getText())); +        programStack.push(node); +        System.out.println(programStack); +    } + +    public void outASineTerm(ASineTerm node)  +    { +        Double num = Double.parseDouble(programStack.pop().getText()); +        System.out.println("Popped " + num); +        Double out = Math.sin(Math.toRadians(num)); +        programStack.push(new TDouble(String.format("%f", out))); +        System.out.println("Pushed sin(" + num + ") = " + out + " to stack"); +        System.out.println(programStack); +    } + +    public void outAPlusExpr(APlusExpr node) +    { +        Double num2 = Double.parseDouble(programStack.pop().getText()); +        Double num1 = Double.parseDouble(programStack.pop().getText()); +        System.out.println("Popped " + num1 + " and " + num2 + " from stack"); +        Double out = num1 + num2; +        if ((out % 1) == 0)  +        { +            // the output is an integer, change types to save memory +            programStack.push(new TNumber(String.format("%d", out.intValue()))); +        } +        else +        { +            programStack.push(new TDouble(String.format("%f", out))); +        } +         +        System.out.println("Pushed " + num1 + "+" + num2 + "=" + out + " to stack"); +        System.out.println(programStack); +    } + +    public void outAMinusExpr(AMinusExpr node) +    { +        Double num2 = Double.parseDouble(programStack.pop().getText()); +        Double num1 = Double.parseDouble(programStack.pop().getText()); +        System.out.println("Popped " + num1 + " and " + num2 + " from stack"); +        Double out = num1 - num2; +        if ((out % 1) == 0)  +        { +            // the output is an integer, change types to save memory +            programStack.push(new TNumber(String.format("%d", out.intValue()))); +        } +        else +        { +            programStack.push(new TDouble(String.format("%f", out))); +        } +         +        System.out.println("Pushed " + num1 + "-" + num2 + "=" + out + " to stack"); +        System.out.println(programStack); +    } + +    public void outAMultFactor(AMultFactor node) +    { +        Double num2 = Double.parseDouble(programStack.pop().getText()); +        Double num1 = Double.parseDouble(programStack.pop().getText()); +        System.out.println("Popped " + num1 + " and " + num2 + " from stack"); +        Double out = num1 * num2; +        if ((out % 1) == 0)  +        { +            // the output is an integer, change types to save memory +            programStack.push(new TNumber(String.format("%d", out.intValue()))); +        } +        else +        { +            programStack.push(new TDouble(String.format("%f", out))); +        } +         +        System.out.println("Pushed " + num1 + "*" + num2 + "=" + out + " to stack"); +        System.out.println(programStack); +    } + +    public void outADivFactor(ADivFactor node) +    { +        Double num2 = Double.parseDouble(programStack.pop().getText()); +        Double num1 = Double.parseDouble(programStack.pop().getText()); +        System.out.println("Popped " + num1 + " and " + num2 + " from stack"); +        Double out = num1 / num2; +        if ((out % 1) == 0)  +        { +            // the output is an integer, change types to save memory +            programStack.push(new TNumber(String.format("%d", out.intValue()))); +        } +        else +        { +            programStack.push(new TDouble(String.format("%f", out))); +        } +         +        System.out.println("Pushed " + num1 + "/" + num2 + "=" + out + " to stack"); +        System.out.println(programStack); +    } + +    public void outAModFactor(AModFactor node) +    { +        Double num2 = Double.parseDouble(programStack.pop().getText()); +        Double num1 = Double.parseDouble(programStack.pop().getText()); +        System.out.println("Popped " + num1 + " and " + num2 + " from stack"); +        Double out = num1 % num2; +        if ((out % 1) == 0)  +        { +            // the output is an integer, change types to save memory +            programStack.push(new TNumber(String.format("%d", out.intValue()))); +        } +        else +        { +            programStack.push(new TDouble(String.format("%f", out))); +        } +         +        System.out.println("Pushed " + num1 + "%" + num2 + "=" + out + " to stack"); +        System.out.println(programStack); +    } +} | 
