编译原理
才大难为用
我不懒
展开
-
构建自己的编译器(十九) 完工总结
如果要用自己的编程语言实现自己的操作系统的话,说实话,那只能完成一部分,因为自己的编程语言与nasm汇编代码并不是一一对应的,而且反正都用汇编写了那么多了,用自己的编程语言写写库函数就够了。。。下面是展示:下面就开始干操作系统了,同时完善自己的编程语言。...原创 2021-02-01 22:56:38 · 183 阅读 · 0 评论 -
构建自己的编译器(十八) 函数执行
[执行方式]cla().[表示执行初始执行语句,也是普通执行函数]cla(1,2).[表示执行初始含参语句,在别的编程语言来说,就是简单的执行函数]cla1\func(1,2).[表示执行函数内函数]cla()\func(1,2).[错误/正确,不能执行两个函数,除非返回的也是自己的类型,这时候就必须添加上后缀了cla()\func(a.int<=1,b.int<=2)[正确,清晰易懂绝不会差,因为之前已经定义了,执行绝不会有定义][前面有.的变量表示隐...原创 2021-02-01 10:04:42 · 106 阅读 · 0 评论 -
构建自己的编译器(十七) 函数声明
#函数f(a:int,b:int):a+b=>f.[按理说,默认返回值是变量函数都可以,但是返回值与后缀就没关系了,它本身是一个函数嘛,还要禁止它呢][但是这最后返回的时候确实有些不对劲,按理说也应该是int啊][类是有后缀的,函数是没有后缀的,我把类和函数归一了,这样仍会报错,但是也没有问题,检查在变量端检查][比如你写的函数既能返回整数,也能返回字符串,但某个时刻你只想返回整数,返回字符串报错,那么你只能在变量端检查][这么写:a.int<=fun().]...原创 2021-02-01 08:33:43 · 158 阅读 · 1 评论 -
构建自己的编译器(十六) if与while
#判断条件语句的实现,分支判断用分号;,分号后可以跟一个问号作为判断^x>1?print("yes");x<1?print("No");print("Idon'tknow").^x>y?x;y.最后以句号作为结尾。#循环@条件?(语句);().步进for该如何设置呢?用语法糖i:1.@b:arr\i++\j?print(b);print("end").[感觉这个语法糖真不错]t_arr:arr....原创 2021-01-31 21:48:39 · 155 阅读 · 0 评论 -
构建自己的编译器(十五) 表达式&运算符
#运算符[<=>叫映射,:叫拷贝,什么意思呢?映射是你之前必须有内存,拷贝是你之前必须没有内存,同时也叫声明符号][拷贝是根据后面的结果来确定前面值的内存和值,按理说后面是返回的一个值][一个是返回返回值,如果没有返回值就返回自己,域与变量是不会相互赋值的,这是错误][一个函数的声明只会在一个声明语句的左部出现,不会在任何地方出现了,而声明左部的函数也必然只是函数声明,不会有函数执行][所以前面必须是单个值,而不能是表达式,后面可以是表达式,而且不会再有形参的声明][..原创 2021-01-31 20:40:56 · 105 阅读 · 0 评论 -
构建自己的编译器(十四) 变量声明
[普通变量声明]a: 0. [最普通的变量声明a.int: 0.b: a.b.int: a.c: 0.2.c.flo: 0.2.d.int: -2.d.flo: -2.0.e: "hello world".e.str: "hello world".f: true.f.boo: false.[不允许连续声明,因为这样很难看,而且单个声明也不是很长的句子][数列,映射声明]g.ar: {1, 2, 3}.g.arr: {{1, 2, 3}, 4, 5}.g.map: {"ke.原创 2021-01-31 20:16:25 · 200 阅读 · 0 评论 -
构建自己的编译器(十三) 回归flex+bison
说实话,词法分析必然用到正则表达式,自己实现一个自动机是不现实的。原创 2021-01-22 11:03:14 · 170 阅读 · 0 评论 -
编译原理(十二)习题1
给出它的左右推导怎么做?例如让你最左推导,你就用最右规约,让你最右推导,你就最左规约,规约比推导要方便。语法分析树就是这样,没有什么神秘的。一般来说,分析树与推导所用的顺序无关,甭管是最左最右,还是其他推导。但是说,如果一个文法里有类似加减运算符的那种类型的话,那么这个就是二义性的,判断一个文法是否是二义性的,就是看不同的形成方法是否会出现不同的语法树,精简一些,就是看是否出现运算...原创 2020-04-26 21:44:57 · 576 阅读 · 0 评论 -
编译原理(十一)题型
从头到尾题型列一遍,就是作业中的:原创 2020-05-25 10:46:20 · 2863 阅读 · 1 评论 -
编译原理(十)语法制导翻译
语法制导翻译 SDD综合属性:从前面语句中获取属性,由底向上的继承属性:从后面语句中获取属性,由顶向下的什么属性可能就与代码有关原创 2020-05-17 18:15:23 · 3301 阅读 · 0 评论 -
编译原理(八)消除空产生式
终于到自底向上了。。。算符优先文法老师不打算讲。。。规范规约就是最左规约,没什么好讲的。一般就是先做规约,再做推导就是这样。判断是否为SLR(1)文法的方法是什么?SLR(1)的特点是什么?LR(0)文法要求文法的每一个LR(0)项目都不含有冲突的项目,这个条件比较苛刻。对于大多数程序设计语言来说,一般都不能满足LR(0)文法的条件。移进冲突规约冲突都不能有。对含有冲突的项目集...原创 2020-04-28 14:38:02 · 6065 阅读 · 1 评论 -
编译原理(七)action表,goto表,LR(1)图,预测分析表与文法判断
今天是自顶向下的专场。。。如何判别是LL(1)文法呢?第一种判断方法:对于文法的产生式任一产生式:(1)文法不存在左递归(2)假设A->α | β是其中一个产生式, 如果α 或者β都不能推出ε,则FIRST(α)∩FIRST(β)=∅(3)假设A->α | β是其中一个产生式,如果α 或者β至多有一个能推出 ε,或者其中一个经过若干步能推出ε,则first(α)∩follow(A)=∅(这里假设β能推出ε)文法所有的产生式都要满足以上三种情况才符合...原创 2020-05-24 22:33:27 · 8656 阅读 · 0 评论 -
编译原理(六)活前缀,LR文法初步介绍
什么是NFA(不确定的有穷自动机)和DFA(确定的有穷自动机) 有穷自动机 ( Finite Automata,FA )由两位神经物理学家MeCuloch和Pitts于1948年首先提出,是对一类处理系统建立的数学模型 这类系统具有一系列离散的输入输出信息和有穷数目的内部状态(状态:概括了对过去输入信息处理的状况) 系统只需要根据当前所处的状态和当前面临的输入信息就可以决定系统的后继...原创 2020-04-28 14:09:17 · 22436 阅读 · 4 评论 -
编译原理(五)短语,句柄定义,语法与正则文法互转
文法如何转正规式?就是转状态机,因为状态机可以有正则式的那些方法,因此就可以方便转换,直接转化貌似是很困难的事情。至于写出定义的语言描述,就是多写出几个例子来,就知道了。...原创 2020-04-26 22:54:56 · 1005 阅读 · 0 评论 -
编译原理(四)FIRST集,FOLLOW集,SELECT集,预测分析表
First集:就是本非终结符的首部Follow集:就是本非终结符的下一个终结符,如果后面没有就把左部非终结符的Follow集添加进来。关于action表与goto表的计算,这个就是找闭包:点在中间就是移进项目,点在最后就是规约项目,根据点在哪里你至少能画出一个图来,然后根据这个图至少能写出协议族来。...原创 2020-04-26 14:01:53 · 2589 阅读 · 0 评论 -
编译原理(三)直接左递归与间接左递归的消除
在进行语法分析的时候,如果采用自上而下的分析方法(从开始符开始,推句子),那么要求文法不是左递归的,进而如果是左递归的,则要求消除左递归,因此左递归只是在自上而下的那种文法里的。 左递归的定义:文法经过一次或多次推导之后,出现如下形式,原理是很简单了。 左递归的分类 直接左递归:P → Pa 简介左递归:P → Aa, A → …… → Pb 直接左递...原创 2020-04-26 08:44:09 · 6666 阅读 · 0 评论 -
编译原理(二)NFA转DFA,DFA的化简
一般凭直观构造出的自动机都是NFA,而要把NFA转换成DFA,要用子集构造法。构建DFA的目的是,,,反正DFA比NFA有用。一般是正则表达式->NFA->DFA。定义真的是蛮变态的,还是自己总结的清楚简单直接明白。这个图是一个NFA,NFA的写法就是从一个开始,最后的那个状态用双圈表示,这里的意思就是从0开始,找0的闭包是为A,然后看输入符号a后的那一个闭包就是B,然后一...原创 2020-04-25 22:53:29 · 4667 阅读 · 1 评论 -
编译原理(一)几种文法,基础符号定义,闭包举例
类型 文法 语言 0 PhraseStructureGrammar(PSG) recursivelyenumerablelanguages递归可枚举 设G=(VN,VT,P,S),如果它的每个产生式α→β是这样一种结构:α∈(VN∪VT)*且至少含有一个非终结符,而β...原创 2020-04-25 22:03:02 · 5237 阅读 · 0 评论 -
FLEX & BISON 联合使用
flex是词法分析器,bison是语法分析器,基本原理就是flex解析出token后,让bison来使用。实际上,一般是先编写bison脚本,里面的token就是一个定义,没有实现,里面的yylex也是没有实现,只有定义,为什么先做bison呢?因为编写bison脚本并被bison编译后,除了产生一个parse的c文件,还会产生一个token头文件,里面详细定义了token,然后,我们再编写f...原创 2020-02-29 10:20:15 · 1381 阅读 · 0 评论 -
文法分析概览
文法分析概览利用BNF写出的文法规则,可以用来对输入的文本进行文法分析。一条BNF文法规则,左边是一个非终结符(Symbol或者non-terminal),右边则定义该非终结符是如何构成的,也称为产生式(Production),产生式中可能包含非终结符,也可能包含终结符(terminal),也可能二者都有。在所有文法规则中,必有一个开始的规则,该规则左边的部分叫做开始符号(start symb...转载 2020-02-28 21:12:48 · 1170 阅读 · 0 评论 -
ant编程语言语法
#ant语言ant语言是一种玩具语言,是一种面向过程的程序设计语言,可运行于多种平台上,如Windows、MAC操作系统以及UNIX的各种版本。一款尽量用其他学科的定义或者常识来设计的编程语言插入型注释为*[xxxx]完成,句子型注释用*[1]来完成,在下面用1.xxx:xxxxxx,进行逻辑判定,好判定又规范函数用*来判定,变量:不用声明,定义用=>和<=来...原创 2020-01-22 22:11:00 · 862 阅读 · 0 评论 -
构建自己的编译器(十一)实质性的第三步
bison a.y -d -v --debug-d是用来生成头文件的,与调试无关。-v生成output文件,描述了我们创建的自动机,可以帮助我们分析调试内容。原创 2020-05-05 12:48:27 · 178 阅读 · 0 评论 -
构建自己的编译器(十)魔改C语言框架
我前几天发现了一个C语言前端,因此我就用那个前端魔改了,通过小小的改动语法分析和大量改动词法分析,现在编写的语言有一点那个样子了。。。但是还有很多不足。。。下面就是现在语言的demo:int a_b_c_d_s_r_p_q, [anotation]switch(a){ case 0: s<=1+4, break, case 1: { a<=b, switc...原创 2020-03-07 20:28:52 · 362 阅读 · 0 评论 -
构建自己的编译器(十)实质性的第二步
本来编译原理是先走了一步,没想到几天没学,课程进度都赶上来了。lalr是在lr1文法百合并同心项得到,就是合并了展望符度,而展望符是用来判断用哪个式知子归约冲突的,将展望符合并了,就是将可道归约的范围扩大了,但每次只能选一个正回确的式子归约。故lalr文法中相对于lr1产生了归约归约冲突答。...原创 2020-04-30 20:31:01 · 159 阅读 · 0 评论 -
构建自己的编译器(九)实质性的第一步
我现在用flex+bison实现的,昨天看了一晚上。。。现在实现了定义,真的很不错了。在lexer.l中,标识符的正则表达式是:[a-zA-Z][a-zA-Z0-9_]* { yylval.strval = strdup(yytext); return IDENTITY; }然后需要一个赋值符:":" { return ASS...原创 2020-03-05 20:01:47 · 208 阅读 · 0 评论 -
构建自己的编译器(八)汇编器之二
现在大致明白了是怎么工作的了,它根据前向算的,获取出一个token之后就能判断它到底属于哪一个句型,对于C语言的确是如此,但是对于我这个语言来说,emmm,貌似也差不多,它维护着一个变量表,我完全可以用map实现,然后对于变量定义,真的不难。那么汇编器实际上也不用做,其也是解析成汇编语言然后放入虚拟机的,我可以更简单。例如变量定义,用map做,而它说的函数调用,现在还没有看,但是它也是要编...原创 2020-03-05 19:49:09 · 587 阅读 · 0 评论 -
构建自己的编译器(七)词法分析之二
对于标识符,已经存在的那些,有初始的一张表,然后是自己定义的变量名函数名什么的,也要存入一张表中,如果标识符存在就返回该标识符,实际上,词法分析后,有很大一部分都变成了id了。代码上int*current_id这样的int*current_id,//currentparsedID*symbols,//symboltableline,...原创 2020-02-15 21:54:11 · 174 阅读 · 0 评论 -
构建自己的编译器(六)虚拟机之二
对,你解析了如果只是一个一个next的话,这就是将词法分析和语法分析合在一起了,因为词法分析本来就不是什么难事语法树都没构造它怎么就可以进行变量定义了?它是通过解析什么enmu啦,int什么的完成的,然后按照定义完成赋值,根本不用断句,好,即便不用断句,那么它是把参数压入栈了吗?首先,一个主函数一个栈,当调用次函数时,要把pc压入栈,然后把pc赋给次函数,执行,完毕则弹出栈,这个...原创 2020-02-15 18:32:22 · 194 阅读 · 0 评论 -
构建自己的编译器(四)递归下降
按理说,今天开始讲词法分析,但是奈何我已经学完了,今天学学递归下降。传统上,编写语法分析器有两种方法,一种是自顶向下,一种是自底自上。自顶向下是从起始非终结符开始,不断地对非终结符进行分解,直到匹配输入的终结符;自底向上是不断地将终结符进行合并,直到合并成起始的非终结符。它们的目的都是判断这条语句是否合法,不合法的不能递归完毕的。自顶向下方法就是我们所说的递归下降。我们能直接根据BNF写出解析代...原创 2020-02-12 14:05:31 · 251 阅读 · 0 评论 -
构建自己的编译器(三)虚拟机
定义语句呢,就是 x:0. 这样,我来说说它的编译过程:首先进行词法编译,变成:<variable, "x"><semicolon><integer, 0><dot>然后进行语法编译,这里就不会了,将词法分析得到的标记流(token)生成一棵语法树。1、next() 用于词法分析,获取下一个标记,它将自动忽略空白字符。2、program...原创 2020-02-02 18:57:22 · 501 阅读 · 1 评论 -
构建自己的编译器(二)语法分析器
既然已经拆分成一个个单词了,那么接下来做什么呢?构建语法树!因为我们是把一个字符串变成单词流了,但是我们并不知道其中的一个句子是否符合语法,那么我们怎么知道这个句子是否符合语法呢?就对它进行规约,从一个句子的几个单词开始,逐渐规约成更大的成分,最后规约成一个最大成分,如果规约成功,那么最后只有一个成分,也就是句子。好,现在我们知道了一个句子是否符合语法,那么然后呢?然后就是针对不同的语句构建不同...原创 2020-01-28 10:44:02 · 637 阅读 · 0 评论