精华内容
下载资源
问答
  • 设计一个编译器的基本思路

    千次阅读 2012-03-28 14:28:52
    1.明确目标语言的语法 2.根据语法写出相应的词法分析程序,也可以用工具 LEX 生成 3.消除左递归文法,编写LL0下推自动机 4.根据自动机产生的语法树生成目标代码 5.目标代码优化 ...目标代码就是按

    1.明确目标语言的语法

    2.根据语法写出相应的词法分析程序,也可以用工具 LEX 生成

    3.消除左递归文法,编写LL0下推自动机

    4.根据自动机产生的语法树生成目标代码

    5.目标代码优化


    其中:

    词法分析使用有状态自动机,遍历状态矩阵


    语法分析使用LL0下推自动机,具体我也不懂


    语法树完全不懂……但是貌似生成的时候要参考符号的优先级


    目标代码就是按照语法树下推就行了

    展开全文
  • 编译原理课设作业,java实现,附上实验报告以及答辩ppt 实现词法分析,语法分析,语义分析
  • 英文出处:Wilfred Hughes:Baby Steps to a C Compiler动手编写一个编译器,学习一下较为底层的编程方式,是一种学习计算机到底是如何工作的非常有效方法。编译器通常被看作是十分复杂的工程。事实上,编写一个产品...

    英文出处:Wilfred Hughes:Baby Steps to a C Compiler


    动手编写一个编译器,学习一下较为底层的编程方式,是一种学习计算机到底是如何工作的非常有效方法。

    编译器通常被看作是十分复杂的工程。事实上,编写一个产品级的编译器也确实是一个庞大的任务。但是写一个小巧可用的编译器却不是这么困难。

    秘诀就是首先去找到一个最小的可用工程,然后把你想要的特性添加进去。这个方法也是Abdulaziz Ghuloum在他那篇著名的论文“一种构造编译器的捷径”里所提到的办法。不过这个办法确实可行。你只需要按照这篇论文中的第一步来操作,就可以得到一个真正可用的编译器!当然,它只能编译程序语言中的非常小的子集,但是它确实是一个真实可用的编译器。你可以随意的扩展这个编译器,然后从中学到更多更深的知识。

    受到这篇文章的鼓舞,我就写了一个C编译器。从某种意义上来说这比写一个scheme的编译器要困难一些(因为你必须去解析C那复杂的语法),但是在某些方面又很便利(你不需要去处理运行时类型)。要写这样一个编译器,你只需要从你那个可用的最小的编译器开始。

    对于我写的编译器来说,我把它叫 babyc,我选了这段代码来作为我需要运行的第一个程序:

    int main() {
        return 2;
    }
    没有变量,没有函数调用,没有额外的依赖,甚至连if语句,循环语句都没有,一切看起来是那么简单。

    我们首先需要解析这段代码。我们将使用 Flex 和 Bison 来做到这点。这里有怎么用的例子可以参考,幸好我们的语法是如此简单,下面就是词法分析器:

    "{" { return '{'; }
    "}" { return '}'; }
    "(" { return '('; }
    ")" { return ')'; }
    ";" { return ';'; }
    [0-9]+ { return NUMBER; }
    "return" { return RETURN; }
    "int" { return TYPE; }
    "main" { return IDENTIFIER; }
    这里是语法分析器:

    function:
    	TYPE IDENTIFIER '(' ')' '{' expression '}'
    	;
        
    expression:
    	RETURN NUMBER ';'
    	;
    最终,我们需要生成一些汇编代码。我们将使用32位的X86汇编,因为它非常的通用而且可以很容易的运行在你的机器上。这里有X86汇编的相关网站

    下面就是我们需要生成的汇编代码:

    .text
            .global _start # Tell the loader we want to start at _start.
    
    _start:
            movl    $2,%ebx # The argument to our system call.
            movl    $1,%eax # The system call number of sys_exit is 1.
            int     $0x80 # Send an interrupt
    然后加上上面的词法语法分析代码,把这段汇编代码写进一个文件里。恭喜你!你已经是一个编译器的编写者了!

    Babyc 就是这样诞生的,你可以在这里看到它最开始的样子

    当然,如果汇编代码没办法运行也是枉然。让我们来用编译器生成我们所希望的真正的汇编代码。

    # Here's the file we want to compile.
    $ cat return_two.c
    #include <stdio.h>
    
    int main() {
        return 2;
    }
    
    # Run the compiler with this file.
    $ ./babyc return_two.c
    Written out.s.
    
    # Check the output looks sensible.
    $ cat out.s
    .text
        .global _start
    
    _start:
        movl    $2, %ebx
        movl    $1, %eax
        int     $0x80
    非常棒!接着让我们来真正的运行一下编译之后代码来确保它能得到我们所想的结果。

    # Assemble the file. We explicitly assemble as 32-bit
    # to avoid confusion on x86_64 machines.
    $ as out.s -o out.o --32
    
    # Link the file, again specifying 32-bit.
    $ ld -m elf_i386 -s -o out out.o
    
    # Run it!
    $ ./out
    
    # What was the return code?
    $ echo $?
    2 # Woohoo!
    我们踏出了第一步,接下去怎么做就全看你了。你可以按照那篇文章所指导的全部做一遍,然后制作一个更加复杂的编译器。你需要去写一个更加精巧的语法树来生成汇编代码。接下去的几步分别是:(1)允许返回任意的值(比如,return 3; 一些可执行代码);(2)添加对“非”的支持(比如,return ~1; 一些可执行代码)。每一个额外的特性都可以教你关于C语言的更多知识,编译器到底是怎么执行的,以及世界上其他编写编译器的人是如何想的。

    这是构建 babyc 的方法。Babyc 现在已经拥有了if语句,循环,变量以及最基础的数据结构。欢迎你来check out它的代码,但是我希望看完我的文章你能够自己动手写一个。

    不要害怕底层的一些事情。这是一个非常奇妙的世界。



    关于程序设计基石与实践更多讨论与交流,敬请关注本博客和新浪微博songzi_tea.


    展开全文
  • 一个小型编译器

    千次阅读 2005-11-25 23:57:00
    最近心血来潮写了一个小型编译器,同时设计了一种小型的高级语言,支持字符型和整型两种变量类型,支持函数,支持条件语句,循环语句等某些高级语言共有的特性;并设计了一种简单的汇编语言,编译器通过扫描源文件,...
            最近心血来潮写了一个小型编译器,同时设计了一种小型的高级语言,支持字符型和整型两种变量类型,支持函数,支持条件语句,循环语句等某些高级语言共有的特性;并设计了一种简单的汇编语言,编译器通过扫描源文件,产生这种相应的汇编代码。最后虚拟机执行这种中间代码,显示程序运行结果。 因为自己的底子本来就不好,加之是第一次写没什么经验,编译器和虚拟机的缺陷很多,代码也写得不好。例如,支持的语言特性不够丰富,对变量的嵌套作用域(符号表)的处理太粗略,产生的中间代码没有优化,虚拟机对于内存申请的操作不够细化,等等。 编译器和虚拟机用标准c++写,在vc6和gcc编译通过。对这方面话题有兴趣的朋友可以来信交流相关技术。我的邮箱:shadow_1331_zyw@163.com
            另注:此前曾有朋友向本人索取源代码,本人如其所愿,但这些朋友连最起码的谢谢也不会,更别提交流,因此本人很失望。本人希望真诚的交流,而不是单纯的来信索取。如果我们都是热爱编译器这份技术,我仍然期待你的来信。
            如果单纯是为了完成编译原理的课程设计,那么你要问问你自己,当初有没有认真去学。这种情况我是不会发送源代码的,请自重。
    展开全文
  • C#开发一个小型编译器

    万次阅读 2015-01-22 12:36:50
    设计任务为开发一个小型编译器,主要包括4个部件:词法分析器、语法分析器、语义分析器、目标代码生成器。 一、课程设计的目的与要求 1.通过设计、编写和调试词法分析程序,了解词法扫描器的组成结构、不同种类单词...
    设计任务为开发一个小型编译器,主要包括4个部件:词法分析器、语法分析器、语义分析器、目标代码生成器。

    一、课程设计的目的与要求
    1.通过设计、编写和调试词法分析程序,了解词法扫描器的组成结构、不同种类单词的识别方法,掌握由单词的词法规则出发,通过识别单词的状态转换图、利用程序实现词法扫描器的方法。
    1.1扫描器设计
    该扫描器是一个子程序,其输入是源程序字符串,每调用一次输出一个单词符号。为了避免超前搜索,提高运行效率,简化扫描器的设计,假设程序设计语言中,基本字不能用作一般标识符,如果基本字、标识符和常数之间没有确定的运算符或界符作间隔,则用空白作间隔。
    2.通过设计、编写和调试语法分析程序,了解语法分析器的组成结构以及对文法的要求,掌握基于LL(1)文法或算符优先文法的语法分析程序的实现方法。
    2.1语法分析器设计
    以算法优先分析方法为例,设计一个算符优先语法分析程序。算符优先分析属于自下而上的分析方法,该语法分析程序的输入是终结符号串(即单词符号串,以一个“#”结尾),如果输入串是句子则输出“YES”,否则输出“NO”和错误信息。当然,也可采用预测分析等方法设计语法分析器,具体方法自定。
    3.通过设计、编写和调试语法制导翻译程序,掌握从语句的语法出发,构造相应的语义子程序,实现自定义语言的语法制导翻译。
    3.1语法制导翻译程序设计
    采用语法制导翻译方法,实现算术表达式、赋值语句和基本控制语句等的翻译。本语法制导翻译程序的输入是终结符号串(即单词符号串,以一个“#”结尾),如果输入符号串是句子,则按照其语义进行翻译,输出等价的四元式序列。
    4.目标代码生成器设计,将程序设计语言的中间代码程序翻译为目标代码程序,其输入是四元式序列,输出是一个汇编代码文件。
    二、设计(实验)正文
    1. 词法分析器设计
    1.1 单词符号表



    1.2 可实现的功能
    1) 输入:字符串(待进行词法分析的源程序);
    输出:一个单词序列文件(即:token文件)和一个符号表文件,并输出错误信息。
    显示为(种别码,自身值)格式的二元式。
    2) 功能:
    a. 过滤空格、回车、换行符等无用字符
    b. 识别保留字并转换成种别码
    c. 识别标识符
    d. 识别界符
    3) 检查如下错误:
    a. 程序语言的字符集以外的非法字符
    b. 单词拼错,如可识别标识符开头为数字的拼写错误
    1.3 基本流程
    首先判断输入的字符是否为0-9或a-z或A-Z,再判断输入的字符串中是否含关键字,若不是关键字则判断是否为整型常数。当出现* / + - = ; ( ) #停止并直接输出,当出现< > :时需判断该符号后是否有其他符号组成<> 、<= 、>=、 := ,若组成这些符号则停止并输出这些符号的种别码,否则直接输出< > :的种别码。当回车时换行,若遇到无法识别的字符则输出错误信息。
    2. 递归下降分析程序设计
    2.1 设置递归下降文法
    程序定义:
    〈程序〉→ program〈标识符〉〈程序体〉.
    〈程序体〉→〈变量说明〉〈复合句〉
    变量定义:
    〈变量说明〉→ var〈变量定义〉|ε
    〈变量定义〉→〈标识符表〉:〈类型〉;|〈标识符表〉:〈类型〉;〈变量定义〉
    〈标识符表〉→〈标识符〉,〈标识符表〉|〈标识符〉
    语句定义:
    〈复合句〉→ begin〈语句表〉end
    〈语句表〉→〈执行句〉;〈语句表〉|〈执行句〉
    〈执行句〉→〈简单句〉|〈结构句〉
    〈简单句〉→〈赋值句〉
    〈赋值句〉→〈变量〉:=〈表达式〉
    〈变量〉→〈标识符〉
    〈结构句〉→〈复合句〉|〈if句〉|〈WHILE句〉
    〈if句〉→ if〈布尔表达式〉then〈执行句〉| if〈布尔表达式〉then〈执行句〉else〈执行句〉
    〈while句〉→ while〈布尔表达式〉do〈执行句〉
    表达式定义:
    〈表达式〉→〈算术表达式〉|〈布尔表达式〉
    〈算术表达式〉→〈算术表达式〉+〈项〉|〈算术表达式〉-〈项〉|〈项〉
    〈项〉→〈项〉*〈因子〉|〈项〉/〈因子〉|〈因子〉
    〈因子〉→〈算术量〉|(〈算术表达式〉)
    〈算术量〉→〈标识符〉|〈整数〉|〈实数〉
    〈布尔表达式〉→〈布尔表达式〉or〈布尔项〉|〈布尔项〉
    〈布尔项〉→〈布尔项〉and〈布尔因子〉|〈布尔因子〉
    〈布尔因子〉→ not〈布尔因子〉|〈布尔量〉
    〈布尔量〉→〈布尔常数〉|〈标识符〉|(〈布尔表达式〉)|〈关系表达式〉
    〈关系表达式〉→〈标识符〉〈关系运算符〉〈标识符〉
    〈关系运算符〉→〈|〈= | =| 〉=| 〉|〈〉
    类型定义:
    〈类型名〉→ integer|bool | real
    单词定义:
    〈标识符〉→〈字母〉|〈标识符〉〈字母〉|〈标识符〉〈数字〉
    〈整数〉→〈数字〉|〈整数〉〈数字〉
    〈实数〉→〈整数〉.|〈实数〉〈数字〉
    〈布尔常数〉→ true|false
    字符定义:
    〈字母〉→ A│B│C│D│E│F│G│H│I│J│K│L│M│N│O│P│Q│R│S│T│
    U│V│W│X│Y│Z│a│b│c│d│e│f│g│h│i│j│k│l│m│n│o│
    p│q│r│s│t│u│v│w│x│y│z
    〈数字〉→ 0│1│2│3│4│5│6│7│8│9
    2.2 可实现的功能
    程序输入窗口输入字符串,然后进行递归下降分析,分析过程中如有错误,则终止程序并报告错误原因。若输入串合法则显示正确,若不合法则显示错误信息。
    2.3 基本流程
    输入一段程序,首先检索第一个单词是否为program,如果是则检索下一个单词是否是标识符,否则输出错误信息:该程序缺少关键字:program;如果下一个单词是标识符,则进行程序体的检索,否则输出错误信息:该程序program缺少方法名;如此依照递归下降的方法,逐步自上而下的判断语法是否符合制定的语义规则。当所有检索结束,无错误时即输出“正确”。
    2.4 实验难点
    算符优先分析方法只能分析类似于算数表达式这样结构的语句,但本实验采用递归下降方法,包括了整个程序的分析过程,这其中较困难的是解决算数表达式和逻辑表达式的结合性问题,解决方案是将表达式细分为因子、项等逻辑单位来确定优先性。
    3. 语法制导翻译程序设计
    3.1 设计流程


    3.2 可实现的功能
    输入:token文件、符号表文件,其数据结构与词法分析产生的文件相同。
    输出:四元式序列文件,其纪录结构:(操作,做操作数,右操作数,结果)
    3.3 实验内容
    该程序的设计是在语法分析的程序的基础之上添加了输出四元式的功能。
    4. 目标代码生成
    4.1 设计流程





    4.2 数据结构
    输入:四元式序列文件和符号表文件,其结构与语法/语义分析程序的输出一致。
    输出:一个汇编代码文件,并无特殊数据结构。

    三、课程设计(综合实验)总结或结论
    本次实验达到了实验目的,成功的实现了词法分析器、语法语义分析器的功能,能够对一段简单的L语言程序代码进行词法、语法、语义分析,能够正确的输出单词的种别码,能够判断代码是否符合语法规则,若不符合能报出相应错误信息,能对代码进行语义的翻译,显示出等价的四元式。
    通过这次实验,我的学习能力得到了很好的锻炼。三个实验的内容都是课堂上学习的,但理论知识和实践不能划等号,能够做出作业题并不代表能做出一个初具功能的编译器,需要熟练的掌握编译知识。
    通过这次实验,我还有了意外的收获,初步学习了一门新的高级程序设计语言C#,熟悉了在.NET环境下的编程,实现了WEB版编译器。C#作为典型的面向对象的语言,在语法上和C++确实有很大不同,但整个功能实现的思路是差不多的。
    以下是各部分实验中的心得和遇到的问题:
    1.词法分析器设计
    此次实验加深了对课堂教学内容的理解,培养了解决实际问题能力。通过这个实验,使我能应用编译程序设计的原理和技术设计出词法分析器,了解扫描器的组成结构,不同种类单词的识别方法,学会判断一个字符串是数字、字母、关键字,学会了超前搜索。
    2.递归下降程序设计
    此次实验加深了对课堂教学内容的理解,培养了解决实际问题能力。通过这个实验,使我能应用编译程序设计的原理和技术, 设计、编写和调试递归下降分析程序,了解递归下降分析程序的组成结构,掌握实现通用递归下降分析算法的方法,能够分析出一段程序代码是否符合规定语法,如果不符合能够显示错误原因。
    3.基于递归下降分析的语法制导翻译设计
    此次实验加深对了课堂教学内容的理解,培养了解决实际问题能力。通过这个实验,使我能应用编译程序设计的原理和技术, 通过设计、编写和调试语法制导翻译程序,掌握从一种语句的语法和语义出发,构造相应的语义子程序,实现基于算符优先分析方法的语法制导翻译的方法,能够正确的输出等价的四元式。

    运行结果:





    具体的实现过程:


    主要的几个类:

    Morophology.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace 编译
    {
        public class Morphology
        {
            string[] machineCodes = new string[38];
            public List<token> tokens = new List<token>();
            public List<symble> symbles = new List<symble>();
            public List<Error> errors = new List<Error>();
            string input;
            int i = 0;
            int rowNum = 1;
    
            public Morphology(string s)//传入字符串
            {
                input = s + " ";
                NewKeyWord();//定义机内码
                Dispose();//主程序
            }
    
            #region 定义机内码
            private void NewKeyWord()
            {
                machineCodes[0] = "";
                machineCodes[1] = "and";
                machineCodes[2] = "begin";
                machineCodes[3] = "bool";
                machineCodes[4] = "do";
                machineCodes[5] = "else";
                machineCodes[6] = "end";
                machineCodes[7] = "false";
                machineCodes[8] = "if";
                machineCodes[9] = "integer";
                machineCodes[10] = "not";
                machineCodes[11] = "or";
                machineCodes[12] = "program";
                machineCodes[13] = "real";
                machineCodes[14] = "then";
                machineCodes[15] = "true";
                machineCodes[16] = "var";
                machineCodes[17] = "while";
                machineCodes[18] = "标志符";
                machineCodes[19] = "整数";
                machineCodes[20] = "实数";
                machineCodes[21] = "(";
                machineCodes[22] = ")";
                machineCodes[23] = "+";
                machineCodes[24] = "-";
                machineCodes[25] = "*";
                machineCodes[26] = "/";
                machineCodes[27] = ".";
                machineCodes[28] = ",";
                machineCodes[29] = ":";
                machineCodes[30] = ";";
                machineCodes[31] = ":=";
                machineCodes[32] = "=";
                machineCodes[33] = "<=";
                machineCodes[34] = "<";
                machineCodes[35] = "<>";
                machineCodes[36] = ">";
                machineCodes[37] = ">=";
            }
            #endregion
    
            #region 处理输入的代码
            public void Dispose()
            {
                while (i < input.Length)//只要不超出字符串长度就继续执行
                {
                    if (IsAlpha(input[i]))
                    {
                        RecogId();
                    }
                    else if (IsDight(input[i]))
                    {
                        RecogCons();
                    }
                    else if (input[i] == '/')
                    {
                        i++;
                        if (input[i] == '/')
                        {
                            while (input[i] != '\r' && i < input.Length)
                            {
                                i++;
                            }
                        }
                        else
                        {
                            i--;
                        }
                    }
                    else if (input[i] == '\r' && input[i + 1] == '\n')
                    {
                        rowNum++;
                        i++;
                        i++;
                    }
                    else if (IsDelimiter(input[i]))
                    {
                        RecogSym();
                    }
                    else if (input[i] == ' ')
                    {
                        i++;
                    }
                    else
                    {
                        Error e = new Error(rowNum, input[i].ToString(), "(1)非法字符");
                        errors.Add(e);
                        i++;
                    }
    
                }
            } 
            #endregion
    
            #region 判断是标识符还是关键字并处理
            private void RecogId()
            {
                string str = "";
                int code;
                do
                {
                    str = str + input[i];
                    i++;
                } while (IsAlpha(input[i]) || IsDight(input[i]));//判断是不是字母或数字,是的话继续执行
                code = Reserve(str);
                token t = new token();//存入token文件
                t.Label = tokens.Count;
                t.Name = str;
                if (code == 0)
                {
                    t.Code = 18;
                    t.Addr = symbles.Count;
                    symble s = new symble();//存入符号表
                    s.Number = t.Addr;
                    s.Name = str;
                    s.Type = 18;
                    symbles.Add(s);
                }
                else
                {
                    t.Code = code;
                    t.Addr = -1;
                }
                tokens.Add(t);
            }
            #endregion
    
            #region 判断是不是常数并处理
            private void RecogCons()
            {
                string str = input[i].ToString();
                bool flag = true;
                bool point = true;
                while (flag)
                {
                    i++;
                    if (IsDight(input[i]))
                    {
                        str += input[i];
                    }
                    else if (input[i] == '.')
                    {
                        if (point)
                        {
                            str += input[i];
                            point = false;
                        }
                        else
                        {
                            Error e = new Error(rowNum, str, "出现第二个'.'号");
                            errors.Add(e);
                            flag = false;
                        }
                    }
                    else if (IsAlpha(input[i]))
                    {
                        i++;
                        if (IsDight(input[i]))
                        {
                            i--;
                            i--;
                            if (point)
                            {
                                Error e = new Error(rowNum, str, "数字开头的数字、字母串");
                                errors.Add(e);
                            }
                            else
                            {
                                Error e = new Error(rowNum, str, "实数的小数部分出现字母");
                                errors.Add(e);
                            }
                        }
                    }
                    else 
                    {
                        flag = false;
                    }
                }
                if (point)
                {
                    token t = new token();
                    t.Label = tokens.Count;
                    t.Name = str;
                    t.Code = 19;
                    t.Addr = symbles.Count;
                    symble s = new symble();
                    s.Number = t.Addr;
                    s.Name = str;
                    s.Type = 19;
                    symbles.Add(s);
                    tokens.Add(t);
                }
                else
                {
                    token t = new token();
                    t.Label = tokens.Count;
                    t.Name = str;
                    t.Code = 20;
                    t.Addr = symbles.Count;
                    symble s = new symble();
                    s.Number = t.Addr;
                    s.Name = str;
                    s.Type = 20;
                    symbles.Add(s);
                    tokens.Add(t);
                }
            }
            #endregion
    
            #region 判断是否是符号并处理
            private void RecogSym()
            {
                string str = "" + input[i];
                if (str == ":" || str == "<" || str == ">")
                {
                    i++;
                    if (input[i] == '=')
                    {
                        str += input[i];
                    }
                    else if (input[i] == '>' && str == "<")
                    {
                        str += input[i];
                    }
                    else
                    {
                        i--;
                    }
                }
                for (int j = 21; j <= 37; j++)
                {
                    if (str == machineCodes[j])
                    {
                        token t = new token();
                        t.Label = tokens.Count;
                        t.Name = str;
                        t.Code = j;
                        t.Addr = -1;
                        tokens.Add(t);
                        i++;
                    }
                }
    
    
    
            }
            #endregion
    
            #region 判断是不是字母
            private bool IsAlpha(char c)
            {
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            #endregion
    
            #region 判断是不是数字
            private bool IsDight(char c)
            {
                if (c >= '0' && c <= '9')
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            #endregion
    
            #region 判断是不是其他界符
            private bool IsDelimiter(char c)
            {
            
                switch (c)
                {
                    case '(':  return true;
                    case ')':  return true;
                    case '+':  return true;
                    case '-':  return true;
                    case '*':  return true;
                    case '.':  return true;
                    case ',':  return true;
                    case ':':  return true;
                    case ';':  return true;
                    case '=':  return true;
                    case '<':  return true;
                    case '>':  return true;
                    default: return false;
                }
            }
            #endregion
    
            #region 匹配机内码
            private int Reserve(string str)
            {
                for (int i = 1; i <= 17; i++)
                {
                    
                    if (str == machineCodes[i])
                    {
                        return i;//返回机内码编号
                    }
                }
                return 0;//标识符
            } 
            #endregion
        }
    }
    Grammar.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace 编译
    {
        public class Grammar
        {
            List<token> tokens;
            List<symble> symbles;
            public string error = "";
            int i = 0;
            public Grammar(Morphology m)
            {
                tokens = m.tokens;
                symbles = m.symbles;
                Dispose();
            }
    
            private void Next()
            {
                if (i < tokens.Count - 1)
                {
                    i++;
                }
            }
    
            private void Before()
            {
                if (i > 0)
                {
                    i--;
                }
            }
    
            #region 主要函数
            private void Dispose()
            {
                if (tokens[i].Code == 12)//含有program
                {
                    Next();
                    if (tokens[i].Code == 18)//是标识符
                    {
                        //执行程序体
                        Next();
                        ProBody();
                    }
                    else
                    {
                        error = "该程序program缺少方法名";
                    }
                }
                else
                {
                    error = "该程序缺少关键字:program";
                }
            }
            #endregion
    
            #region 程序体
            private void ProBody()
            {
                if (tokens[i].Code == 16)//判断var
                {
                    Next();
                    VarDef();
                }
                else if (tokens[i].Code == 2)//判断begin
                {
                    Next();
                    ComSent();
                }
                else
                {
                    error = "程序体缺少var或begin";
                }
            }
            #endregion
    
            #region 变量定义
            private void VarDef()
            {
                if (IsIdlist())
                {
                    Next();
                    if (tokens[i].Code == 29)//:
                    {
                        Next();
                        if (tokens[i].Code == 9 || tokens[i].Code == 3 || tokens[i].Code == 13)//integer,bool,real
                        {
                            int j = i;
                            j = j - 2;
                            symbles[tokens[j].Addr].Type = tokens[i].Code;
                            j--;
                            while (tokens[j].Code == 28)
                            {
                                j--;
                                symbles[tokens[j].Addr].Type = tokens[i].Code;
                            }
                            Next();
                            if (tokens[i].Code == 30)
                            {
                                Next();
                                if (tokens[i].Code == 2)
                                {
                                    Next();
                                    ComSent();
                                }
                                else
                                {
                                    VarDef();
                                }
                            }
                            else
                            {
                                error = "变量定义后面缺少;";
                            }
                        }
                        else
                        {
                            error = "变量定义缺少类型或类型定义错误";
                            return;
                        }
                    }
                    else
                    {
                        error = "var后面缺少冒号";
                    }
                }
                else
                {
                    error = "变量定义标识符出错";
                }
            }
            #endregion
    
            #region 判断是不是标识符表
            private bool IsIdlist()
            {
                if (tokens[i].Code == 18)
                {
                    Next();
                    if (tokens[i].Code == 28)//,
                    {
                        Next();
                        return IsIdlist();
                    }
                    else
                    {
                        Before();
                        return true;
                    }
                }
                else
                {
                    return false;
                }
            }
            #endregion
    
            #region 复合句
            private void ComSent()
            {
                SentList();
                if (error == "")
                {
                    if (tokens[i].Code == 6)
                    {
                        return;
                    }
                    else
                    {
                        error = "复合句末尾缺少end";
                    }
                }
            }
            #endregion
    
            #region 语句表
            private void SentList()
            {
                ExecSent();
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 30)
                    {
                        Next();
                        SentList();
                    }
                }
            }
            #endregion
    
            #region 执行句
            private void ExecSent()
            {
                if (tokens[i].Code == 18)
                {
                    Next();
                    AssiSent();
                }
                else if (tokens[i].Code == 2 || tokens[i].Code == 8 || tokens[i].Code == 17)
                {
                    StructSent();
                }
                else
                {
                    Before();
                }
            }
            #endregion
    
            #region 赋值句
            private void AssiSent()
            {
                if (tokens[i].Code == 31)//:=
                {
                    Next();
                    Expression();
                }
                else
                {
                    error = "赋值句变量后缺少:=";
                }
            }
            #endregion
    
            #region 表达式
            private void Expression()
            {
                if (tokens[i].Code == 7 || tokens[i].Code == 15 || (tokens[i].Addr != -1 && symbles[tokens[i].Addr].Type == 3))
                {
                    BoolExp();
                }
                else
                {
                    AritExp();
                }
            }
            #endregion
    
            #region 布尔表达式
            private void BoolExp()
            {
                BoolItem();
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 11)
                    {
                        Next();
                        BoolExp();
                    }
                    else
                    {
                        Before();
                    }
                }
                else
                {
                    return;
                }
            }
            #endregion
    
            #region 布尔项
            private void BoolItem()
            {
                BoolFactor();
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 1)
                    {
                        Next();
                        BoolItem();
                    }
                    else
                    {
                        Before();
                    }
                }
            }
            #endregion
    
            #region 布尔因子
            private void BoolFactor()
            {
                if (tokens[i].Code == 10)
                {
                    Next();
                    BoolFactor();
                }
                else
                {
                    BoolValue();
                }
            }
            #endregion
    
            #region 布尔量
            private void BoolValue()
            {
                if (tokens[i].Code == 15 || tokens[i].Code == 7)
                {
                    return;
                }
                else if (tokens[i].Code == 18)
                {
                    Next();
                    if (tokens[i].Code == 34 || tokens[i].Code == 33 || tokens[i].Code == 32 || tokens[i].Code == 37 || tokens[i].Code == 36 || tokens[i].Code == 35)
                    {
                        Next();
                        if (tokens[i].Code == 18)
                        {
                        }
                        else
                        {
                            error = "关系运算符后缺少标识符";
                        }
                    }
                    else
                    {
                        Before();
                    }
                }
                else if (tokens[i].Code == 21)
                {
                    BoolExp();
                    //?
                    if (tokens[i].Code == 22)
                    {
                        return;
                    }
                    else
                    {
                        error = "布尔量中的布尔表达式缺少一个)";
                    }
                }
                else
                {
                    error = "布尔量出错";
                }
            }
            #endregion
    
            #region 算数表达式
            private void AritExp()
            {
                Item();
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 23 || tokens[i].Code == 24)
                    {
                        Next();
                        AritExp();
                    }
                    else
                    {
                        Before();
                        return;
                    }
                }
                else
                {
                    return;
                }
            }
            #endregion
    
            #region 项
            private void Item()
            {
                Factor();
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 25 || tokens[i].Code == 26)
                    {
                        Next();
                        Item();
                    }
                    else
                    {
                        Before();
                        return;
                    }
                }
                else
                {
                    return;
                }
            }
            #endregion
    
            #region 因子
            private void Factor()
            {
                if (tokens[i].Code == 21)
                {
                    Next();
                    AritExp();
                    Next();
                    if (tokens[i].Code == 22)
                    {
                        return;
                    }
                    else
                    {
                        error = "因子中算数表达式缺少)";
                    }
                }
                else
                {
                    CalQua();
                }
            }
            #endregion
    
            #region 算数量
            private void CalQua()
            {
                if (tokens[i].Code == 18 || tokens[i].Code == 19 || tokens[i].Code == 20)
                {
                    return;
                }
                else
                {
                    error = "算数量出错";
                }
            }
            #endregion
    
            #region 结构句
            private void StructSent()
            {
                if (tokens[i].Code == 2)
                {
                    Next();
                    ComSent();
                }
                else if (tokens[i].Code == 8)
                {
                    Next();
                    IfSent();
                }
                else if (tokens[i].Code == 17)
                {
                    Next();
                    WhileSent();
                }
            }
            #endregion
    
            #region if语句
            private void IfSent()
            {
                BoolExp();
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 14)
                    {
                        Next();
                        ExecSent();
                        Next();
                        if (tokens[i].Code == 5)
                        {
                            Next();
                            ExecSent();
                        }
                        else
                        {
                            Before();
                            return;
                        }
                    }
                    else
                    {
                        error = "if...then语句缺少then";
                    }
                }
                else
                {
                    error = "if语句布尔表达式出错";
                }
            }
            #endregion
    
            #region while语句
            private void WhileSent()
            {
                BoolExp();
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 4)
                    {
                        Next();
                        ExecSent();
                    }
                    else
                    {
                        error = "while语句缺少do";
                    }
                }
            }
            #endregion
        }
    }
    
    semantic.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace 编译
    {
        public class Semantic
        {
            public List<FourPart> fps = new List<FourPart>();
            public List<E> es = new List<E>();
            List<token> tokens;
            public List<symble> symbles=new List<symble>();
            public string error = "";
            int i = 0;
            int ti = 1;
            string tt = "";
    
            public Semantic(Morphology m)
            {
                tokens = m.tokens;
                symbles = m.symbles;
                Dispose();
            }
    
            private void Next()
            {
                if (i < tokens.Count - 1)
                {
                    i++;
                }
            }
    
            private void Before()
            {
                if (i > 0)
                {
                    i--;
                }
            }
    
            #region 创建临时变量
            private string NewTemp()
            {
                string temp = "T" + ti.ToString();
                ti++;
                symble s=new symble();
                s.Name=temp;
                symbles.Add(s);
                return temp;
            }
            #endregion
    
            #region 回填函数
            private void BackPatch(int addr, int addr2)
            {
                fps[addr].JumpNum = addr2.ToString();
            }
            #endregion
    
            #region 产生四元式
            private void Emit(string op, string strLeft, string strRight, string jumpNum)
            {
                FourPart fp = new FourPart(op, strLeft, strRight, jumpNum);
                fps.Add(fp);
            }
            #endregion
    
            #region 主要函数
            private void Dispose()
            {
                if (tokens[i].Code == 12)//含有program
                {
                    Next();
                    if (tokens[i].Code == 18)//是标识符
                    {
                        Emit("program", tokens[i].Name, "_", "_");
                        //执行程序体
                        Next();
                        ProBody();
                    }
                    else
                    {
                        error = "该程序program缺少方法名";
                    }
                }
                else
                {
                    error = "该程序缺少关键字:program";
                }
            }
            #endregion
    
            #region 程序体
            private void ProBody()
            {
                if (tokens[i].Code == 16)
                {
                    Next();
                    VarDef();
                }
                else if (tokens[i].Code == 2)
                {
                    Next();
                    ComSent();
                }
                else
                {
                    error = "程序体缺少var或begin";
                }
            }
            #endregion
    
            #region 变量定义
            private void VarDef()
            {
                if (IsIdlist())
                {
                    Next();
                    if (tokens[i].Code == 29)//:
                    {
                        Next();
                        if (tokens[i].Code == 9 || tokens[i].Code == 3 || tokens[i].Code == 13)//integer,bool,real
                        {
                            int j = i;
                            j = j - 2;
                            symbles[tokens[j].Addr].Type = tokens[i].Code;
                            j--;
                            while (tokens[j].Code == 28)
                            {
                                j--;
                                symbles[tokens[j].Addr].Type = tokens[i].Code;
                            }
                            Next();
                            if (tokens[i].Code == 30)
                            {
                                Next();
                                if (tokens[i].Code == 2)
                                {
                                    Next();
                                    ComSent();
                                }
                                else
                                {
                                    VarDef();
                                }
                            }
                            else
                            {
                                error = "变量定义后面缺少;";
                            }
                        }
                        else
                        {
                            error = "变量定义缺少类型或类型定义错误";
                            return;
                        }
                    }
                    else
                    {
                        error = "var后面缺少冒号";
                    }
                }
                else
                {
                    error = "变量定义标识符出错";
                }
            }
            #endregion
    
            #region 判断是不是标识符表
            private bool IsIdlist()
            {
                if (tokens[i].Code == 18)
                {
                    Next();
                    if (tokens[i].Code == 28)//,
                    {
                        Next();
                        return IsIdlist();
                    }
                    else
                    {
                        Before();
                        return true;
                    }
                }
                else
                {
                    return false;
                }
            }
            #endregion
    
            #region 复合句
            private void ComSent()
            {
                SentList();
                if (error == "")
                {
                    if (tokens[i].Code == 6)
                    {
                        Emit("sys", "_", "_", "_");
                    }
                    else
                    {
                        error = "复合句末尾缺少end";
                    }
                }
            }
            #endregion
    
            #region 语句表
            private void SentList()
            {
                S s = new S();
                ExecSent(ref s);
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 30)
                    {
                        Next();
                        SentList();
                    }
                }
            }
            #endregion
    
            #region 执行句
            private void ExecSent(ref S s)
            {
                if (tokens[i].Code == 18)
                {
                    Next();
                    AssiSent();
                }
                else if (tokens[i].Code == 2 || tokens[i].Code == 8 || tokens[i].Code == 17)
                {
                    StructSent(ref s);
                }
                else
                {
                    Before();
                }
            }
            #endregion
    
            #region 赋值句
            private void AssiSent()
            {
                if (tokens[i].Code == 31)//:=
                {
                    string temp = tokens[i - 1].Name;
                    Next();
                    Expression();
                    Emit(":=", tt, "_", temp);
                }
                else
                {
                    error = "赋值句变量后缺少:=";
                }
            }
            #endregion
    
            #region 表达式
            private void Expression()
            {
                if (tokens[i].Code == 7 || tokens[i].Code == 15 || (tokens[i].Addr != -1 && symbles[tokens[i].Addr].Type == 3))
                {
                    E e = new E();
                    BoolExp(ref e);
                }
                else
                {
                    AritExp();
                }
            }
            #endregion
    
            #region 布尔表达式
            private void BoolExp(ref E e)
            {
                E e1 = new E();
                BoolItem(ref e1);
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 11)
                    {
                        int m = fps.Count;
                        E e2 = new E();
                        Next();
                        BoolExp(ref e2);
                        e.t.Concat(e1.t);
                        e.t.Concat(e2.t);
                        e.f = e2.f;
                        foreach (int k in e.t)
                        {
                            BackPatch(k, m);
                        }
                    }
                    else
                    {
                        e = e1;
                        Before();
                    }
                }
                else
                {
                    e = e1;
                }
            }
            #endregion
    
            #region 布尔项
            private void BoolItem(ref E e)
            {
                E e1 = new E();
                BoolFactor(ref e1);
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 1)
                    {
                        Next();
                        int m = fps.Count;
                        E e2 = new E();
                        BoolItem(ref e2);
                        e.t = e2.t;
                        e.f.Concat(e1.f);
                        e.f.Concat(e2.f);
                        foreach (int k in e.t)
                        {
                            BackPatch(k, m);
                        }
                    }
                    else
                    {
                        e = e1;
                        Before();
                    }
                }
            }
            #endregion
    
            #region 布尔因子
            private void BoolFactor(ref E e)
            {
                if (tokens[i].Code == 10)
                {
                    Next();
                    E e1 = new E();
                    BoolFactor(ref e1);
                    e.t = e1.f;
                    e.f = e1.t;
                }
                else
                {
                    E e1 = new E();
                    BoolValue(ref e1);
                    e = e1;
                }
            }
            #endregion
    
            #region 布尔量
            private void BoolValue(ref E e)
            {
                if (tokens[i].Code == 15 || tokens[i].Code == 7)
                {
                    e.t.Add(fps.Count);
                    e.f.Add(fps.Count + 1);
                    tt = tokens[i].Name;
                }
                else if (tokens[i].Code == 18)
                {
                    Next();
                    if (tokens[i].Code == 34 || tokens[i].Code == 33 || tokens[i].Code == 32 || tokens[i].Code == 37 || tokens[i].Code == 36 || tokens[i].Code == 35)
                    {
                        Next();
                        if (tokens[i].Code == 18)
                        {
                            e.t.Add(fps.Count);
                            e.f.Add(fps.Count + 1);
                            Emit("j" + tokens[i - 1].Name, tokens[i - 2].Name, tokens[i].Name, "-1");
                            Emit("j", "_", "_", "-1");
                        }
                        else
                        {
                            Before();
                        }
                    }
                    else
                    {
                        Before();
                        e.t.Add(fps.Count);
                        e.f.Add(fps.Count + 1);
                        Emit("jnz", tokens[i].Name, "_", "-1");
                        Emit("j", "_", "_", "-1");
                        Next();
                    }
    
                }
                else if (tokens[i].Code == 21)
                {
                    E e1 = new E();
                    BoolExp(ref e1);
                    e.t = e1.t;
                    e.f = e1.f;
                    if (tokens[i].Code == 22)
                    {
                        return;
                    }
                }
            }
            #endregion
    
            #region 算数表达式
            private void AritExp()
            {
                Item();
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 23 || tokens[i].Code == 24)
                    {
                        string[] temp = { tokens[i - 1].Name, tokens[i].Name };
                        if (tokens[i - 1].Code == 22)
                        {
                            temp[0] = tt;
                        }
                        Next();
                        AritExp();
                        Emit(temp[1], temp[0], tt, NewTemp());
                        tt = "T" + (ti - 1).ToString();
                    }
                    else
                    {
                        Before();
                        return;
                    }
                }
                else
                {
                    return;
                }
            }
            #endregion
    
            #region 项
            private void Item()
            {
                Factor();
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 25 || tokens[i].Code == 26)
                    {
                        string[] temp = { tokens[i - 1].Name, tokens[i].Name };
                        if (tokens[i - 1].Code == 22)
                        {
                            temp[0] = tt;
                        }
                        Next();
                        Item();
                        Emit(temp[1], temp[0], tt, NewTemp());
                        tt = "T" + (ti - 1).ToString();
                    }
                    else
                    {
                        Before();
                    }
                }
                else
                {
                }
            }
            #endregion
    
            #region 因子
            private void Factor()
            {
                if (tokens[i].Code == 21)
                {
                    Next();
                    AritExp();
                    Next();
                    if (tokens[i].Code == 22)
                    {
                    }
                    else
                    {
                        error = "因子中算数表达式缺少)";
                    }
                }
                else
                {
                    CalQua();
                }
            }
            #endregion
    
            #region 算数量
            private void CalQua()
            {
                if (tokens[i].Code == 18 || tokens[i].Code == 19 || tokens[i].Code == 20)
                {
                    tt = tokens[i].Name;
                }
                else
                {
                    error = "算数量出错";
                }
            }
            #endregion
    
            #region 结构句
            private void StructSent(ref S s)
            {
                if (tokens[i].Code == 2)
                {
                    Next();
                    ComSent();
                }
                else if (tokens[i].Code == 8)
                {
                    Next();
                    IfSent(ref s);
                }
                else if (tokens[i].Code == 17)
                {
                    Next();
                    WhileSent(ref s);
                }
            }
            #endregion
    
            #region if语句
            private void IfSent(ref S s)
            {
                E e = new E();
                BoolExp(ref e);
                if (error == "")
                {
                    Next();
                    if (tokens[i].Code == 14)
                    {
                        int m1 = fps.Count;
                        S s1 = new S();
                        Next();
                        ExecSent(ref s1);
                        Next();
                        if (tokens[i].Code == 5)
                        {
                            S n = new S();
                            n.next.Add(fps.Count);
                            Emit("j", "_", "_", "-1");
                            S s2 = new S();
                            int m2 = fps.Count;
                            Next();
                            ExecSent(ref s2);
                            s.next=s1.next;
                            s.next.Concat(n.next);
                            s.next.Concat(s2.next);
    
                            foreach (int k in e.t)
                            {
                                BackPatch(k, m1);
                            }
                            foreach (int k in e.f)
                            {
                                BackPatch(k, m2);
                            }
                        }
                        else
                        {
                            s.next=e.f;
                            s.next.Concat(s1.next);
                            foreach (int k in e.t)
                            {
                                BackPatch(k, m1);
                            }
                            Before();
                        }
                    }
                    else
                    {
                        error = "if...then语句缺少then";
                    }
                }
                else
                {
                    error = "if语句布尔表达式出错";
                }
            }
            #endregion
    
            #region while语句
            private void WhileSent(ref S s)
            {
                int m1 = fps.Count;
                E e = new E();
                BoolExp(ref e);
                Next();
                if (tokens[i].Code == 4)
                {
                    int m2 = fps.Count;
                    S s1 = new S();
                    Next();
                    ExecSent(ref s1);
                    s.next = e.f;
                    Emit("j", "_", "_", m1.ToString());
                    foreach (int k in e.t)
                    {
                        BackPatch(k, m2);
                    }
                    foreach (int k in s1.next)
                    {
                        BackPatch(k, m1);
                    }
                }
    
            }
            #endregion
    
    
    
    
        }
    }
    
    FourPart.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace 编译
    {
        public class FourPart
        {
            public string Op { get; set; }
            public string StrLeft { get; set; }
            public string StrRight { get; set; }
            public string JumpNum { get; set; }
            public bool Input { get; set; }
            public FourPart() { }
            public FourPart(string op, string strLeft, string strRight, string jumpNum)
            {
                this.Op = op;
                this.StrLeft = strLeft;
                this.StrRight = strRight;
                this.JumpNum = jumpNum;
                this.Input = false;
            }
        }
    }
    
    Create.cs
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace 编译
    {
        public class Create
        {
            List<FourPart> fps = new List<FourPart>();
            public List<symble> symbles = new List<symble>();
            public List<Assembly> assemblys = new List<Assembly>();
            string bx = "";
            string dx = "";
            bool ism = false;
    
            public Create(Semantic s)
            {
                fps = s.fps;
                symbles = s.symbles;
                Dispose();
                Back();
                Translate();
            }
    
            #region 从尾到头的回填待用,活跃信息
            private void Back()
            {
                int i = fps.Count - 2;
                for (; i == 0; i--)
                {
                    if (!fps[i].Op.Contains("j"))
                    {
                        string str = fps[i].StrLeft;
                        foreach (symble s in symbles)
                        {
                            if (s.Name == str)
                            {
                                s.Wait.Add(new string[2] { "" + i + 1 + "", "Y" });
                            }
                        }
                        if (fps[i].StrRight != "_")
                        {
                            str = fps[i].StrRight;
                            foreach (symble s in symbles)
                            {
                                if (s.Name == str)
                                {
                                    s.Wait.Add(new string[2] { "" + i + 1 + "", "Y" });
                                }
                            }
                        }
                    }
                }
            }
            #endregion
    
            #region 划分基本块
            private void Dispose()
            {
                fps[1].Input = true;
                int i = 0;
                foreach (FourPart f in fps)
                {
                    if (f.Op.Contains("j") && f.JumpNum != "-1")
                    {
                        fps[Convert.ToInt32(f.JumpNum)].Input = true;
                        if (f.Op != "j")
                        {
                            fps[i + 1].Input = true;
                        }
                    }
                    i++;
                }
            }
            #endregion
    
            #region 寻找参数的value值
            private string GetValue(string str)
            {
                foreach (symble s in symbles)
                {
                    if (s.Name == str)
                    {
                        return s.Value;
                    }
                }
                return "";
            }
            #endregion
    
            #region 寄存器分配策略
            private string GetReg(FourPart f)
            {
                if (bx == "" || GetValue(f.StrLeft) == "bx")
                {
                    bx = f.StrLeft;
                    foreach (symble s in symbles)
                    {
                        if (s.Name == f.StrLeft)
                        {
                            s.Value = "bx";
                        }
                    }
                    return "bx";
                }
                else
                {
                    if (dx == "" || GetValue(f.StrLeft) == "dx")
                    {
                        dx = f.StrLeft;
                        foreach (symble s in symbles)
                        {
                            if (s.Name == f.StrLeft)
                            {
                                s.Value = "dx";
                            }
                        }
                        return "dx";
                    }
                    else
                    {
                        ism = true;
                        int bxNum = 0;
                        int dxNum = 0;
                        foreach (symble s in symbles)
                        {
                            if (s.Name == bx)
                            {
                                bxNum = Convert.ToInt32(s.Wait.Last()[0]);
                            }
                            if (s.Name == dx)
                            {
                                dxNum = Convert.ToInt32(s.Wait.Last()[0]);
                            }
                        }
                        if (bxNum > dxNum)
                        {
                            dx = f.StrLeft;
                            foreach (symble s in symbles)
                            {
                                if (s.Name == f.StrLeft)
                                {
                                    s.Value = "dx";
                                }
                            }
                            return "dx";
                        }
                        else
                        {
                            bx = f.StrLeft;
                            foreach (symble s in symbles)
                            {
                                if (s.Name == f.StrLeft)
                                {
                                    s.Value = "bx";
                                }
                            }
                            return "bx";
                        }
                    }
                }
            }
            #endregion
    
            #region 寄存器内信息不再用清空
            private void SetNull()
            {
                if (bx != "")
                {
                    foreach (symble sym in symbles)
                    {
                        if (sym.Name == bx)
                        {
                            if (sym.Wait.Count == 0)
                            {
                                bx = "";
                            }
                        }
                    }
                }
                if (dx != "")
                {
                    foreach (symble sym in symbles)
                    {
                        if (sym.Name == dx)
                        {
                            if (sym.Wait.Count == 0)
                            {
                                dx = "";
                            }
                        }
                    }
                }
            } 
            #endregion
    
            #region 放入主存
            private void PutIntoM(string s)
            {
                if (ism)
                {
                    Assembly a;
                    if (s == "bx")
                    {
                        a = new Assembly("MOV", bx, s);
                    }
                    else
                    {
                        a = new Assembly("MOV", dx, s);
                    }
                    assemblys.Add(a);
                    ism = false;
                }
            } 
            #endregion
    
            #region 删除代码执行后对应的待用非待用信息
            private void DelateWait(FourPart f)
            {
                foreach (symble sym in symbles)
                {
                    if (sym.Name == f.StrLeft)
                    {
                        if (sym.Wait.Count > 1)
                        {
                            sym.Wait.RemoveAt(sym.Wait.Count - 1);
                        }
                    }
                    if (sym.Name == f.StrRight)
                    {
                        if (sym.Wait.Count > 1)
                        {
                            sym.Wait.RemoveAt(sym.Wait.Count - 1);
                        }
                    }
                }
            } 
            #endregion
    
            #region 产生目标代码
            private void Translate()
            {
                int i = 0;
                foreach (FourPart f in fps)
                {
                    if (f.Op == "j")
                    {
                        Assembly a = new Assembly("JMP", "L" + f.JumpNum, "");
                        a.Num = i.ToString();
                        assemblys.Add(a);
                        SetNull();
                    }
                    else if (f.Op == "j>")
                    {
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", bx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", dx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("CMP", s, f.StrRight);
                            assemblys.Add(a2);
                        }
                        Assembly a3 = new Assembly("JG", "L" + f.JumpNum, "");
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == "j<")
                    {
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", bx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", dx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("CMP", s, f.StrRight);
                            assemblys.Add(a2);
                        }
                        Assembly a3 = new Assembly("JL", "L" + f.JumpNum, "");
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == "j=")
                    {
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", bx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", dx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("CMP", s, f.StrRight);
                            assemblys.Add(a2);
                        }
                        Assembly a3 = new Assembly("JZ", "L" + f.JumpNum, "");
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == "j<>")
                    {
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", bx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", dx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("CMP", s, f.StrRight);
                            assemblys.Add(a2);
                        }
                        Assembly a3 = new Assembly("JNZ", "L" + f.JumpNum, "");
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == "j<=")
                    {
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", bx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", dx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("CMP", s, f.StrRight);
                            assemblys.Add(a2);
                        }
                        Assembly a3 = new Assembly("JLE", "L" + f.JumpNum, "");
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == "j>=")
                    {
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", bx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("CMP", dx, f.StrRight);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("CMP", s, f.StrRight);
                            assemblys.Add(a2);
                        }
                        Assembly a3 = new Assembly("JGE", "L" + f.JumpNum, "");
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == "+")
                    {
                        string reg = "";
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("ADD", bx, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            reg = "bx";
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("ADD", dx, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            reg = "dx";
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("ADD", s, f.StrRight);
                            assemblys.Add(a2);
                            reg = s;
                        }
                        Assembly a3 = new Assembly("MOV", f.JumpNum, reg);
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == "-")
                    {
                        string reg = "";
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("SUB", bx, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            reg = "bx";
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("SUB", dx, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            reg = "dx";
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("SUB", s, f.StrRight);
                            assemblys.Add(a2);
                            reg = s;
                        }
                        Assembly a3 = new Assembly("MOV", f.JumpNum, reg);
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == "*")
                    {
                        string reg = "";
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("MUL", bx, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            reg = "bx";
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("MUL", dx, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            reg = "dx";
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("MUL", s, f.StrRight);
                            assemblys.Add(a2);
                            reg = s;
                        }
                        Assembly a3 = new Assembly("MOV", f.JumpNum, reg);
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == "/")
                    {
                        string reg = "";
                        if (bx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("DIV", bx, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            reg = "bx";
                        }
                        else if (dx == f.StrLeft)
                        {
                            Assembly a1 = new Assembly("DIV", dx, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            reg = "dx";
                        }
                        else
                        {
                            string s = GetReg(f);
                            PutIntoM(s);
                            Assembly a1 = new Assembly("MOV", s, f.StrLeft);
                            a1.Num = i.ToString();
                            assemblys.Add(a1);
                            Assembly a2 = new Assembly("DIV", s, f.StrRight);
                            assemblys.Add(a2);
                            reg = s;
                        }
                        Assembly a3 = new Assembly("MOV", f.JumpNum, reg);
                        assemblys.Add(a3);
                        DelateWait(f);
                        SetNull();
                    }
                    else if (f.Op == ":=")
                    {
                        Assembly a1 = new Assembly("MOV", f.JumpNum, f.StrLeft);
                        a1.Num = i.ToString();
                        assemblys.Add(a1);
                        foreach (symble sym in symbles)
                        {
                            if (sym.Name == f.StrLeft)
                            {
                                if (sym.Wait.Count > 1)
                                {
                                    sym.Wait.RemoveAt(sym.Wait.Count - 1);
                                }
                            }
                        }
                        SetNull();
                    }
                    else
                    {
                    }
                    i++;
                }
            }
            #endregion
        }
    }
    








    展开全文
  • java实现c语言编译器,包括词法分析,语法分析,语义分析,目标代码生成四部分,总体实现编译器功能,有运行界面,代码精简,值得下载。
  • CPython编译器设计

    千次阅读 2015-04-17 16:37:45
    CPython编译器设计1....这是以往使用的编译过程,因而这不是一个标准的编译器工作流程。通常标准的编译流程是这样:1)分析源码生成分析树(Parser/pgen.c)。2)转换分析树为抽象语法树(Python/ast.c)。3
  • 一个编译器的结构分为分析部分(编译器的前端)和综合部分(编译器的后端)。 编译器的前端:把源程序分解成为多个组成要素,并在这些要素之上加上语法结构。然后,它使用这个结构来创建该源程序的一个中间表示。如...
  • Java初学者设计简单文本编译器

    千次阅读 多人点赞 2019-12-22 11:26:37
    Java初学者设计简单文本编译器编译器可以实现一些基本功能 (1)所见即所得的文本输入; (2)能方便地选中文本、复制、剪切、删除和粘贴文本; (3)具有一般编辑器所具有的查找、替换和文件保存功能; (4)...
  • 我的第一个编译器之词法分析器

    千次阅读 2015-04-11 22:23:57
    用Java写java的编译器和jvm为什么用java,java的结构最便于理解,其丰富的设计模式能使编译器的结构十分鲜明一个编译器的前端模型源代码–词法分析器-(词法单元)-语法分析器-(语法分析树)-中间代码生成器–三...
  • MinGW -将GNU开发工具移植到Win32平台下的计划 Cygwin - 在Windows上运行GNU... 在编码阶段我们使用程序设计语言,根据特定的文法利用程序设计语言来编码。就像是根据英语的语法用英语语言来写文章。当然种语言
  • 编译原理——一个编译器的各个步骤的介绍 版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zoweiccc/article/details/82556601 一个编译器的结构分为分析部分(编译器的前端)和...
  • C++程序设计的各种编译器及IDE

    千次阅读 2011-04-13 21:38:00
    C++程序设计的各种编译器及IDE
  • c编译器设计

    2007-11-20 00:15:27
    包括了c编译器实现的原理和实现代码
  • 一个简单编译器的实现过程

    千次阅读 2016-08-18 15:17:18
    编译器的实现步骤 1、词法分析,将原文件划分为单独的单词或关键字。 2、语法分析,利用上下文无关文法分析程序的短语结构。 3、语义分析,根据短语建立抽象语法树,确定短语含义、变量关联声明、检查表达式类型...
  • 1. 浏览器接收html文件,在屏幕上显示出来,是一个解释执行的过程. 2. 作为编译器的用户,我关注以下5个特性,  a.1 编译完成的速度  a.2 编译时占用的内存  a.3 编译时临时文件占用的空间  a.4 错误提示...
  • 手把手教你实现一个简单的编译器

    千次阅读 2018-01-21 19:25:10
    手把手教你实现一个简单的编译器 1、 概述 今天我们将学习开发一个编译器,但是呢,这个编译器并不是说什么都能都编译,它只是一个超级小的编译器,主要用于说明编译器的一些基本的原理。 我们这个编译器可以将类似...
  • 编译器设计原则

    2007-09-05 15:04:00
    一个真正优秀的编译器不应该有预设的限制,而应该只受一些外部因素的限制,如可用的内存或硬盘空间等,这可以通过使用链表和必要时动态扩展表的大小来实现!对于编程语言的语法来说,歧义是非常可怕的,因为它使...
  • 用java写一个编译器(1)基本知识

    千次阅读 2019-03-30 06:24:31
    无意中在b站看到了coding迪斯尼老师的 java写编译器的课程,学完真让我收益匪浅。但学归学,终究还是要动手实操一下的。先走遍知识脉络。详细的可看coding迪斯尼老师的博客(tyler_download) ...
  • 自己动手实现一个简单c编译器

    千次阅读 2015-11-28 10:37:19
    这学期的编译课程设计需要做一个类c编译器,准确的说是完善上学期做的大实验。 上学期的实验中,使用antlr完成的编译器识别的语法很有限,基本上是个计算器的语法,于是这次决定弄语法一个更加完整。 语法支持: ...
  • 学习较底层编程:动手写一个C语言编译器 http://blog.jobbole.com/77305/
  • 编译器设计与实现 编译原理课程设计 完整报告 总结编译器设计与实现 编译原理课程设计 完整报告 总结编译器设计与实现 编译原理课程设计 完整报告 总结
  • 一个小型的汇编编译器

    千次阅读 2018-04-25 19:09:26
    本程序包含4源文件与6个头文件,源文件约2200行代码,头文件共约500行,可识别并编译27项指令。 支持vs2013及更高版本 支持gcc 6.3.0及更高版本,gcc编译过程如图:(2019.7.26更新,直接在终端输入make来编译,...
  • 自己做编译课程设计写的一个很简单的C编译器,用的是LEX+YACC写的,方法比较新,由于时间的关系写的不是很完善,但是要扩充的话比较容易。压缩包中附LEX&YACC的语言详解,相信对于对编译有兴趣的人有些帮助。
  • 编译器

    2011-10-28 14:58:58
    一个模块化并且可扩展的 IDE 中全面集成编译器和调试器工具箱。 - 高度优化的 ISO/ANSI 标准 C 编译器能够生成市面上最紧凑的代码 - 灵活的硬件调试支持 - C 到 C 转换器支持 Keil 到 IAR C 代码转换 所有 ...
  • 一个C语言编译器是怎么编写的

    千次阅读 2017-11-27 09:38:47
    一个 C 语言编译器是怎样编写的? 转自:https://www.csdn.net/article/2015-11-27/2826350 发表于2015-11-27 18:03| 次阅读| 来源开源中文社区| 0 条评论| 作者Chaobs 摘要:当今几乎所有的实用的...
  • 几乎所有的软件都是通过称为编译器的工具转换而来的,编译器也只是一个计算机程序,它转换其它计算机程序,并使之准备好执行。 1.概念路线图 编译器是一种工具,将一种语言编写的软件转换为另一种语言,它需要理解...
  • 许多初学者都会对这三个概念区分不清,应该说这三个概念是完全不同的,不能混为一谈。...首先说程序设计语言,它同人类的自然语言一样也是一个语言,并且它是自然语言的一个子集。大家都知道自然
  • 一个小型的编译器设计,是哈工大计算机专业必修课《编译原理》的课程设计
  • 编译器设计:词法分析

    千次阅读 2016-11-29 09:31:26
    通过python实现了一个能够识别单词的程序,单词定义为 以字母开头的任意数字和字母的组合1. re模块定义字母和数字pattern,通过match对字符进行匹配2. enum模块用来定义识别单词过程中的状态,这里定义了 初始态 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 391,591
精华内容 156,636
关键字:

怎么设计一个编译器