Java理论期末大作业_TPL解释器

TPL解释器—作业说明

编写一个Java程序,该程序读取一个文件中的TPL指令(见下文),并执行这些指令。该程序应将TPL文件的名称作为命令行参数,并将结果输出到控制台。一个例子TPL会话如下所示(假设程序名称为cw2):

java cw2 factor.tpl

TPL Interpreter by Shan Zhang

Factorial Calculation

The factorial of 10 is 3628800

TPL Finished OK [16 lines processed].

关于TPL

TPL(Tiny Programming Language)是为本次练习所设计的一种非常简易的编程语言。该语言是完全线性的,它没有分支或循环,每个语句都是按顺序执行。TPL能够处理文本和简单的算法,它具有整型和字符串型两个变量类型。它有8个保留字,具体如下表所示。

保留字名称

描述

#

注释符

INTEGER

声明整型变量

STRING

声明字符串型变量

LET

分配一个变量

CALCULATE

执行算术运算

PRINT

写入数据到控制台

PRINTLN

在PRINT执行基础上附带一个空行

END

终止程序

该语言编写的程序每一行都必须以这些单词中的一个开头,不区分大小写。

COMMENT

#是注释符,所以任何以#字符开头的行都被完全忽略。

例:

    # ignore this line!

INTEGER

INTEGER可以声明一个整型变量,默认值为0。

例:

    INTEGER myInt

这等同于JAVA中的表达“int myInt=0;”

STRING

STRING可以声明一个字符串型变量,默认值为空串。

例:

    STRING myString

这等同于JAVA中的表达“String myString;”

LET

LET将值分配给变量(整数或双引号括起来的字符串)。

例:

LET myInt=42

LET myString="Hello World!"

CALCULATE

CALCULATE对数值或变量执行数值计算,并将结果赋值给变量(必须提前声明)。支持四个运算符:+, -, *和/(分别为加法、减法,乘法和整数除法)。

例:

CALCULATE myInt=2*2

CALCULATE myInt=myInt+24

CALCULATE myInt=intA/intB

PRINT和PRINTLN

PRINT和PRINTLN可以将内容打印到控制台上,唯一的区别是PRINTLN打印完后追加一个新的行(类似Java中的Systme.out.println)。它们可以打印作为参数的文本或变量(字符串或整数)。

例:

PRINTLN "Hello World!"

PRINT myString

PRINTLN myInt

END

END将终止程序,并打印一条提示来表明。

TPL完整程序样例

左边是一个示例TPL输入文件,用于计算5的阶乘。

# A TPL Program to calculate the factorial of 5

INTEGER myInt

INTEGER factorial

STRING myString

LET mystring="Factorial Program"

LET myInt=5

CALCULATE factorial=myInt*4

CALCULATE factorial=factorial*3

CALCULATE factorial=factorial*2

PRINTLN mystring

PRINTLN

PRINT "The factorial of "

PRINT myInt

PRINT " is "

PRINTLN factorial

END

package work;


import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Locale;
import java.util.Scanner;
import java.io.IOException;


public class theoreticalwork {
    public static void main(String[] args){
        virtual_TPL TPL_edit = new virtual_TPL();
        TPL_edit.run();
    }
}



