前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >基于Android的编译原理课程设计:C语言的预处理程序

基于Android的编译原理课程设计:C语言的预处理程序

作者头像
Cyril-KI
发布于 2022-09-19 06:12:21
发布于 2022-09-19 06:12:21
1.1K00
代码可运行
举报
文章被收录于专栏:KI的算法杂记KI的算法杂记
运行总次数:0
代码可运行

前言

考虑到大家最近在做编译原理课设,所以拿出来以供参考!

1.题目要求

设计一个 C 语言的预处理程序,将C语言中所有的宏常量进行计算,并生成另外一个文件,将宏常量展开和计算的结果全部显示出来,最后将定义的宏在源程序中全部进行替换。

例如,源程序为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#define  ADDR_START   0x20480000
#define  ADDR_A        ADDR_START + 0x04
#define  ADDR_B        ADDR_START + 15
#define  BUFFER_SIZE  1024
#define  BUFFER_END    ADDR_START + BUFFER_SIZE1
#define  PI      3.14
void main()
{
  float r, l;
  scanf(%f”, &r);
  l = 2 * PI *r;
  memset(ADDR_START, BUFFER_SIZE, 0x00);
}

替换后为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include <stdio.h>
#define  ADDR_START   0x20480000
#define  ADDR_A        0x20480004
#define  ADDR_B        0x2048000F
#define  BUFFER_SIZE  1024
#define  BUFFER_END   0x204803FF
#define  PI      3.14
void main()
{
  float r, l;
  scanf(%f”, &r);
  l = 2 * 3.14 *r;
  memset(0x20480000, 1024, 0x00);
}

2.思路分析

2.1 文法设计

我们知道,C 语言中运算符的优先级为:[] > (! ~) > (* / %) > (+ -) > (<< >>) > (> >= < <=) > (== !=) > & > ^ > | > && > || > ?: > (= += -= /= *= %=) > ,(逗号)。

为保证依据设计的文法求得的算符优先矩阵符合上述要求,根据求算符优先矩阵的方法,从优先级别最低的逗号开始逐次往高级别推导,这样算出来的算符优先矩阵就是符合预期的。

比如& < ==,则文法设计为:G->G&H,G->H,H->H==I。可以看到FirstVt(G) = {&, ==},FirstVt(H) = {==},而G->G&H,所以& < FirstVt(H),即& < ==。同理根据LastVt 可得== > &。

表达式文法设计过程中有以下几点需要特别考虑:

1. 推至结尾O时,为了将前后连贯起来,O必须能导出最开始的符号A,同时若A是表达式,则(A)也必然是表达式,于是最后两条产生式为:O->i,O->(A),文法中用i表征一切变量。

2. 下标运算符[]的设计。下标运算符在C语言中通常与数组结合起来,其标准用法为a[i],其中a为数组名,i为下标。在上述所有双目运算符中,其产生式都是类似于:A->A&&B这种形式,于是将[]运算符的产生式设计为:N->N[]O,其中N为数组名,O为数组下标。

3. 有了以上前提,在词法分析阶段,要将源程序中所有含有条件运算符以及下标运算符的表达式改写成上述产生式形式。

4. 经过设计,最终文法为:

2.2 表达式的计算

本次课设表达式的计算思路为:不使用属性文法计算,而是将原表达式转为逆波兰式,再进行计算。

2.3 概要设计

事先写好三个待分析的源程序文件,点击Open按钮,可选择打开哪一个源程序,打开后,会马上进行词法分析,得到各种有意义字符串的种别号,然后根据种别号对源程序设置不同的颜色,例如{}为红色,define以及include为粉红色等等(参考了vscode的CPP程序界面)。

接下来点击Lexical按钮,开始进行词法分析。词法分析实际上在源程序打开后就已经结束了,点击Lexical按钮只是做一个展示功能。

词法分析程序的主要任务是对构成源程序的字符串从左到右扫描,逐个字符地读入源程序字符并按照构词规则切分成一个一个具有独立意义的单词,并确定其属性(如关键字、宏常量、标识符等)。

词法分析中将单词分为以下几类:

1.关键字keyWord:由程序语言定义的具有固定意义的标识符,也称为保留字或基本字。如auto、short、typedef等。

2.宏常量MACRO:本次实验的主要目的就是分析宏常量,所以单独定义。

3.一般变量var:用来表示程序中各种名字的字符串。

4.常数number:常数的类型一般有整型、实型、布尔型、文字型。

5.运算符ope:如+、- 、*、/等。

6.界限符:如逗号、分号、括号等。

7.特殊字符special:C语言在语法上并未将main、include以及define等符号定义为关键字,所以单独列出。

