20分钟快速编写简易计算器

一、从Gitee上下载编译器框架的可执行包并解压,可以得到一个jar文件,我们不执行jar文件,而是作为一个模块导入。(https://gitee.com/llyronx/LYRON/attach_files/329927/download)。

20分钟快速编写简易计算器

二、使用Intellij IDEA新建一个Java工程,然后将lib和jar包移动到工程文件夹下。

20分钟快速编写简易计算器

三、在Project Structure中设置Dependencies,添加加入的jar文件。

20分钟快速编写简易计算器

四、新建一个XML文件,写下计算器的基本文法:

<?xml version="1.0" encoding="UTF-8" ?>

<pldl>
    <cfgproductions>
        <item>
            <production> Program -> E </production>
        </item>
        <item>
            <production> E -> E + T</production>
        </item>
        <item>
            <production> E -> E - T</production>
        </item>
        <item>
            <production> E -> T </production>
        </item>
        <item>
            <production> T -> T * F</production>
        </item>
        <item>
            <production> T -> T / F</production>
        </item>
        <item>
            <production> T -> F </production>
        </item>
        <item>
            <production> F -> num</production>
        </item>
        <item>
            <production> F -> ( E )</production>
        </item>
    </cfgproductions>

    <terminators>
        <item>
            <name>num</name>
            <regex>[1-9][0-9]*|0</regex>
        </item>
    </terminators>

    <comments></comments>
</pldl>

五、完善<movements>:在每个文法产生式增加简单的属性传递动作,其中加减乘除产生式的属性传递动作都相同:

<?xml version="1.0" encoding="UTF-8" ?>

<pldl>
    <cfgproductions>
        <item>
            <production> Program -> E </production>
            <movements>
                <item>go($1)</item>
            </movements>
        </item>
        <item>
            <production> E -> E + T</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
        </item>
        <item>
            <production> E -> E - T</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
        </item>
        <item>
            <production> E -> T </production>
            <movements>
                <item>go($1)</item>
                <item>$$(val) = $1(val)</item>
            </movements>
        </item>
        <item>
            <production> T -> T * F</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
        </item>
        <item>
            <production> T -> T / F</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
        </item>
        <item>
            <production>T -> F </production>
            <movements>
                <item>go($1)</item>
                <item>$$(val) = $1(val)</item>
            </movements>
        </item>
        <item>
            <production> F -> num</production>
            <movements>
                <item>$$(val) = $1(val)</item>
            </movements>
        </item>
        <item>
            <production> F -> ( E )</production>
            <movements>
                <item>go($2)</item>
                <item>$$(val) = $2(val)</item>
            </movements>
        </item>
    </cfgproductions>

    <terminators>
        <item>
            <name>num</name>
            <regex>[1-9][0-9]*|0</regex>
        </item>
    </terminators>

    <comments></comments>
</pldl> 

六、完善生成四元式的语法动作,只需要在加减乘除产生式和Program产生式中加入<after-generations>即可,其中Program添加的语句用于结束:

<?xml version="1.0" encoding="UTF-8" ?>

<pldl>
    <cfgproductions>
        <item>
            <production> Program -> E </production>
            <movements>
                <item>go($1)</item>
            </movements>
            <after-generations>
                <item>gen(end, _, _, $1(val))</item>
            </after-generations>
        </item>
        <item>
            <production> E -> E + T</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
            <after-generations>
                <item>gen(add, $1(val), $3(val), $$(val))</item>
            </after-generations>
        </item>
        <item>
            <production> E -> E - T</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
            <after-generations>
                <item>gen(sub, $1(val), $3(val), $$(val))</item>
            </after-generations>
        </item>
        <item>
            <production> E -> T </production>
            <movements>
                <item>go($1)</item>
                <item>$$(val) = $1(val)</item>
            </movements>
        </item>
        <item>
            <production> T -> T * F</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
            <after-generations>
                <item>gen(multi, $1(val), $3(val), $$(val))</item>
            </after-generations>
        </item>
        <item>
            <production> T -> T / F</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
            <after-generations>
                <item>gen(div, $1(val), $3(val), $$(val))</item>
            </after-generations>
        </item>
        <item>
            <production>T -> F </production>
            <movements>
                <item>go($1)</item>
                <item>$$(val) = $1(val)</item>
            </movements>
        </item>
        <item>
            <production> F -> num</production>
            <movements>
                <item>$$(val) = $1(val)</item>
            </movements>
        </item>
        <item>
            <production> F -> ( E )</production>
            <movements>
                <item>go($2)</item>
                <item>$$(val) = $2(val)</item>
            </movements>
        </item>
    </cfgproductions>

    <terminators>
        <item>
            <name>num</name>
            <regex>[1-9][0-9]*|0</regex>
        </item>
    </terminators>

    <comments></comments>
</pldl>

七、编写测试代码进行测试,注意ConsoleApplication中LLBegin用于初始化XML文件,LLParse用于解析代码文件(在这里则是四则运算式),LLEnd用于输出四元式。

public static void main(String[] args) throws Exception {
        FileInputStream grammarInput = new FileInputStream(new File("Calculator.xml"));
        FileOutputStream fourTupleOutput = new FileOutputStream(new File("fourTuple.txt"));
        StringBufferInputStream codeInput = new StringBufferInputStream("1+2*3");
        ConsoleApplication consoleApplication = new ConsoleApplication();
        consoleApplication.LLBegin(grammarInput);
        consoleApplication.LLParse(codeInput);
        consoleApplication.LLEnd(fourTupleOutput);
    }

下面是输出结果:

20分钟快速编写简易计算器

 

八、最后编写代码解析输出四元式即可,只需要一个简单的符号表(临时变量和数值的映射):

private static int getVar(HashMap<String, Integer> symbols, String s){
        return Character.isDigit(s.charAt(0)) ? Integer.valueOf(s) : symbols.get(s);
    }
    private static void putVar(HashMap<String, Integer> symbols, String s, Integer i){
        symbols.put(s, i);
    }
    public static int getResult(InputStream stream){
        Scanner scanner = new Scanner(stream);
        HashMap<String, Integer> symbols = new HashMap<>();
        String last = null;
        while (scanner.hasNext()){
            String lineIn = scanner.nextLine();
            String []fourStrs = lineIn.split(",");
            int first, second;
            switch (fourStrs[0]){
                case "add":
                    first = getVar(symbols, fourStrs[1]);second = getVar(symbols, fourStrs[2]); putVar(symbols, fourStrs[3], first + second); break;
                case "sub":
                    first = getVar(symbols, fourStrs[1]);second = getVar(symbols, fourStrs[2]); putVar(symbols, fourStrs[3], first - second); break;
                case "multi":
                    first = getVar(symbols, fourStrs[1]);second = getVar(symbols, fourStrs[2]); putVar(symbols, fourStrs[3], first * second); break;
                case "div":
                    first = getVar(symbols, fourStrs[1]);second = getVar(symbols, fourStrs[2]); putVar(symbols, fourStrs[3], first / second); break;
                case "end":
                    return getVar(symbols, fourStrs[3]);
            }
        }
        return 0;
    }

在main中调用:

public static void main(String[] args) throws Exception {
        FileInputStream grammarInput = new FileInputStream(new File("Calculator.xml"));
        FileOutputStream fourTupleOutput = new FileOutputStream(new File("fourTuple.txt"));
        StringBufferInputStream codeInput = new StringBufferInputStream("1+2*3");
        ConsoleApplication consoleApplication = new ConsoleApplication();
        consoleApplication.LLBegin(grammarInput);
        consoleApplication.LLParse(codeInput);
        consoleApplication.LLEnd(fourTupleOutput);

        fourTupleOutput.close();
        FileInputStream fourTupleInput = new FileInputStream(new File("fourTuple.txt"));
        System.out.println(getResult(fourTupleInput));
    }

运行结果:

20分钟快速编写简易计算器

 

附xml文件代码:

<?xml version="1.0" encoding="UTF-8" ?>

<pldl>
    <cfgproductions>
        <item>
            <production> Program -> E </production>
            <movements>
                <item>go($1)</item>
            </movements>
            <after-generations>
                <item>gen(end, _, _, $1(val))</item>
            </after-generations>
        </item>
        <item>
            <production> E -> E + T</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
            <after-generations>
                <item>gen(add, $1(val), $3(val), $$(val))</item>
            </after-generations>
        </item>
        <item>
            <production> E -> E - T</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
            <after-generations>
                <item>gen(sub, $1(val), $3(val), $$(val))</item>
            </after-generations>
        </item>
        <item>
            <production> E -> T </production>
            <movements>
                <item>go($1)</item>
                <item>$$(val) = $1(val)</item>
            </movements>
        </item>
        <item>
            <production> T -> T * F</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
            <after-generations>
                <item>gen(multi, $1(val), $3(val), $$(val))</item>
            </after-generations>
        </item>
        <item>
            <production> T -> T / F</production>
            <movements>
                <item>go($1)</item>
                <item>go($3)</item>
                <item>$$(val) = newTemp(var)</item>
            </movements>
            <after-generations>
                <item>gen(div, $1(val), $3(val), $$(val))</item>
            </after-generations>
        </item>
        <item>
            <production>T -> F </production>
            <movements>
                <item>go($1)</item>
                <item>$$(val) = $1(val)</item>
            </movements>
        </item>
        <item>
            <production> F -> num</production>
            <movements>
                <item>$$(val) = $1(val)</item>
            </movements>
        </item>
        <item>
            <production> F -> ( E )</production>
            <movements>
                <item>go($2)</item>
                <item>$$(val) = $2(val)</item>
            </movements>
        </item>
    </cfgproductions>

    <terminators>
        <item>
            <name>num</name>
            <regex>[1-9][0-9]*|0</regex>
        </item>
    </terminators>

    <comments></comments>
</pldl>

Java代码:

import app.ConsoleApplication;
import java.io.*;
import java.util.HashMap;
import java.util.Scanner;

public class Calculator {

    private static int getVar(HashMap<String, Integer> symbols, String s){
        return Character.isDigit(s.charAt(0)) ? Integer.valueOf(s) : symbols.get(s);
    }
    private static void putVar(HashMap<String, Integer> symbols, String s, Integer i){
        symbols.put(s, i);
    }
    public static int getResult(InputStream stream){
        Scanner scanner = new Scanner(stream);
        HashMap<String, Integer> symbols = new HashMap<>();
        String last = null;
        while (scanner.hasNext()){
            String lineIn = scanner.nextLine();
            String []fourStrs = lineIn.split(",");
            int first, second;
            switch (fourStrs[0]){
                case "add":
                    first = getVar(symbols, fourStrs[1]);second = getVar(symbols, fourStrs[2]); putVar(symbols, fourStrs[3], first + second); break;
                case "sub":
                    first = getVar(symbols, fourStrs[1]);second = getVar(symbols, fourStrs[2]); putVar(symbols, fourStrs[3], first - second); break;
                case "multi":
                    first = getVar(symbols, fourStrs[1]);second = getVar(symbols, fourStrs[2]); putVar(symbols, fourStrs[3], first * second); break;
                case "div":
                    first = getVar(symbols, fourStrs[1]);second = getVar(symbols, fourStrs[2]); putVar(symbols, fourStrs[3], first / second); break;
                case "end":
                    return getVar(symbols, fourStrs[3]);
            }
        }
        return 0;
    }

    public static void main(String[] args) throws Exception {
        FileInputStream grammarInput = new FileInputStream(new File("Calculator.xml"));
        FileOutputStream fourTupleOutput = new FileOutputStream(new File("fourTuple.txt"));
        StringBufferInputStream codeInput = new StringBufferInputStream("1+2*3");
        ConsoleApplication consoleApplication = new ConsoleApplication();
        consoleApplication.LLBegin(grammarInput);
        consoleApplication.LLParse(codeInput);
        consoleApplication.LLEnd(fourTupleOutput);

        fourTupleOutput.close();
        FileInputStream fourTupleInput = new FileInputStream(new File("fourTuple.txt"));
        System.out.println(getResult(fourTupleInput));
    }
}

 

  

上一篇:解决wps for linux缺失windows字体


下一篇:设置微软符号服务器的又一方法