class virtual_TPL{
    static int count = 0;//定义行数
    static int countString = 0;//定义String个数
    static int countInt    = 0;//定义int个数
    static int countError  = 0;//定义编译错误个数
    static int countPrint = 0;//定义要输出的个数
    static TPL_Int[] IntStruct = new TPL_Int[10100];//定义int类数组
    static TPL_String[] StringStruct = new TPL_String[10100];//定义String类数组
    static TPL_CompileError[] ErrorStruct = new TPL_CompileError[10100];//定义编译错误类数组
    static TPL_Print[] PrintStruct = new TPL_Print[10100];//定义输出类数组
    public static void run(){
        Scanner input = new Scanner(System.in);
        BufferedReader in = null;
        try{
            System.out.println("java cw2 factor.tpl");
            System.out.println("TPL Interpreter Cheng Li\n");
            in = new BufferedReader(new FileReader("/Users/licheng/Desktop/Java/JAVA_TPL/文档/2019212212042物联网191李骋/input2.txt"));//读取文件路径
            String check;
            while((check = in.readLine()) != null){
                count ++;
                check = check.trim(); //去除首尾空格

                /*-----------------注释-------------------*/
                if(check.charAt(0) == '#') continue;
                /*----------------------------------------*/

                /*--------------------------------------*/
                //判断最后一个字符串
                if(!check_last(check.charAt(check.length()-1))){
                    countError++;
                    ErrorStruct[countError] = new TPL_CompileError(count,9,"xxxx");
                    continue;
                }
                /*----------------------------------------*/

                String before = check;
                check = check.toUpperCase(Locale.ROOT);
                String s1 = getfirstString(check);

                /*------------判断第一个字符串--------------*/
                int flag = getnum(s1);
                /*---------------------------------------*/

                /*--------------首字符编译报错--------------*/
                if(flag == -1){
                    countError++;
                    ErrorStruct[countError] = new TPL_CompileError(count,flag,s1);
                    continue;
                }
                /*---------------------------------------*/

                /*---------------构造int-----------------*/
                if(flag == 1){
                    String str = check.substring(s1.length()).trim();//删除头尾空格
                    String[] as = str.split(",");//按空格分割
                    for(int i=0;i<as.length;i++){
                        String Intname = as[i].trim();
                        int flagint = getstatusInt(Intname);
                        if(flagint!=-1){
                            countError++;
                            ErrorStruct[countError] = new TPL_CompileError(count,7,Intname);//int变量名存在报错
                            break;
                        }
                        int flagString = getstatusString(Intname);
                        if (flagString!=-1){
                            countError++;
                            ErrorStruct[countError] = new TPL_CompileError(count,7,Intname);//string变量名存在报错
                            break;
                        }
                        countInt++;
                        IntStruct[countInt] = new TPL_Int(Intname);
                        if (!IntStruct[countInt].check_name()){
                            countError++;
                            ErrorStruct[countError] = new TPL_CompileError(count,flag,Intname);//变量名错误
                            break;
                        }
                    }
                }
                /*---------------------------------------*/

                /*---------------构造String-----------------*/
                if(flag == 2){
                    String str = check.substring(s1.length()).trim();
                    String[] as = str.split(",");
                    for (int i=0;i<as.length;i++){
                        String Stringname = as[i].trim();
                        int flagstring = getstatusString(Stringname);
                        int flagint = getstatusInt(Stringname);
                        if(flagint!=-1){
                            countError++;
                            ErrorStruct[countError] = new TPL_CompileError(count,7,Stringname);//int变量名存在报错
                            break;
                        }
                        if(flagstring!=-1){
                            countError++;
                            ErrorStruct[countError] = new TPL_CompileError(count,7,Stringname);//string变量名存在报错
                            break;
                        }
                        countString++;
                        StringStruct[countString] = new TPL_String(Stringname);
                        if (!StringStruct[countString].check_name()){
                            countError++;
                            ErrorStruct[countError] = new TPL_CompileError(count,flag,Stringname);//变量名错误
                            break;
                        }
                    }
                }
                /*---------------------------------------*/


                /*----------------赋值语句-----------------*/
                if(flag == 3){
                    int pos1 = check.indexOf('='); // 第一个等于号的位置
                    if (pos1 == -1){
                        countError++;
                        ErrorStruct[countError] = new TPL_CompileError(count,8,"xxxx");//格式错误
                        continue;
                    }
                    String name_let = getvaluename(check,s1.length(),pos1);
                    if(name_let == null||check_intvalue(name_let)){
                        countError++;
                        ErrorStruct[countError] = new TPL_CompileError(count,8,"xxxxx");//格式错误
                        continue;
                    }
                    int getflag1 = getstatusInt(name_let);//判断int变量是否存在
                    int getflag2 = getstatusString(name_let);//判断string变量名是否存在
                    if(getflag1!=-1){//int类型存在时
                        String value_int = getIntvalue(check,pos1);
                        int value = 0;
                        if(check_intvalue(value_int)){//判断为数字时
                            value = Integer.parseInt(value_int);//存入数据
                            IntStruct[getflag1].putsvalue(value);
                        }else{
                            int flagx = getstatusInt(value_int);//赋值变量名是否存在
                            if (flagx == -1){
                                countError++;//报错
                                ErrorStruct[countError] = new TPL_CompileError(count,4,value_int);
                            }else{
                                IntStruct[getflag1].putsvalue(IntStruct[flagx].getValue());//赋值
                            }
                        }
                    }else if(getflag2!=-1){//string类型存在时
                        String value_String = getStringvalue(before,pos1);//获取字符串赋值
                        String value;
                        if(value_String.charAt(0) == '\"'&&value_String.charAt(value_String.length()-1) == '\"'){//格式错误
                            value = value_String.substring(1,value_String.length()-1);//取出所附的值
                            StringStruct[getflag2].putsvalue(value);//给变量名赋值
                        }else{
                            int flagx = getstatusInt(value_String);//判读是否存在
                            if (flagx == -1){//不能存在编译错误加一
                                countError++;
                                ErrorStruct[countError] = new TPL_CompileError(count,5,value_String);
                            }else{//赋值
                                IntStruct[getflag2].putsvalue(IntStruct[flagx].getValue());
                            }
                        }
                    }else{//都不存在直接报错
                        countError++;
                        ErrorStruct[countError] = new TPL_CompileError(count,3,name_let);
                    }
                }
                /*---------------------------------------*/

                /*---------------算数语句------------------*/
                if(flag == 4){
                    int pos1 = -1;
                    pos1 = check.indexOf('=');
                    if(pos1 == -1){//不存在等号报错
                        countError++;
                        ErrorStruct[countError] = new TPL_CompileError(count,6,"xxxx");
                    }else{//存在等号
                        String num1 = check.substring(s1.length()+1,pos1);//获取算数的变量名
                        num1 = num1.trim();
                        int flagnum1 = getstatusInt(num1);//判断有没有变量名
                        if(flagnum1 == -1){
                            boolean isDagit = check_intvalue(num1);//判断等号后面全是数字
                            if (isDagit){//如果是编译错误加一
                                countError++;
                                ErrorStruct[countError] = new TPL_CompileError(count,6,num1);
                            }else{//错误类型不一致
                                countError++;
                                ErrorStruct[countError] = new TPL_CompileError(count,3,num1);
                            }
                        }else{
                            //判断加减乘除然后进行计算
                                int poschar1 = check.indexOf('+');
                                int poschar2 = check.indexOf('-');
                                int poschar3 = check.indexOf('*');
                                int poschar4 = check.indexOf('/');
                                if(poschar1!=-1){
                                    Cal(1,check,pos1,poschar1,flagnum1);
                                }else if(poschar2!=-1){
                                    Cal(2,check,pos1,poschar2,flagnum1);
                                }else if(poschar3!=-1){
                                    Cal(3,check,pos1,poschar3,flagnum1);
                                }else if(poschar4!=-1){
                                    Cal(4,check,pos1,poschar4,flagnum1);
                                }else{
                                    countError++;
                                    ErrorStruct[countError] = new TPL_CompileError(count,6,"xxx");
                                }
                        }
                    }
                }
                /*---------------------------------------*/

                /*---------------PRINT语句------------------*/
                if(flag == 5){
                    String Print_met = getprintString(before,s1.length());
                    if(Print_met.length() == 0){
                        //如果长度为0,直接加入print/println
                        countPrint++;
                        PrintStruct[countPrint] = new TPL_Print(3,"",0);
                        continue;
                    }
                    if(Print_met.charAt(0) == '\"'&&Print_met.charAt(Print_met.length()-1) == '\"'){//获取直接输出语句
                        String value = Print_met.substring(1,Print_met.length()-1);
                        countPrint++;
                        PrintStruct[countPrint] = new TPL_Print(3,value,0);
                    }else{//获取变量名输出
                        Print_met = Print_met.toUpperCase(Locale.ROOT);
                        int flag1 = getstatusInt(Print_met);
                        int flag2 = getstatusString(Print_met);
                        if(flag1!=-1){//如果是int类型
                            countPrint++;
                            PrintStruct[countPrint] = new TPL_Print(1,"xxxx",IntStruct[flag1].getValue());
                        }else if(flag2!=-1){//string类型
                            countPrint++;
                            PrintStruct[countPrint] = new TPL_Print(3,StringStruct[flag2].getValue(),0);
                        }else{//都不是直接报错
                            countError++;
                            ErrorStruct[countError] = new TPL_CompileError(count,3,Print_met);
                        }
                    }
                }
                /*---------------------------------------*/

                /*---------------PRINTLN语句------------------*/
                //与print类似
                if(flag == 6){
                    String Print_met = getprintString(before,s1.length());
                    if(Print_met.length() == 0){
                        countPrint++;
                        PrintStruct[countPrint] = new TPL_Print(4,"",0);
                        continue;
                    }
                    if(Print_met.charAt(0) == '\"'&&Print_met.charAt(Print_met.length()-1) == '\"'){
                        String value = Print_met.substring(1,Print_met.length()-1);
                        countPrint++;
                        PrintStruct[countPrint] = new TPL_Print(4,value,0);
                    }else{
                        Print_met = Print_met.toUpperCase(Locale.ROOT);
                        int flag1 = getstatusInt(Print_met);
                        int flag2 = getstatusString(Print_met);
                        if(flag1!=-1){
                            countPrint++;
                            PrintStruct[countPrint] = new TPL_Print(2,"xxxx",IntStruct[flag1].getValue());
                        }else if(flag2!=-1){
                            countPrint++;
                            PrintStruct[countPrint] = new TPL_Print(4,StringStruct[flag2].getValue(),0);
                        }else{
                            countError++;
                            ErrorStruct[countError] = new TPL_CompileError(count,3,Print_met);
                        }
                    }
                }
                /*---------------------------------------*/

                /*----------------结束程序----------------*/
                if(flag == 7){
                    break;
                }
                /*---------------------------------------*/
             }
        }
        catch (FileNotFoundException e){
            //路径错误
            System.out.println("文件找不到请检查路径");
            return;
        }
        catch (IOException e){
            //输出错误
            System.out.println("输出错误");
            return;
        }
        if(countError == 0){
            //无错误控制台输出
            for (int i=1;i<=countPrint;i++){
                PrintStruct[i].Print_result();
            }
            System.out.println("TPL Finshed OK["+count+" lines processed]");
        }else{
            //有错误输出错误提示
            for (int i=1;i<=countError;i++){
                System.out.print("Error line");
                System.out.print(ErrorStruct[i].get_line()+":");
                System.out.println(ErrorStruct[i].getError_String());
            }
        }
    }