词法分析得到的结果是一个初始符号表,每一个表项都是一个向量,每一个向量表示一个有意义的字符串,比如(SIZE, MACRO, X + Y),表明SIZE是一个宏常量,其表达式为X + Y。又如(+, 4)表明加法运算符的种别号为4。

接下来点击Grammar按钮,即可进行语法分析。语法分析首先分析的是宏常量的表达式,根据词法分析得到的符号表,找到每一个宏常量的表达式(可以是一个常数,也可以是一个很复杂的表达式),然后将每个表达式中的变量以及常数都用小写字母i替代,因为设计的文法当中默认用i表示操作数。例如SIZE + X / Y 变为i+i/i,然后用算符优先文法来规约这个表达式,并判断是否合法。

宏常量的表达式语法分析完毕后,紧接着分析主函数当中的表达式,对于主函数中的表达式,与宏常量表达式一样,也将除开运算符以外的所有变量用i表示,然后用上述定义的表达式文法进行规约分析。分析完毕后,所有的分析过程在点击Grammar按钮后都会显示在模拟器界面上。

语法分析结束后,最后进行的是表达式计算。点击Calculate按钮,即可对所有经过语法分析并且合法的表达式进行计算。计算时首先将表达式转成逆波兰式,然后利用栈对其进行计算。每计算完一个表达式,就将符号表进行更新,方便下一步的计算,所有表达式的计算过程都会显示在模拟器界面上。

表达式计算完毕之后,开始对源程序进行替换,替换过程与计算过程同步进行:扫描源程序,对宏常量以及相关表达式出现的地方,用计算得到的值进行替换,该值通过扫描符号表得到。替换完毕后,再根据结果变换程序字符串的颜色,显示在模拟器界面上。

3.系统的类图

系统中包含一个主界面MainActivity以及五个子类,分别介绍如下:

1. 主界面MainActivity:主界面中包含两个EditText以及一个RadioGroup,RadioGroup中包含四个RadioButton,分别对应打开文件、词法分析、语法分析以及表达式计算。

2. Grammatical_Analysis类:该类中定义了识别数字以及标识符的文法,其方法booleanisVar(String x)与boolean isNum(string x)分别来判断字符串是否是合法的标识符或者数字。

3. Lexical_Analysis类:词法分析类,该类中定义了所有可能出现的符号以及它们的类别号,并对源程序进行扫描,生成初始符号表。

4. Operator_Precedence类:算符优先分析类,该类中定义了表达式文法。findFirstVt()与findLastVt()用于求解所有非终结符的 FirstVt以及LastVt集合;findRe()根据两个集合建立算符优先矩阵;check(String x)对表达式x进行算符优先分析,并给出规约结果。

5. Compute类:计算类,根据Operator_Precedence类的分析结果,对表达式进行计算。其中:mid2suffix()方法将给出的表达式转成逆波兰式;hex2dec()将计算过程中可能出现的十六进制数转成十进制数;calculateSuffix()用于计算mid2suffix()产生的逆波兰式。

类图如下:

4.界面设计

4.1 主界面

4.2 打开文件

4.3 词法分析

点击词法分析后,编辑器上缩,下方的显示栏显示词法分析结果,如下所示:

4.4 语法分析

点击语法分析按钮,可对源程序中所有表达式进行语法分析,结果如下所示:

4.5 表达式计算

点击表达式计算按钮,可将计算过程显示出来。另外可以看到,源程序中相应位置的代码已经被替换。

5.部分源码

5.1 MainActivity

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * Date   : 2021/1/5 12:30
 * Author : KI
 * File   : MainActivity
 * Desc   : main
 * Motto  : Hungry And Humble
 */
package com.example.compiler;

import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.PopupWindow;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.example.compiler.Utils.CheckAllExpression;
import com.example.compiler.Utils.Compute;
import com.example.compiler.Utils.Lexical_Analysis;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Map;
import java.util.Vector;

public class MainActivity extends AppCompatActivity {