    /*---------------获取第一个字符串编号函数-----------------*/
    public static int getnum(String s){
        if(s.equals("INTEGER")) return 1;
        if(s.equals("STRING")) return 2;
        if(s.equals("LET")) return 3;
        if(s.equals("CALCULATE")) return 4;
        if(s.equals("PRINT")) return 5;
        if(s.equals("PRINTLN")) return 6;
        if(s.equals("END")) return 7;
        return -1;
    }
    /*------------------------------------------------------*/

    /*---------------获取每行第一个字符串函数-------------------*/
    public static String getfirstString(String check){
        StringBuilder s1 = new StringBuilder();
        for(int i=0;i<check.length();i++){
            if(check.charAt(i) == ' ') break;
            s1.append(check.charAt(i));
        }
        return s1.toString().trim();
    }
    /*------------------------------------------------------*/

    /*------------获取int类型name函数------------------------*/
    public static String getIntname(String check,int pos){
        boolean flagint = false;
        StringBuilder name = new StringBuilder();
        for(int i=pos;i<check.length();i++){
            if(check.charAt(i) == '#') break;
            if(check.charAt(i)!=' '){
                flagint = true;
            }
            if (flagint){
                name.append(check.charAt(i));
            }
        }
        return name.toString().trim();
    }
    /*------------------------------------------------------*/

    /*------------获取String类型name函数------------------------*/
    public static String getStringname(String check,int pos){
        boolean flagint = false;
        StringBuilder name = new StringBuilder();
        for(int i=pos;i<check.length();i++){
            if (check.charAt(i) == '#') break;
            if(check.charAt(i)!=' '){
                flagint = true;
            }
            if (flagint){
                name.append(check.charAt(i));
            }
        }
        return name.toString().trim();
    }
    /*------------------------------------------------------*/

    /*-----------------获取赋值语句变量函数------------------------*/
    public static String getvaluename(String check,int pos1,int pos2){
        int posx = check.length()+1;
        int posy = check.length();
        for(int i=pos1;i<pos2;i++){
            if(check.charAt(i)!=' '){
                posx = i;
                break;
            }
        }
        for(int i=pos2-1;i>=pos1;i--){
            if(check.charAt(i) != ' '){
                posy = i;
                break;
            }
        }
        if(posx>posy) return null;
        return check.substring(posx,posy+1).trim();
    }
    /*------------------------------------------------------*/

    /*-------------------判断变量名Int------------------------*/
    public static int getstatusInt(String check){
        for(int i=1;i<=countInt;i++){
            if(IntStruct[i].getName().equals(check)){
                return i;
            }
        }
        return -1;
    }
    /*------------------------------------------------------*/