    private RadioGroup rg_tab_bar;
    private RadioButton rb_open;
    private RadioButton rb_lexer;
    private RadioButton rb_grammar;
    private RadioButton rb_calculate;
    private View div;
    private EditText editText;
    private EditText editTextComp;
    private Lexical_Analysis lexical_analysis;
    private PopupWindow popupWindow;
    public String resourceString = "";   //源程序
    public String tab = "";
    public Vector<Vector> resVectors = new Vector<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bindViews();
        rg_tab_bar.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                switch (checkedId) {
                    case R.id.rb_open:
                        rb_open.setOnClickListener(new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                View view=getLayoutInflater().inflate(R.layout.layout_pop,null);
                                TextView textView1 = view.findViewById(R.id.s1);
                                textView1.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        popupWindow.dismiss();
                                        resourceString = getResources().getString(R.string.source_1);
                                        //lexical_analysis.show();
                                        SpannableStringBuilder builder = convert(resourceString);
                                        editText.setText(builder);
                                    }
                                });
                                TextView textView2 = view.findViewById(R.id.s2);
                                textView2.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        popupWindow.dismiss();
                                        resourceString = getResources().getString(R.string.source_2);
                                        //lexical_analysis.show();
                                        SpannableStringBuilder builder = convert(resourceString);
                                        editText.setText(builder);
                                    }
                                });
                                TextView textView3 = view.findViewById(R.id.s3);
                                textView3.setOnClickListener(new View.OnClickListener() {
                                    @Override
                                    public void onClick(View v) {
                                        popupWindow.dismiss();
                                        resourceString = getResources().getString(R.string.source_3);
                                        SpannableStringBuilder builder = convert(resourceString);
                                        editText.setText(builder);
                                    }
                                });
                                popupWindow=new PopupWindow(view, rb_open.getWidth(), ViewGroup.LayoutParams.WRAP_CONTENT);
                                popupWindow.setOutsideTouchable(true);
                                popupWindow.setFocusable(true);
                                popupWindow.showAsDropDown(rb_open);
                            }
                        });
                        break;
                    case R.id.rb_lexer:    //词法分析
                        Lexical();
                        break;
                    case R.id.rb_grammar:    //语法分析每一个跟宏有关的式子是否是合法的
                        Grammar();
                        break;
                    case R.id.rb_calculate:    //计算并替换所有表达式
                        try {
                            Calculate();
                        } catch (FileNotFoundException e) {
                            e.printStackTrace();
                        }
                        break;
                }
            }
        });
    }

    private void bindViews() {
        tab = getResources().getString(R.string.tab);
        rg_tab_bar =  findViewById(R.id.rg_tab_bar);
        rb_open =  findViewById(R.id.rb_open);
        rb_lexer =  findViewById(R.id.rb_lexer);
        rb_grammar =  findViewById(R.id.rb_grammar);
        rb_calculate =  findViewById(R.id.rb_calculate);
        div = findViewById(R.id.div_tab_bar);
        editText = findViewById(R.id.edit);
        editTextComp = findViewById(R.id.comp);
    }

    private SpannableStringBuilder convert(String x) {
        String yy = getResources().getString(R.string.source_1);
        String []yyStrings = x.split("\n");
        for(int i = 0; i < yyStrings.length; i++) {
            if(yyStrings[i].contains("main")) {
                break;
            }
            else {
                yyStrings[i] = yyStrings[i].trim();
            }
        }
        x = "";
        for(int i = 0; i <yyStrings.length; i++) {
            x += (yyStrings[i] + "\n");
        }
        lexical_analysis = new Lexical_Analysis(yy);
        lexical_analysis.initNum();
        lexical_analysis.mainFunc();
        SpannableStringBuilder builder = new SpannableStringBuilder(x);
        for(int i = 0; i < x.length(); i++) {
            char y = x.charAt(i);
            if (y == '{' || y == '}' || y == '(' || y == ')') {
                builder.setSpan(new ForegroundColorSpan(Color.RED), i, i + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//指定索引a到b-1的字符
            }
            if (y == '#' && x.charAt(i + 1) == 'i') {
                builder.setSpan(new ForegroundColorSpan(Color.rgb(204, 51, 204)), i, i + 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//指定索引a到b-1的字符
                int j = i + 8;
                while (x.charAt(i) != '>') {
                    i++;
                }
                builder.setSpan(new ForegroundColorSpan(Color.rgb(153, 102, 113)), j + 1, i, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
            if (y == '#' && x.charAt(i + 1) == 'd') {
                builder.setSpan(new ForegroundColorSpan(Color.rgb(204, 51, 204)), i, i + 7, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

            }
        }
        for(String xString : lexical_analysis.keyWord) {
            int index = 0;
            while(index != -1) {
                index = x.indexOf(xString, index + xString.length());
                if(index != -1) {
                    builder.setSpan(new ForegroundColorSpan(Color.rgb(26, 107, 230)), index, index + xString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }
        for(String xString : lexical_analysis.keyWord) {
            int index = 0;
            while(index != -1) {
                index = x.indexOf(xString, index + xString.length());
                if(index != -1) {
                    builder.setSpan(new ForegroundColorSpan(Color.rgb(26, 107, 230)), index, index + xString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }
        int index1 = x.indexOf("main");
        builder.setSpan(new ForegroundColorSpan(Color.rgb(213, 213, 43)), index1, index1 + 4, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        for(String xString : lexical_analysis.function) {
            int index = x.indexOf(xString);
            if(index != -1) {
                builder.setSpan(new ForegroundColorSpan(Color.rgb(213, 213, 43)), index, index + xString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            }
        }
        //宏常量
        ArrayList<String> temp = new ArrayList<>();
        for(Vector<String> vector : lexical_analysis.resVector) {
            if(vector.get(1).equals("MACRO")) {
                temp.add(vector.get(0));
            }
        }
        System.out.println("temp = " + temp.size());
        for(String xString : temp) {
            int index = 0 - xString.length();
            while(index != -1) {
                index = x.indexOf(xString, index + xString.length());
                if(index != -1) {
                    builder.setSpan(new ForegroundColorSpan(Color.rgb(26, 107, 230)), index, index + xString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
                }
            }
        }
        return builder;
    }

    //词法分析
    private void Lexical() {
        lexical_analysis = new Lexical_Analysis(resourceString);
        lexical_analysis.initNum();
        lexical_analysis.mainFunc();
        String finalString = "";
        for(Vector vector : lexical_analysis.resVector) {
            //System.out.print("(");
            String temp = "(";
            for(int j = 0; j < vector.size() - 1; j++) {
                //System.out.print(vector.get(j) + "," + " ");
                temp += (vector.get(j) + "," + " ");
            }
            //System.out.println(vector.get(vector.size() - 1) + ")");
            temp += (vector.get(vector.size() - 1) + ")" + "\n");
            finalString += temp;
        }
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) editText.getLayoutParams();
        lp.height = 500;
        editText.setLayoutParams(lp);
        RelativeLayout.LayoutParams lp1 = (RelativeLayout.LayoutParams) editTextComp.getLayoutParams();
        lp1.height = 2000;
        editTextComp.setLayoutParams(lp1);
        finalString = "词法分析结果为:" + "\n" + finalString;
        SpannableStringBuilder builder1 = new SpannableStringBuilder(finalString);
        builder1.setSpan(new ForegroundColorSpan(Color.RED), 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//指定索引a到b-1的字符
        editTextComp.setText(builder1);
    }
    //语法分析
    private void Grammar() {
        CheckAllExpression checkAllExpression = new CheckAllExpression(resourceString, tab);
        checkAllExpression.checkMacro();
        checkAllExpression.checkMain();
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) editText.getLayoutParams();
        lp.height = 500;
        editText.setLayoutParams(lp);
        RelativeLayout.LayoutParams lp1 = (RelativeLayout.LayoutParams) editTextComp.getLayoutParams();
        lp1.height = 1800;
        editTextComp.setLayoutParams(lp1);
        String finalString = checkAllExpression.resString;
        finalString = "语法分析结果为:" + "\n" + finalString;
        SpannableStringBuilder builder1 = new SpannableStringBuilder(finalString);
        builder1.setSpan(new ForegroundColorSpan(Color.RED), 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);//指定索引a到b-1的字符
        editTextComp.setText(builder1);
    }

    private void Calculate() throws FileNotFoundException {
        lexical_analysis = new Lexical_Analysis(resourceString);
        lexical_analysis.initNum();
        lexical_analysis.mainFunc();
        resVectors = lexical_analysis.resVector;
        String showProcess = "";
        CheckAllExpression checkAllExpression = new CheckAllExpression(resourceString, "");
        checkAllExpression.checkMacro();
        checkAllExpression.checkMain();

        Map<String, String> expMap = checkAllExpression.expMap;  //存储表达式
        for(Map.Entry<String, String> entry : expMap.entrySet()) {
            String keyString = entry.getKey();
            String valueString = entry.getValue();
            //System.out.println(keyString + ":" + valueString);
            if(!keyString.equals("mainExp")) {
                String waitString = valueString.replace(" ", "");
                showProcess += ("正在计算的宏常量:" + keyString + "\n");
                showProcess += ("宏常量表达式:" + valueString + "\n");
                System.out.println("正在计算的宏常量:" + keyString);
                System.out.println("宏常量表达式:" + valueString);
                //System.out.println(waitString);
                waitString = Compute.hex2dec(waitString);
                //System.out.println(waitString);
                Compute compute = new Compute(waitString, resourceString);
                compute.lexical_Analysis.resVector = resVectors;
                String suffixString = compute.mid2suffix();
                showProcess += ("逆波兰式:" + suffixString + "\n");
                System.out.println("逆波兰式:" + suffixString);
                //System.out.println("suffix:" + suffixString);
                String resString = compute.calculateSuffix(suffixString);
                showProcess += compute.processString;
                showProcess += ("计算结果:" + resString + "\n" + "\n");
                System.out.println("计算结果:" + resString);
                System.out.println();
                for(int i = 0; i < resVectors.size(); i++) {
                    Vector<String> vector = resVectors.get(i);
                    if(vector.get(0).equals(keyString)) {
                        //System.out.println("当前被替换的宏常量为:" + keyString + " " + resString);
                        resVectors.get(i).set(2, resString);
                    }else {
                        continue;
                    }
                }
            }
        }

        //计算主函数中表达式
        System.out.println("计算主函数中表达式:");
        ArrayList<String> mainExpArrayList = checkAllExpression.mainExpArrayList;
        for(String valueString : mainExpArrayList) {
            if(valueString.contains("PI")) {
                continue;
            }
            String waitString = valueString.replace(" ", "");
            showProcess += ("正在计算的表达式:" + valueString + "\n");
            System.out.println("正在计算的表达式:" + valueString);
            //System.out.println(waitString);
            waitString = Compute.hex2dec(waitString);
            //System.out.println(waitString);
            Compute compute = new Compute(waitString, resourceString);
            compute.lexical_Analysis.resVector = resVectors;
            String suffixString = compute.mid2suffix();
            showProcess += ("逆波兰式:" + suffixString);
            System.out.println("逆波兰式:" + suffixString);
            //System.out.println("suffix:" + suffixString);
            String resString = compute.calculateSuffix(suffixString);
            showProcess += ("计算结果:" + resString + "\n" + "\n");
            System.out.println("计算结果:" + resString);
            System.out.println();
            for(int i = 0; i < resVectors.size(); i++) {
                Vector<String> vector = resVectors.get(i);
                if(waitString.contains(vector.get(0)) && vector.get(1).equals("var") || waitString.contains(vector.get(0)) && vector.get(1).equals("const")) {
                    //先找到resString中的答案
                    int index = resString.indexOf('=');
                    String real = resString.substring(index + 2, resString.length());
                    resVectors.get(i).add(real);
                    resVectors.get(i).set(1, "const");
                }
            }
        }

        //replace Macro
        for(int i = 0; i < resourceString.length(); i++) {
            if(resourceString.charAt(i) == '#' && i + 1 < resourceString.length() && resourceString.charAt(i + 1) == 'd') {
                //当前位置为#define
                i += 7;  //当前位置为e后面的空格
                while(resourceString.charAt(i) == ' ') {
                    i++;
                }//结束后位置为一个宏变量的开始符号
                int j = i;
                int k = i;
                while(resourceString.charAt(i) != ' ') {
                    i++;
                }//当前位置为变量后第一个空格
                String macroString = resourceString.substring(j, i);
                //System.out.println("待替换的变量为:" + macroString);
                String replaceString = "";
                for(Vector vector : resVectors) {
                    if(vector.get(0).equals(macroString)) {
                        replaceString = (String) vector.get(2);
                        //System.out.println(macroString + "替换为:" + replaceString);
                        break;
                    }
                }
                while(resourceString.charAt(i) == ' ') {
                    i++;
                }//当前结束为表达式第一个字符的位置
                j = i;
                while(resourceString.charAt(i) != '\n') {
                    i++;
                }
                StringBuilder builder = new StringBuilder(resourceString);
                builder.replace(j,  i, replaceString);
                resourceString = builder.toString();
                i = k;
                continue;
            }
        }

        int mainIndex = 0;
        for(int i = 0; i < resourceString.length(); i++) {
            if(resourceString.substring(i, i + 4).equals("main")) {
                mainIndex = i;
                break;
            }
        }

        String finalX = resourceString.substring(0, mainIndex);
        String finalY = resourceString.substring(mainIndex, resourceString.length());

        //替换主函数中的宏
        boolean flag = false;
        while(true) {
            flag = false;
            for(Vector vector : resVectors) {
                if(vector.get(1).equals("MACRO")) {
                    String macroString = (String) vector.get(0);
                    int index = finalY.indexOf(macroString);
                    if(index != -1) {
                        flag = true;
                        StringBuilder builder = new StringBuilder(finalY);
                        builder.replace(index, index + macroString.length(), (String) vector.get(2));
                        finalY = builder.toString();
                    }
                }
            }
            if(!flag) {
                break;
            }
        }

        //替换主函数中的表达式
        int index = 0;
        resourceString = finalX + finalY;
        String []subStrings = resourceString.split("\n");
        for(int i = 0; i < subStrings.length; i++) {
            if(subStrings[i].contains("define")) {
                continue;
            }
            if(subStrings[i].contains("=") && !subStrings[i].contains("3.14")) {
                int j = 0;
                //System.out.println("主函数中待替换: " + subStrings[i]);
                while (subStrings[i].charAt(j) == '\t' || subStrings[i].charAt(j) == ' ') {
                    j++;
                }//当前位置变量起始位置
                int k = j;
                while (subStrings[i].charAt(j) != ' ') {
                    j++;
                }//当前位置变量结束
                String varString = subStrings[i].substring(k, j);
                String replaceString = "";
                //search value
                for(Vector<String> vector : resVectors) {
                    if(vector.get(0).equals(varString)) {
                        replaceString = vector.get(2 + index++);
                        break;
                    }
                }
                subStrings[i] = subStrings[i].substring(0, k) + varString + " = " +
                        replaceString;
            }
        }
        resourceString = "";
        for(String xString : subStrings) {
            resourceString += (xString + "\n");
        }

        System.out.println("替换结束了");

        System.out.println(resourceString);
        RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) editText.getLayoutParams();
        lp.height = 1000;
        editText.setLayoutParams(lp);
        RelativeLayout.LayoutParams lp1 = (RelativeLayout.LayoutParams) editTextComp.getLayoutParams();
        lp1.height = 1300;
        editTextComp.setLayoutParams(lp1);
        SpannableStringBuilder builder = convert(resourceString);
        editText.setText(builder);
        editTextComp.setText(showProcess);
    }
}

5.2 表达式检验

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/**
 * Date   : 2021/1/5 12:30
 * Author : KI
 * File   : CheckAllExpression
 * Desc   : check expression
 * Motto  : Hungry And Humble
 */
package com.example.compiler.Utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Vector;

public class CheckAllExpression {
    public Map<String, String> expMap = new LinkedHashMap<String, String>();
    String tab = "";
    public String resString = "";
    public ArrayList<String> mainExpArrayList = new ArrayList<>();
    Lexical_Analysis lexical_Analysis;
    Grammatical_Analysis grammatical_Analysis;
    Operator_Precedence operator_Precedence;
    ArrayList<String> Vt = new ArrayList<String>(Arrays.asList(
            ",", "=", "+=", "-=", "*=", "/=", "%=", "||", "&&", "|", "^", "&", "=", "!=",
            ">", ">=", "<", "<=", "<<", ">>", "+", "-", "*", "/", "%",  "!", "[]",
            "(", ")", "i", "#"));   //规定一个顺序
    ArrayList<String> Vn = new ArrayList<String>(Arrays.asList(
            "S", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N"));
    String []proRule = {"S->#A#", "A->A,B", "A->B", "B->C=B", "B->C+=B",
            "B->C-=B", "B->C*=B", "B->C/=B", "B->C%=B", "B->C", "C->C||D", "C->D",
            "D->D&&E", "D->E", "E->E|F", "E->F", "F->F^G", "F->G", "G->G&H",
            "G->H", "H->H=I", "H->H!=I", "H->I", "I->I>J", "I->I>=J", "I->I<J",
            "I->I<=J", "I->J", "J->J<<K", "J->J>>K", "J->K", "K->K+L", "K->K-L",
            "K->L", "L->L*M", "L->L/M", "L->L%M", "L->M", "M->!M", "M->N", "N->N[]N",
            "N->(A)", "N->i"};
    String procedure = "";
    public CheckAllExpression(String procedure, String tab) {
        this.tab = tab;
        lexical_Analysis = new Lexical_Analysis(procedure);
        lexical_Analysis.initNum();
        lexical_Analysis.mainFunc();
        this.procedure = procedure;
        grammatical_Analysis = new Grammatical_Analysis();
        operator_Precedence = new Operator_Precedence(Vn, Vt, proRule, tab);
    }

    public String convert(String xString) {
        xString = xString.trim();
        String resString = "";
        for(int i = 0; i < xString.length(); i++) {
            char char1 = xString.charAt(i);
            if(char1 == '(') {
                xString = xString.substring(0, i + 1) + " " + xString.substring(i + 1, xString.length());
                i++;
            }
            if(char1 == ')') {
                xString = xString.substring(0, i) + " " + xString.substring(i, xString.length());
                i++;
            }
        }
        String list[] = xString.split(" ");
        for(String yString : list) {
            if(yString.equals("(") || yString.equals(")") || Vt.contains(yString)) {
                resString += yString;
            }else {
                resString += "i";
            }
        }
        return resString;
    }

    public boolean checkMacro() {
        //convert("(ADD_t + (FR * tt + 100))");
        //先检查所有宏表达式定义的
        boolean resFlag = true;
        String []lineStrings = procedure.split("\n");
        ArrayList<String> tempArrayList = new ArrayList<String>();
        for(int k = 0; k < lineStrings.length; k++) {
            String xString = lineStrings[k];
            if(!xString.contains("define")) {
                continue;
            }
            if(xString.contains("define") && k + 1 < lineStrings.length && !lineStrings[k + 1].contains("main")) {
                //说明为宏定义语句
                for(int i = 0; i < lexical_Analysis.resVector.size(); i++) {
                    Vector<String> vector = lexical_Analysis.resVector.get(i);
                    if(vector.get(1).equals("MACRO") && !tempArrayList.contains(vector.get(0))) {
                        tempArrayList.add(vector.get(0));
                        String waitString = vector.get(2);  //待分析的表达式
                        resString += ("待分析的宏常量:" + vector.get(0) + "\n");
                        resString += ("待分析的表达式:" + waitString + "\n");
                        System.out.println("待分析的宏常量:" + vector.get(0));
                        System.out.println("待分析的表达式:" + waitString);
                        expMap.put(vector.get(0), waitString);
                        waitString = convert(waitString);
                        resString += ("转换后:" + waitString + "\n");
                        System.out.println("转换后:" + waitString);
                        operator_Precedence.processString = "";
                        boolean flag = operator_Precedence.check(waitString);
                        resString += operator_Precedence.processString;
                        operator_Precedence.processString = "";
                        if(flag) {
                            resString += ("Successful!" + "\n" + "\n");
                            System.out.println("Successful!");
                            System.out.println();
                        }else {
                            resFlag = false;
                            resString += ("failed!" + "\n" + "\n");
                            System.out.println("failed!");
                            System.out.println();
                        }
                    }
                }
            }
        }
        return resFlag;
    }


    public boolean checkMain() {
        boolean resFlag = true;
        String []lineStrings = procedure.split("\n");
        flag:for(String xString : lineStrings) {
            if(xString.contains("define") || xString.contains("include") || xString.contains("main") || xString.contains("{") || xString.contains("}")) {
                continue;
            }
            for(String yString : lexical_Analysis.keyWord) {
                if(xString.contains(yString)) {
                    continue flag;
                }
            }
            for(String yString : lexical_Analysis.function) {
                if(xString.contains(yString)) {
                    continue flag;
                }
            }
            resString += ("待分析的句子:" + xString + "\n");
            System.out.println("待分析的句子:" + xString);
            mainExpArrayList.add(xString);
            xString = convert(xString);
            resString += ("转换后:" + xString + "\n");
            System.out.println("转换后:" + xString);
            operator_Precedence.processString = "";
            boolean flag = operator_Precedence.check(xString);
            resString += operator_Precedence.processString;
            operator_Precedence.processString = "";
            if(flag) {
                resString += ("Successful!" + "\n" + "\n");
                System.out.println("Successful!");
                System.out.println();
            }else {
                resString += ("failed!" + "\n" + "\n");
                resFlag = false;
                System.out.println("failed!");
                System.out.println();
            }
        }
        return resFlag;
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 KI的算法杂记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
在VMware中安装CentOS7(超详细的图文教程)
4、客户机操作选择“Linux”,版本选择“CentOS 7 64位”,点击下一步。
郑郑SunUp
2025/01/01
2.1K0
超详细的CentOS7.4下载与图文安装
链接:https://pan.baidu.com/s/1cRgNfZ5REf4LQMIyl5K3hQ 提取码:lp6q
全栈程序员站长
2022/08/10
6K0
超详细的CentOS7.4下载与图文安装
CentOS7安装详解
本文基于vmware workstations进行CentOS7安装过程展示,关于vmware workstations安装配置本人这里不再介绍,基本过程相当于windows下安装个软件而已。
hailang2zh
2019/08/29
1.4K0
CentOS7安装详解
Linux服务配置 DNS服务器配置「建议收藏」
DNS(Domain Name System):域名系统 用于IP和域名的解析 产生原因:上网需要IP,而IP不好记忆,用英文字母表示的域名便于记忆。
全栈程序员站长
2022/09/05
15.3K0
Linux虚拟化技术—CentOS7.4下KVM虚拟化一 安装配置及基本操作
目录 第一部分 实验环境 第二部分 安装图形界面 第三部分 配置KVM虚拟化 第四部分 创建桥接网卡 第五部分 KVM虚拟环境中安装系统 第六部分 克隆 第七部分 其它命令
拓荒者
2019/05/24
2.2K0
VMware 虚拟机外网连接问题排查
今天使用 VMware 搭建完一台 CentOS7 的 Linux 虚拟机后,发现不能够使用 CRT 远程链接。报错“The remote system refused the connection”。
JiekeXu之路
2022/05/17
1.8K0
VMware 虚拟机外网连接问题排查
CentOS7 配置外网静态ip
命令行承上继续输入,会看到如下文件ifcfg-ens33,这个文件名不固定,前缀固定ifcfg-*
六月的雨在Tencent
2024/03/28
2.5K0
CentOS7 配置外网静态ip
手把手教你安装Linux必备的VMware及CentOS7(保姆级教程)
        1.去VMware官网下载,链接VMware桌面虚拟机 官方中文版 软件下载 (bangtengxinxi.com),双击打开,点击下一步。
天寒雨落
2022/11/20
1.2K0
手把手教你安装Linux必备的VMware及CentOS7(保姆级教程)
虚拟机安装linux无法访问外网解决办法
有朋友反馈虚拟机安装Linux后,IP、网关、DNS都配置正确,但是系统使用外网,无法ping通百度,我研究了好久一步一步的操作下来找到了问题所在。 下面从虚拟机安装步骤开始介绍,顺便给想安装linux系统的朋友一个思路!
张旭博客
2022/12/27
6.1K0
虚拟机安装linux无法访问外网解决办法
【Zookeeper】基于3台linux虚拟机搭建zookeeper集群
http://mirrors.aliyun.com/centos/7.9.2009/isos/x86_64/
阿东
2023/06/27
1.2K0
【Zookeeper】基于3台linux虚拟机搭建zookeeper集群
Linux_异常_01_CentOS7无法ping 百度
当时设置的网关为:  GATEWAY=192.168.1.1    。是因为这个网关设置错了。这个网关的值要从虚拟机——编辑——虚拟网络编辑器下面去查看。如下图
shirayner
2018/08/10
6950
Linux_异常_01_CentOS7无法ping 百度
CentOS7中配置网络连接[通俗易懂]
刚在VMware安装好的CentOS7,默认安装是没有开启配置网卡信息的,所以连不上网。尝试用两种配置来让CentOS7开启联网功能,一种是直接打开网络功能自动获取ip,会在设定的网段下面随机分配一个ip,另一种是设置固定ip,出于某些特殊的需求,例如要在局域网内做端口映射,需要将虚拟机设置成使用固定的局域网IP,即使虚拟机重启了,其局域网ip仍然不变。
全栈程序员站长
2022/09/01
11.8K0
centos 7.0双网卡主备和负载均衡模式配置(bond0)
网卡bond是通过把多张网卡绑定为一个逻辑网卡,实现本地网卡的冗余,带宽扩容和负载均衡。在应用部署中是一种常用的技术,bond共有7中模式,mode 0-6,但是常用的模式有三种:
吾爱运维
2022/09/29
10.6K0
centos 7.0双网卡主备和负载均衡模式配置(bond0)
运维开发工程师教程之MongoDB单机版设置
在VMware Workstation软件中新建一个虚拟机,具体操作步骤如下:
张哥编程
2024/12/07
1390
运维开发工程师教程之MongoDB单机版设置
使用VMware安装centos7并配置网络
2.Centos7安装包(https://www.centos.org/download/)
全栈程序员站长
2022/09/06
1.3K0
使用VMware安装centos7并配置网络
Linux虚拟机无法联网问题解决
打开虚拟机,根据自己虚拟机所使用的网卡进行修改,默认一般为ifcfg-ens33 sudo vi /etc/sysconfig/network-scripts/ifcfg-ens33
用户1483438
2021/11/16
2.2K0
Hadoop基础教程-第1章 环境安装配置(1.2 安装Linux虚拟机)
1)打开CentOS官网,进入下载页面https://www.centos.org/download/
程裕强
2022/05/06
8580
Hadoop基础教程-第1章 环境安装配置(1.2 安装Linux虚拟机)
Python爬虫入门教程 1-100 CentOS环境安装
你好,当你打开这个文档的时候,我知道,你想要的是什么! Python爬虫,如何快速的学会Python爬虫,是你最期待的事情,可是这个事情应该没有想象中的那么容易,况且你的编程底子还不一定好,这套课程,没有你想要的Python基础,没有变量,循环,数组等基础知识,因为我不想在那些你可以直接快速学会的地方,去浪费你的时间。
梦想橡皮擦
2019/01/21
1.2K0
Python爬虫入门教程 1-100 CentOS环境安装
VMware14安装CentOS7的详细教程
本篇文章主要介绍了VMware安装Centos7超详细过程(图文),具有一定的参考价值,感兴趣的小伙伴们可以参考一下
Lansonli
2021/10/09
5360
Centos7安装并配置多网口
文章链接:https://www.mobaijun.com/posts/1316700149.html
框架师
2021/08/05
2.2K0
推荐阅读
相关推荐
在VMware中安装CentOS7(超详细的图文教程)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档