    /*-------------------判断变量名String------------------------*/
    public static int getstatusString(String check){
        for(int i=1;i<=countString;i++){
            if(StringStruct[i].getName().equals(check)){
                return i;
            }
        }
        return -1;
    }
    /*------------------------------------------------------*/

    /*-------------------获取int类型的value-------------------*/
    public static String getIntvalue(String check,int pos){
        StringBuilder value = new StringBuilder();
        boolean flag_s = false;
        for (int i=pos+1;i<check.length();i++){
            if (check.charAt(i) != ' ') {
                flag_s = true;
            }
            if (flag_s){
                value.append(check.charAt(i));
            }
        }
        return value.toString().trim();
    }

    /*------------------------------------------------------*/

    /*-----------------判断是否为数字--------------------*/
    public static boolean check_intvalue(String check){
        int pos = (check.charAt(0) == '-')?1:0;
        for (int i=pos;i<check.length();i++){
            if(!Character.isDigit(check.charAt(i))){
                return false;
            }
        }
        return true;
    }
    /*------------------------------------------------------*/

    /*-------------------获取String类型的value-------------------*/
    public static String getStringvalue(String check,int pos){
        StringBuilder value = new StringBuilder();
        boolean flag_s = false;
        for (int i=pos+1;i<check.length();i++){
            if (check.charAt(i) != ' ') {
                flag_s = true;
            }
            if (flag_s){
                value.append(check.charAt(i));
            }
        }
        return value.toString().trim();
    }

    /*------------------------------------------------------*/

    /*---------------------print/println---------------------*/
    public static String getprintString(String check,int pos){
        StringBuilder value = new StringBuilder();
        boolean flag = false;
        for (int i=pos;i<check.length();i++){
            if(check.charAt(i)!=' ') flag = true;
            if(flag) value.append(check.charAt(i));
        }
        return value.toString().trim();
    }
    /*------------------------------------------------------*/

    /*-----------------------算数操作-------------------------*/
    public static void Cal(int x,String check,int pos1,int poschar1,int flagnum1){
        String num2 = check.substring(pos1+1,poschar1);
        num2 = num2.trim();
        String num3 = check.substring(poschar1+1);
        num3 = num3.trim();
        boolean flagnum2 = check_intvalue(num2);
        boolean flagnum3 = check_intvalue(num3);
        int value2 = 0;
        int value3 = 0;
        if (flagnum2){
            value2 = Integer.parseInt(num2);
        }else{
            int x2 = getstatusInt(num2);
            if(x2 == -1){
                countError++;
                ErrorStruct[countError] = new TPL_CompileError(count,3,num2);
                return ;
            }else{
                value2 = IntStruct[x2].getValue();
            }
        }
        if (flagnum3){
            value3 = Integer.parseInt(num3);
        }else{
            int x2 = getstatusInt(num3);
            if(x2 == -1){
                countError++;
                ErrorStruct[countError] = new TPL_CompileError(count,3,num3);
                return;
            }else{
                value3 = IntStruct[x2].getValue();
            }
        }
        if(value3 == 0&&x == 4){
            countError++;
            ErrorStruct[countError] = new TPL_CompileError(count,10,"xxxxx");
            return;
        }
        int result = 0;
        if (x == 1) result = value2 + value3;
        else if (x == 2) result = value2 - value3;
        else if (x == 3) result = value2 * value3;
        else result = value2 / value3;
        IntStruct[flagnum1].putsvalue(result);
    }
    /*------------------------------------------------------*/


    /*-----------------------判断最后一个字母------------------*/
    public static boolean check_last(char ch){
        if(ch>='A'&&ch<='Z'){
            return true;
        }
        if(ch>='a'&&ch<='z'){
            return true;
        }
        if(ch>='0'&&ch<='9'){
            return true;
        }
        if(ch == '\"') return true;
        return false;
    }
    /*------------------------------------------------------*/
}



/*-------------------封装TPL_String类------------------*/
class TPL_String{
    private String name;
    private String value;
    TPL_String(){}
    TPL_String(String sx){
        this.name = sx;
    }
    public boolean check_name(){
        if(this.name.charAt(0)<='9'&&this.name.charAt(0)>='0'){
            return false;
        }
        for (int i=0;i<name.length();i++){
            if (name.charAt(i) == ' ') return false;
        }
        if (name.length() == 0) return false;
        return true;
    }
    public String getName(){
        return this.name;
    }
    public String getValue(){
        return this.value;
    }
    public void putsvalue(String x){
        this.value = x;
    }
}
/*------------------------------------------------------*/




/*-------------------封装TPL_Int类------------------*/
class TPL_Int{
    private String name;
    private int value = 0;
    TPL_Int(){}
    TPL_Int(String sx){
        this.name = sx;
    }
    public boolean check_name(){
        if(this.name.charAt(0)<='9'&&this.name.charAt(0)>='0'){
            return false;
        }
        for (int i=0;i<name.length();i++){
            if (name.charAt(i) == ' ') return false;
        }
        if (name.length() == 0) return  false;
        return true;
    }
    public String getName(){
        return name;
    }
    public int getValue(){
        return value;
    }
    public void putsvalue(int x){
        this.value = x;
    }
}
/*------------------------------------------------------*/




/*-------------------封装TPL_CompileError类------------------*/
class TPL_CompileError{
    private int line = 0;
    private String ERRORStruct;
    TPL_CompileError(){}
    TPL_CompileError(int nline,int flag,String nError){
        this.line = nline;
        if(flag == -1) ERRORStruct = nError + "无法识别";
        if(flag == 1) ERRORStruct = "INTEGER类型" + nError + "声明错误/命名错误";
        if(flag == 2) ERRORStruct = "STRING类型" + nError + "声明错误/命名错误";
        if(flag == 3) ERRORStruct = nError + "未声明此变量";
        if(flag == 4) ERRORStruct = nError + "Integer类型赋值错误";
        if(flag == 5) ERRORStruct = nError + "String类型赋值错误";
        if(flag == 6) ERRORStruct = "CALCULATE计算格式不正确";
        if(flag == 7) ERRORStruct = nError + "重复定义";
        if(flag == 8) ERRORStruct = "赋值语句格式不正确";
        if(flag == 9) ERRORStruct = "格式错误";
        if(flag == 10) ERRORStruct = "除数为零";
    }
    public int get_line(){
        return this.line;
    }
    public String getError_String(){
        return ERRORStruct;
    }
}
/*------------------------------------------------------*/


/*------------------封装需要print(ln)的语句类-------------------*/
class TPL_Print{
    private int flag = -1;
    private int print_int = -1;
    private int println_int = -1;
    private String print_String = "xxx";
    private String println_String = "xxx";
    TPL_Print(){}
    TPL_Print(int flag,String s,int num){
        this.flag = flag;
        if (flag == 1) this.print_int = num;
        else if (flag == 2) this.println_int = num;
        else if (flag == 3) this.print_String = s;
        else if (flag == 4) this.println_String = s;
    }
    public void Print_result(){
        if (flag == 1) System.out.print(print_int);
        else if (flag == 2) System.out.println(println_int);
        else if (flag == 3) System.out.print(print_String);
        else if (flag == 4) System.out.println(println_String);
    }

    public int getFlag() {
        return flag;
    }
}
/*------------------------------------------------------*/
原文地址:https://www.cnblogs.com/lcsdsg/p/15810207.html