计算机编译原理实验生成四元式序列#精选.

合集下载

写出如下语句的四元式序列

写出如下语句的四元式序列

写出如下语句的四元式序列1.引言1.1 概述在编程语言中,为了对程序进行分析和执行,我们需要将程序转换成计算机能够理解和执行的形式。

而四元式序列就是一种常用的表示方式之一。

四元式序列是由四个元素组成的元组,分别是操作符、操作数1、操作数2和结果。

它可以将复杂的程序语句拆分成更简单的操作,方便计算机进行处理。

在撰写四元式序列时,我们需要根据具体的语句来确定操作符、操作数1、操作数2和结果。

以以下语句为例:pythonx = y + z我们可以将这个语句转换成如下的四元式序列:1. (+, y, z, t1)2. (=, t1, "", x)在这个序列中,第一行的操作符是加号,操作数1和操作数2分别是变量y和z,结果是临时变量t1。

第二行的操作符是赋值号,操作数1是临时变量t1,操作数2为空,结果是变量x。

这样,通过四元式序列的表示,我们可以更清晰地描述程序的执行过程,方便后续的语义分析和执行。

总的来说,四元式序列在程序分析和执行中具有重要的作用,它可以将复杂的程序语句转换成更简单的操作,方便计算机进行处理。

在实际的编程中,我们可以根据具体的语句来编写相应的四元式序列,以达到更高效、更准确地执行程序的目的。

1.2文章结构文章1.2 文章结构文章结构是指文章整体的组织形式,包括各个部分之间的关系和排列顺序。

一个合理的文章结构能够使读者更好地理解文章的主题和内容,提高文章的可读性和逻辑性。

在本文中,我们将主要围绕三个部分展开,分别是引言、正文和结论。

引言部分作为文章的开端,其主要功能是引起读者的兴趣,明确文章的主题和目的。

在引言部分中,我们将对本文的概述进行介绍,简要说明文章的主要内容和结构,并阐述文章撰写的目的。

通过清晰明了地阐述引言部分的内容,能够让读者对后续的内容有一个整体的认识和预期,为接下来的阅读打下基础。

正文部分是文章的核心,也是作者表达观点和论证思路的主要部分。

在正文部分中,我们将围绕两个要点展开,分别是要点一和要点二。

词法分析程序+语法语义分析四元式生成+实验报告

词法分析程序+语法语义分析四元式生成+实验报告

《编译原理》实验报告本文档集合了编译原理大作业的实验报告加代码实验主要内容为用C++实现了词法分析程序;语法语义以及四元式生成程序代码见附录,复制进VS后程序绝对可编译执行。

文档代码为原创,谨慎使用(姚砺的大作业)实验设计一[一、实验名称]词法分析程序[二、实验目的](1)设计一个词法分析程序,每调用一次就从源程序文件中顺序识别出一个单词符号,并返回该单词符号的内部编码、单词符号自身、行列位置信息。

(2)要能处理单行注释。

[三、实验内容及要求]单词种类与识别规则(1)标识符:首字符为字母或下划线,其后由字母、数字或下划线组成、长度不超过255个字符;(2)整数:由1到8个数字组成。

(3)小数:数字串1 .数字串2,其中:数字串1由1-8个数字符组成;数字串2由0-8个数字符组成,即:数字串2可以为空。

(4)字符串:由一对“”括起来的符号串,长度不超过255个字符;(5)保留字:if、else、while、do、integer、float、string、input、output、and、or、function、end、def、as、begin(6)数学运算符:+、-、*、/、=(7)比较运算符:<、<=、>、>=、<>、==(8)逻辑运算符:and、or(9)分隔符:{、}、(、)、;、,[四、实验环境]操作系统:Win7/其他编译工具:VC++6.0 / CFree / VS2012[五、设计]1设计大体思路将读取的文件采用一遍扫描的方法,即从左到右只扫描一次源程序,将读取的数据存放在一个二维数组里。

然后通过扫描函数scan,再从数组中一行一行的读取数据,每调用其依次返回一个单词的类型,同时单词本身以及行列号存放在全局变量中。

而说词法分析作为语法分析的一个子程序,故在编写词法分析程序时,将会反复调用scan函数来获取一个个单词信息。

程图4函数设计/*词法分析函数*/int scan( string s ,int line )框架:{初始化工作是空格直接跳过,知直到读取到一个字符if( 是字母){查表判断是否为关键字判断是否为逻辑运算符and或orElse则为标识符}else if( 是否为数字){判断是整数Else是小数}Else{其余情况判断是否为运算符,字符串等}else if( getchar==’/’ ){if( content[line][i+1]=='/') //向前看一个,确定是否为行注释;如果是,则游标指向行末,跳过行注释if( content[line][i+1]=='/*')如果向前看一个发现时块注释则一直向前扫描直到出现“*/”停止,略过块注释如果都不是则Else判断为除号,返回运算符类型}}2 对其中部分实现的说明(1) 数字识别while( content[line][i]>='0' && content[line][i]<='9' ) //判断是否为数字{text += content[line][i];i++;flag=1;}if( flag==1 ){if( content[line][i]=='.' ){text += content[line][i];i++;while( content[line][i]>='0' && content[line][i]<='9' ) //判断是否为数字{text += content[line][i];i++;}return 2; //整数}return 3; //小数}每读入一个字符,判断是否数字,然后找小数点,找到即为小数(2)标识符处理while( (content[line][i]>=65 && content[line][i]<=90) || (content[line][i]>=91 &&content[line][i]<=122) || content[line][i]>='0' && content[line][i]<='9' ) //判断是否为数字或者字母或者下划线{text += content[line][i];i++;}for( j=0; j<=13 ; j++ )if( text==key[j] ) //查表判断是否为保留字return 5;检查到读取的字符为字母时,进行查表判断,找到即说明为关键字(3)空格,注释,行号的处理if( mode==0 ){if( i<content[k].length() ) i++;} //如果为行注释直接跳到下一行elseif( mode==-1 ) //如果为块注释找回行号k=templine;[六、程序源代码]见源代码文件。

一个语法分析程序并生成四元式中间代码

一个语法分析程序并生成四元式中间代码

编写一个语法分析程序并生成四元式中间代码班级学号姓名:指导老师:一、实验目的:1、学习编译的基本原理;2、巩固课堂学习的知识;3、会对最基本的语句进行分析,转换成四元式;二、实验内容:编制一个大型程序,可以对小型的EL语言程序进行翻译,可以处理最基本的语句如:if语句,while语句等;三、实验硬件和软件平台:INTEL C433MHz Cpu128Mb SDRAMTPWMicrosoft Windows XP SP1四、步骤和算法描述:1、先对输入的语句进行词法分析,建立各种表格;2、对程序进行语法分析,建立四元式;对部分程序语句进行翻译,生成相应的四元式,及出错处理五.源程序:program elcompiler(input,output,f);const reser=20;type alfa=packed array[1..9] of char;opr=(jmp,prt,jeq,jne,jgt,jlt,jge,jle,add,sub,mul, did,ass,umi,jsr,ret,inp,out,xxx);{中间代码的操作码符号}instruction=record{四元式} op:opr;arg1,arg2,result:integer;end;symset=set of 0..45;obj=1..45;var reserve:array[0..reser] of alfa; {保留字表}token,id:alfa;line:array[1..80] of char; {输入缓冲区}ch,ch1:char;quad:array[0..300] of instruction; {四元式表}table:array[0..100] of {符号表} recordname:alfa;level:integer;case cat:obj of2 : (val:integer);18,7: (addr:integer)end;mnemonic:array[opr] of array[1..3] of char;cp,tp,new,nxq:integer;cc,ii,i,j,k,num:integer;kind,l,err:integer;filename:string;{外部文件名}f:text;procedure getchar; {从扫描缓冲区取一字符}beginif cc=ii then {如果已取到缓冲区的最后,则从外部}{文件再读一行}beginif eof(f) thenbeginwriteln('program incomplete!');close(f); exitend;cc:=0; ii:=0; { cc is input to buffer pointer; { ii is output pointer from buffer;}while not eoln(f) dobegin cc:=cc+1;read(f,line[cc]);write(line[cc])end;readln(f); writeln;cc:=cc+1; line[cc]:=' ';end;ii:=ii+1; ch:=line[ii]end;procedure getnbc; {读取非空字符}label l;beginl:getchar;while ch='' do getchar;if ch='{' thenbegin repeat getchar until ch='}';goto l end {跳过注解}end;procedure retract; {退回一字符}beginii:=ii-1end;procedure scanner; {词法分析过程}begingetnbc;if ch in ['a'..'z'] then {symbol is id or reserve}begink:=0;repeatif k<10 thenbegin k:=k+1; token[k]:=ch end;getcharuntil not(ch in['a'..'z','0'..'9']);retract;if k<10 thenrepeatk:=k+1;token[k]:=' 'until k=10;id:=token; i:=0; j:=reser;repeat k:=(i+j) div 2; {对半查找保留字表}if id<=reserve[k] then j:=k-1;if id>=reserve[k] then i:=k+1until i>j;if i-1>j then kind:=k else kind:=21 {变量的类别}end elseif ch in ['0'..'9'] thenbegin{整数}k:=0; num:=0; kind:=22;repeatnum:=10*num+(ord(ch)-ord('0'));k:=k+1; getnbc;until not(ch in ['0'..'9']); retractend elsebegincase ch of'+','-':beginch1:=ch; retract; retract; getchar;if (ch='=') or (ch='(') then {区分单目双目算符}if ch1='+' then kind:=32 else kind:=33else if ch1='+' then kind:=34 else kind:=35;getcharend;'*':kind:=36;'/':kind:=37;',':kind:=23;'.':kind:=26;';':begin writeln; kind:=24 end;'(':kind:=27;')':kind:=28;'[':kind:=29;']':kind:=30;'=':kind:=38;':': begingetnbc;if ch='=' then kind:=44else begin retract; kind:=25 endend;'#':kind:=47;'{':kind:=45;'}':kind:=46;'>':begingetnbc;if ch='=' then kind:=43else begin retract; kind:=40 endend;'<':begingetnbc;if ch='=' then kind:=42else if ch='>' then kind:=41else begin kind:=39; retract endend;else;end;endend;procedure error(n:integer); {出错处理}beginwrite('*',' ',ii-2,'^',n:2); err:=err+1;case n of0:writeln('lack ''program''');1:writeln('ought to''='' ');2:writeln('lack''=''');3:writeln('expected indent');4:writeln('expected factor');5:writeln('expeced '','''';''');6:writeln('expected ''begin or functin''');7:writeln('expected statement') ;8:writeln('expected''begin''');9:writeln('expect '',''');10:writeln('num is too big');11:writeln('indent isnt specify');12:writeln('cant assign to const');13:writeln('expeced '':=''');14:writeln('expected ''(''');16:writeln('ought to ''then''');17:writeln('expected ''end''or'';''');18:writeln('ought to ''do''');19:writeln('expected '';''on''.');20:writeln('expeced ''rop''');22:writeln('expected '')''');23:writeln('may be to lack''*''');25:writeln('to lack type specify');26:writeln('indent double define')else ;endend;procedure test(s1,s2:symset;m:integer); { 测试单词的合法}beginif not(kind in s1) thenbeginerror(m); s1:=s1+s2;while not (kind in s1) do scannerendend;procedure gen(op:opr;ag1,ag2,result:integer); {生成中间代码}beginquad[cp].op:=op;quad[cp].arg1:=ag1;quad[cp].arg2:=ag2;quad[cp].result:=result;cp:=cp+1;nxq:=cp;end;procedure blk(lev,tp:integer;sys:symset);var tp0,cp0,dp:integer;chain:integer;function entry(iden:alfa):integer;var i:integer;begini:=tp;table[0].name:=iden;while table[i].name<>iden do i:=i+1;entry:=iend;procedure fill(k:obj);{填写符号表}var i:integer;beginfor i:=tp0 to tp do {tp0 本分程序符号表首址}if table[i].name=id thenbegin error(26); exit end;tp:=tp+1;with table[tp] dobegin name:=id; cat:=k; level:=lev;case k of2: begin if num>22767 then{const 说明} begin error(10); num:=22767 end; val:=num;end;18:begin addr:=dp; dp:=dp+1 end; {var 说明}7:addr:=0;{function 说明}endendend;procedure constdec; {说明处理}beginif kind=21 then {变量}beginscanner if kind in [38,44] then {=,:=}beginif kind=44 then error(1);scanner;if kind=22 thenbeginfill(2); scannerendelse error(4)endelse error(2)endelse error(3)end;procedure vardec; {var说明处理}beginif kind=21 thenbegin fill(18); scanner endelse error(4);end;procedure listquad; {显示中间代码结果}var i:integer;beginfor i:=cp0 to cp-1 dowith quad[i] do writeln(i:3,mnemonic[op]:6,arg1:6,arg2:6,resul t:6);end;procedure listtable; {显示符号表}var i:integer;beginfor i:=1 to tp dowith table[i] dowriteln(name:5,cat:5,level:5,val:5,addr:5); end;function newtemp:integer; {取一临时变量序号}beginnew:=new+1;newtemp:=newend;procedure bp(p,t:integer); {回填四元式链}var q:integer;beginq:=p;while q<>0 dobeginp:=quad[q].result;quad[q].result:=t;q:=pendend;function merg(p1,p2:integer):integer; {并链}var p:integer;beginif p2=0 then merg:=p1else beginp:=p2;while quad[p].result <> 0 dop:=quad[p].result;quad[p].result:=p1;endend;procedure statement(var schain:integer; sys :symset); {语句分析处理}var i,j,k,q,place:integer;ttc,ffc,slchain,s2chain:integer; function exp(sys:symset):integer; {表达式处理}var addop,e1place,e2place,t:integer;function term(sys:symset):integer; {项处理}var mulop,t1place,t2place,t:integer;function fact(sys:symset):integer; {因子处理}var i,j,k,f,f1,t1:integer;queue:array[1..5] of integer; {存实参队列}begintest([27,21,22],sys,6);if kind=21 then {变量}begini:=entry(id);if i=0 then begin error(11);scanner endelsewith table[i] docase cat of2:beginj:=val;fact:=j+10000;scanner end;{常数} 18:begin j:=lev-level; k:=addr; {lev当前层次} fact:=100*j+k;scanner; {变量地址}end;7: begin scanner;f:=1; {函数调用}if kind=27 then {'<'} beginscanner; k:=4; {k+1是形参开始单元} queue[f]:=exp([28,23]+sys);{')',','}while kind=23 do beginscanner; f:=f+1; queue[f]:=exp([28,23]+sys);end; if kind=28 then {')'} beginscanner;for f1:=1 to f do {传递实在参数} gen(ass,queue[f1],0,dp+k+f1)end else error(22) end; f:=lev-level; {f为相对当前的外层层次}gen(jsr,0,f,addr); {调函数} t1:=newtemp; gen(ass,dp,0,t1); {返回结果在dp单元} fact:=t1; {函数结果作为因子} end end {case}end elseif kind=22 then {数}begin fact:=10000+num;scanner end elseif kind=27 then {'(',表达式)beginscanner;j:=exp([28]+sys);if kind=28 then scanner else error(22);fact:=j;end;test(sys,[27],23);end;begin {项}t1place:=fact(sys+[3,36,37]);{div,*,/}while kind in [3,36,37] dobegin mulop:=kind;scanner;t2place:=fact(sys+[3,36,37]);t:=newtemp;if mulop=36 then gen(mul,t1place,t2place,t)else gen(did,t1place,t2place,t);t1place:=t;end;term:=t1place;end;begin {表达式}if kind in [32,33] then {单目+or-}begin addop:=kind;scanner;e1place:=term(sys+[34,35]);{ 双目+or-}if addop=33 thenbegin t:=newtemp;gen(umi,e1place,0,t);e1place:=t;endendelse e1place:=term(sys+[34,35]);while kind in [34,35] dobeginaddop:=kind;scanner;e2place:=term(sys+[34,35]);t:=newtemp;if addop=34 then gen(add,e1place,e2place,t)else gen(sub,e1place,e2place,t);e1place:=t;end;exp:=e1place;end;procedure condition(var tc,fc:integer;sys:symset); {条件表达式处理} var cond1,cond2,relop:integer;begincond1:=exp([38,43]+sys);if not(kind in [38,43]) thenbegin error(20);scanner endelse begin relop:=kind;scanner;cond2:=exp([38,43]+sys);tc:=cp;case relop of38:gen(jeq,cond1,cond2,0);39:gen(jlt,cond1,cond2,0);40:gen(jgt,cond1,cond2,0);41:gen(jne,cond1,cond2,0);42:gen(jle,cond1,cond2,0);43:gen(jge,cond1,cond2,0);end;fc:=cp;gen(jmp,0,0,0);endend;beginif kind=21 then {赋值语句}begin i:=entry(id);if i=0 then begin error(11);scanner end elseif table[i].cat <>18 thenif table[i].cat=7 then k:=0 elsebegin error(12);i:=0 end {把赋值给常量错}else begin j:=lev-table[i].level;k:=100*j+table[i].addrend;scanner;if kind=44 then {:=}begin scanner; place:=exp(sys);gen(ass,place,0,k); schain:=0;end else error(13);end elseif kind =8 thenbeginscanner;condition(ttc,ffc,sys+[16]);if kind=16 thenbegin scanner;bp(ttc,nxq);statement(slchain,sys);end else error (16);if kind=5 thenbegin scanner;q:=nxq;gen(jmp,0,0,0);bp(ffc,nxq); slchain:=merg(slchain,q);statement(s2chain,sys); end else schain:=merg(ffc,slchain);end elseif kind=19 thenbeginscanner;q:=nxq;condition(ttc,ffc,sys+[4]);if kind=4 then {'do'} begin scanner; bp(ttc,nxq); statement(slchain,sys);bp(slchain,q);gen(jmp,0,0,q);schain:=ffc;end else error(18);end elseif kind =1 thenbeginscanner;statement(schain,sys);while kind=24 do {';'} begin scanner;bp(schain,nxq);statement(schain,sys);end;if kind=6 then {'end'}beginscanner;bp(schain,nxq);schain:=0 endelse error(17); {expected end}end elseif kind=14 then {read 语句}begin scanner;if kind <>27 then error(14) elsebegin scanner;if kind=21 thenbegini:=entry(id);j:=table[i].level;k:=table[i].addr;q:=j*100+k;gen(inp,0,0,q);scanner;while kind=23 do {','} beginscanner; if kind =21 then begin i:=entry(id);j:=table[i].level; k:=table[i].addr;q:=j*100+k;gen(inp,0,0,q)end else error(4); scanner;end;if kind=28 then scanner else error(22) {')'}end else error(4);end;schain:=0;end elseif kind=20 then {write 语句}begin scanner;if kind<>27 then error(14) elserepeatscanner;place:=exp([28,23]+sys);gen(out,0,0,place);until kind<>23;if kind<>28 then error(22);scanner;schain:=0end;test(sys,[],19); {空语句自动匹配}end;begin {'blk' 分程序处理}dp:=5;tp0:=tp;table[tp].addr:=cp;cp0:=cp;gen(jmp,0,0,0); {跳过函数说明的语句体代码}if kind=27 then {'('} {处理形参说明}begin scanner;vardec;while kind=23 do {','}begin scanner;vardec; end;if kind=25 thenbegin scanner;if(kind=9) or (kind=15) then scanner else error(25);end;if kind=28 then scanner else error(22); {')'}end;if kind=25 then {':'}begin scanner;if(kind=9) or (kind=15) then scanner else error(25);end; {type is integer or real?}if kind=24 then scanner else error(5); {';'}if kind=2 then {'const'} {处理常量说明}begin scanner;repeat scanner;while kind=23 do {','}begin scanner;constdec end;if kind=24 then scanner else error(5) {';'}until kind<>21;end;if kind=18 then {'var'} {处理变量说明}begin scanner;repeat vardec;while kind=23 do {','}begin scanner;vardec end;if kind=25 then {':'}begin scanner;if(kind=9) or (kind=15) then scanner else error(25)end;{integer or real}if kind=24 then scanner else error(5)until kind<>21;end;while kind=7 do {'function'} {处理函数说明}begin scanner;if kind=21 thenbegin fill(7);scanner endelse error(4);blk(lev+1,tp,[24]+sys); {递归调用blk}if kind=24 then {';'}begin scanner;test([1,7],[8,19,21]+sys,6){s1=begin,function}endelse error(5);end;test([1],[8,19,21]+sys,7);{s2=if,while,indent,'.','.';'}bp(cp0,nxq);table[tp0].addr:=cp; {cp作为函数入口序号}cp0:=cp;gen(prt,0,0,dp);if kind =1 then {'begin'} {复合语句}beginstatement(chain,[24,6,5,1,8,19,21]+sys);{s=follow(s)+first(s)}if(kind=24) or (kind=26) then {';','.'}begin bp(chain,nxq);gen(ret,0,0,0);endelse error(5);endelse error(8);test(sys,[8,19,21,1,14,20],8);{s2=first(s)}listquad;{listtable} {调试用}end;{0uses wincrt,windos;}procedure interpret;{解释程序}const stacksize=300;cxmax=200;var m:instruction;s:array[0..stacksize]of integer;{data stack area}tp:array[0..10] of integer;{temp variable stack area}p,t,b,t1:INTEGER;K,K0,K1:INTEGER;term1,term2,term3,order:integer;f1,f2:boolean;f:text;function base(n:integer):integer;{找直系静态外层数据区首址}var b1:integer;beginb1:=b;while n>0 dobegin b1:=s[b1-1];n:=n-1 end;base:=b1end;procedure opd(k:integer;var opd1:integer;var flag:boolean);{分析操数作并转化成相应值}var k0,k1:integer;beginflag:=false;if k<1000 then {变量}begin k1:=k div 100;k0:=k mod 100;opd1:=s[base(k1)+k0]endelse if k<2000 then {临时变量}beginopd1:=tp[t1];t1:=t1-1;flag:=true end;opd1:=k-10000; {常量}end;{end; }begint:=0;b:=0;p:=1;t1:=1;s[0]:=0;s[1]:=0;s[2]:=0;s[3]:=0;s[4]:=0; repeatm:=quad[p];p:=p+1;f1:=false;f2:=false;with m dobegin if op=jmp then p:=resultelse if op=prt then t:=result {t 为当前数据区的top+1}else if (op=ass) or(op=umi) thenbegin opd(arg1,term1,f1);if op=umi then term1:=-term1;if result<1000 thens[base(result div 100)+result mod 100]:=term1else begin t1:=t1+1; tp[t1]:=term1 end;end elseif(op=add)or(op=sub)or(op=mul)or(op=did) thenbeginopd(arg1,term1,f1);opd(arg2,term2,f2);if (f1=true)and(f2=true)thenbeginterm3:=term1;term1:=term2;term2:=term3 end;if op=add then term3:=term1+term2else if op=sub then term3:=term1-term2else if op=mul then term3:=term1*term2else term3:=term1 div term2;if result<1000 then s[base(result div 100)+result mod 100]:=term3else begin t1:=t1+1;tp[t1]:=term3 end;end else if(op=jeq)or(op=jgt)or(op=jlt)or(op=jge)or(op =jle)or(op=jne)thenbeginopd(arg1,term1,f1);opd(arg2,term2,f2);if (f1=true)and(f2=true)thenbeginterm3:=term1;term1:=term2;term2:=term3 end;if op=jgt thenbegin if ord(term1>term2)=1 then p:=result endelse if op=jeq thenbegin if ord(term1=term2)=1 then p:=result endelse if op=jlt thenbegin if ord(term1<term2)=1 then p:=result endelse if op=jge thenbegin if ord(term1>=term2)=1 then p:=result endelse if op=jle thenbegin if ord(term1<=term2)=1 then p:=result endelse if ord(term1<>term2)=1 then p:=resultend elseif op=inp thenbegin writeln('input one number!');readln(s[base(result div 100)+(result mod 100)]);end elseif op=out thenbeginopd(result,term1,f1);writeln(term1);end elseif op=jsr thenbegins[t+1]:=base(arg2);s[t+2]:=b;s[t+3]:=p;b:=t;p:=result;{保存静态、动态链和返回地址,建立新数据区和pc}end elseif op=ret then begin t:=b;p:=s[t+3];b:=s[t+2] end{回到老数据区和老pc}end;until p=0;writeln('end');end;begin {main}reserve[0]:='and '; reserve[1]:='begin ';reserve[2]:='const '; reserve[3]:='div ';reserve[4]:='do '; reserve[5]:='else ';reserve[6]:='end '; reserve[7]:='function ';reserve[8]:='if '; reserve[9]:='integer ';reserve[10]:='not '; reserve[11]:='or ';reserve[12]:='procedure';reserve[13]:='program ';reserve[14]:='read '; reserve[15]:='real ';reserve[16]:='then '; reserve[17]:='type ';reserve[18]:='var '; reserve[19]:='while ';reserve[20]:='write ';mnemonic[jmp]:='jmp';mnemonic[prt]:='prt';mnemonic[jeq]:='jeq';mnemonic[jne]:='jne';mnemonic[jgt]:='jgt';mnemonic[jlt]:='jlt';mnemonic[jge]:='jge';mnemonic[jle]:='jle';mnemonic[add]:='add';mnemonic[sub]:='sub';mnemonic[mul]:='mul';mnemonic[did]:='did';mnemonic[ass]:='ass';mnemonic[umi]:='umi';mnemonic[jsr]:='jsr';mnemonic[ret]:='ret';new:=1000;write('Please input source program filename:');readln(filename);assign(f,filename);reset(f);cc:=0; ii:=0;ch:=' ';scanner;while kind<>26 do {'.'}beginwrite(kind,' ');l:=l+1;{if(l mod 10)=0 then writeln;}scanner;end;{上面一段程序用语产生词法分析结果,分调用!}if kind=13 then scanner else error(0);{分析程序首部}if kind=21 then scanner else error(4);if kind=27 thenbeginrepeatscanner;until kind=28;if kind=28 then scanner else error(22)end;if kind<>24 then error(5);cp:=1;tp:=0;blk(0,0,[26]);{'.'}{分析分程序}if kind<>26 then error(9);close(f);if err=0 then interpret;end.。

编译原理课程设计——算术表达式、for、while语句转换为四元式

编译原理课程设计——算术表达式、for、while语句转换为四元式

计算机与信息学院《操作系统与编译原理联合课程设计报告》专题:编译原理部分学生姓名:学号:专业班级:指导教师:2014 年 7 月一、设计目标设计一个语法制导翻译器,将算术表达式、for语句、while语句翻译成四元式。

要求先确定一个定义算术表达式、for语句、while语句的文法,为其设计一个语法分析程序,为每条产生式配备一个语义子程序,按照一遍扫描的语法制导翻译方法,实现翻译程序。

对用户输入的任意一个正确的表达式,程序将其转换成四元式输出。

二、设计思路开发平台:Visual C++ MFC解决这个问题的方案分为以下几个步骤:1.将算数表达式、for语句、while语句转换为四元式的第一步为对读入的表达式进行处理,即删除不必要的空格、回车、换行等,保证之后的步骤能够顺利进行。

2.分析算术表达式、for语句、while语句的文法。

3.通过词法分析判断语句中的每个字符的类型,如:数字、字母、符号等。

4.建立每种文法的LR(0)分析表,通过每个文法的LR(0)分析表对相应的表达式进行语法分析。

5.在语法分析正确的情况下,通过语法分析的中间过程的符号栈输出四元式,四元式的形式为:(op arg1 arg2 result)。

(一)算术表达式转换为四元式将算术表达式转换为四元式首先考虑了括号的问题,对于不同的算术表达式第一步进行词法分析,即确定各种符号的位置。

而括号中的式子是优先级最高的,应该最先进行处理。

我使用了一个数组记录算术表达式中括号的位置,并且定义了first_cc和first_jj函数对括号内的乘除法和加减法分别进行处理。

后将括号内的式子以四元式的形式输出。

通过以上转换,已将原算术表达式中的括号中的内容使用大写字母’A’、’B’……等代替(其中定义声明了change函数,用来将括号部分替换为大写字母)。

新的式子中,只含有加减乘除以及赋值这四种运算,后根据优先级的不同,逐步生成四元式。

其算法流程图如右图所示。

编译原理实验报告(词法分析器语法分析器)

编译原理实验报告(词法分析器语法分析器)

编译原理实验报告实验一一、实验名称:词法分析器的设计二、实验目的:1,词法分析器能够识别简单语言的单词符号2,识别出并输出简单语言的基本字.标示符.无符号整数.运算符.和界符。

三、实验要求:给出一个简单语言单词符号的种别编码词法分析器四、实验原理:1、词法分析程序的算法思想算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是根据扫描到单词符号的第一个字符的种类,拼出相应的单词符号。

2、程序流程图(1(2)扫描子程序3五、实验内容:1、实验分析编写程序时,先定义几个全局变量a[]、token[](均为字符串数组),c,s( char型),i,j,k (int型),a[]用来存放输入的字符串,token[]另一个则用来帮助识别单词符号,s用来表示正在分析的字符。

字符串输入之后,逐个分析输入字符,判断其是否‘#’,若是表示字符串输入分析完毕,结束分析程序,若否则通过int digit(char c)、int letter(char c)判断其是数字,字符还是算术符,分别为用以判断数字或字符的情况,算术符的判断可以在switch语句中进行,还要通过函数int lookup(char token[])来判断标识符和保留字。

2 实验词法分析器源程序:#include <stdio.h>#include <math.h>#include <string.h>int i,j,k;char c,s,a[20],token[20]={'0'};int letter(char s){if((s>=97)&&(s<=122)) return(1);else return(0);}int digit(char s){if((s>=48)&&(s<=57)) return(1);else return(0);}void get(){s=a[i];i=i+1;}void retract(){i=i-1;}int lookup(char token[20]){if(strcmp(token,"while")==0) return(1);else if(strcmp(token,"if")==0) return(2);else if(strcmp(token,"else")==0) return(3);else if(strcmp(token,"switch")==0) return(4);else if(strcmp(token,"case")==0) return(5);else return(0);}void main(){printf("please input string :\n");i=0;do{i=i+1;scanf("%c",&a[i]);}while(a[i]!='#');i=1;j=0;get();while(s!='#'){ memset(token,0,20);switch(s){case 'a':case 'b':case 'c':case 'd':case 'e':case 'f':case 'g':case 'h':case 'i':case 'j':case 'k':case 'l':case 'm':case 'n':case 'o':case 'p':case 'q':case 'r':case 's':case 't':case 'u':case 'v':case 'w':case 'x':case 'y':case 'z':while(letter(s)||digit(s)){token[j]=s;j=j+1;get();}retract();k=lookup(token);if(k==0)printf("(%d,%s)",6,token);else printf("(%d,-)",k);break;case '0':case '1':case '2':case '3':case '4':case '5':case '6':case '7':case '8':case '9':while(digit(s)){token[j]=s;j=j+1;get();}retract();printf("%d,%s",7,token);break;case '+':printf("('+',NULL)");break;case '-':printf("('-',null)");break; case '*':printf("('*',null)");break;case '<':get();if(s=='=') printf("(relop,LE)");else{retract();printf("(relop,LT)");}break;case '=':get();if(s=='=')printf("(relop,EQ)");else{retract();printf("('=',null)");}break;case ';':printf("(;,null)");break;case ' ':break;default:printf("!\n");}j=0;get();} }六:实验结果:实验二一、实验名称:语法分析器的设计二、实验目的:用C语言编写对一个算术表达式实现语法分析的语法分析程序,并以四元式的形式输出,以加深对语法语义分析原理的理解,掌握语法分析程序的实现方法和技术。

编译原理实验 中间代码生成

编译原理实验 中间代码生成

实验四中间代码生成一.实验目的:掌握中间代码的四种形式(逆波兰式、语法树、三元式、四元式)。

二.实验内容:1、逆波兰式定义:将运算对象写在前面,而把运算符号写在后面。

用这种表示法表示的表达式也称做后缀式。

2、抽象(语法)树:运算对象作为叶子结点,运算符作为内部结点。

3、三元式:形式序号:(op,arg1,arg2)4、四元式:形式(op,arg1,arg2,result)三、以逆波兰式为例的实验设计思想及算法(1)首先构造一个运算符栈,此运算符在栈内遵循越往栈顶优先级越高的原则。

(2)读入一个用中缀表示的简单算术表达式,为方便起见,设该简单算术表达式的右端多加上了优先级最低的特殊符号“#”。

(3)从左至右扫描该算术表达式,从第一个字符开始判断,如果该字符是数字,则分析到该数字串的结束并将该数字串直接输出。

(4)如果不是数字,该字符则是运算符,此时需比较优先关系。

做法如下:将该字符与运算符栈顶的运算符的优先关系相比较。

如果,该字符优先关系高于此运算符栈顶的运算符,则将该运算符入栈。

倘若不是的话,则将此运算符栈顶的运算符从栈中弹出,将该字符入栈。

(5)重复上述操作(1)-(2)直至扫描完整个简单算术表达式,确定所有字符都得到正确处理,我们便可以将中缀式表示的简单算术表达式转化为逆波兰表示的简单算术表达式。

四、程序代码://这是一个由中缀式生成后缀式的程序#include<iostream.h>#include<string.h>#include<math.h>#include<ctype.h>#define maxbuffer 64void main(){char display_out(char out_ch[maxbuffer], char ch[32]);//int caculate_array(char out_ch[32]);static int i=0;static int j=0;char ch[maxbuffer],s[maxbuffer],out[maxbuffer];cout<<"请输入中缀表达式: ";cin>>ch;for(i=0;i<maxbuffer;i++){out[i]=ch[i];}cout<<"请确认您输入的表达式:"; while(out[j]!='#'){cout<<out[j];j++;}cout<<'#'<<endl;display_out(s,out);//caculate_array;}char display_out(char out_ch[32],char ch[]) {int top=-1;int i=0,data[maxbuffer],n;int j=0;char sta[20];while(ch[i]!='#'){if(isalnum(ch[i])){while(isalnum(ch[i])){out_ch[j]=ch[i];j++;i++;}out_ch[j]=' ';j++;}else{switch(ch[i]){case '+':case '-': if(sta[top]=='('||top==-1){top++;sta[top]=ch[i];i++;}else{//j--;out_ch[j]=sta[top];j++;top--;//i++;}break;//break;case '*':case '/':if(sta[top]=='*'&&sta[top]=='/'){out_ch[j]=sta[top];j++;//i++;top--;}else{top++;sta[top]=ch[i];i++;}break ;//break;case '(':top++;sta[top]=ch[i];i++;break;case ')':if(sta[top]=='('){top--;i++;}if(top==-1){//cout<<"错误: 第"<<j<<"个位置的")"没有找到与之匹配的"(""; ch[i]='#';j=0;}else{//while(sta[top]!=‘(‘){out_ch[j]=sta[top];top--;j++;//}break;}break;/*case ‘#‘: out_ch[j]=‘#‘;j++;break;*/default:cout<<" your input is error"<<endl; ch[i]='#';j=0;break;}}}while(top!=-1){out_ch[j]=sta[top];j++;top--;}out_ch[j]='#';n=0;cout<<"逆波兰表达式为: ";while(out_ch[n]!='#'){cout<<out_ch[n];n++;}cout<<endl;j=0;return out_ch[maxbuffer];}五、实验结果:要求:自己给出3个测试用例,观察结果。

编译原理报告三四元式

编译原理报告三四元式

四元式生成一、目的和要求1、目的通过上机实习,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法范畴变换为某种中间代码的语义翻译方法。

2、要求(1)选用目前世界上普遍采用的语义分析方法──语法制导翻译技术。

(2)语义分析对象重点考虑经过语法分析后已是正确的语法范畴,实习重点是语义子程序。

(3)中间代码选用比较常见的形式,例如四元式。

二、背景知识属性文法:A=(G,V,F),其中:G:一个CFG, 属性文法的基础。

V:有穷的属性集:每个属性与一个文法符号相关联,这些属性代表与文法符号相关的语义信息,如:类型、地址、值、代码、符号表内容等等。

属性与变量一样,可以进行计算和传递,属性加工的过程即是语义处理的过程。

属性加工与语法分析同时进行。

属性的表示:标始符(或数),写在相应文法的下边,点记法:E.Val,E.Place,E.Type…。

F:关于属性的属性断言或一组属性的计算规则(称为语义规则)。

断言或语义规则与一个产生式相联,只引用该产生式左端或右端的终结符或非终结符相联的属性。

属性有两类:综合属性:归约型属性,用于“自下而上”传递信息。

继承属性:推导型属性,用于“自上而下”传递信息。

综合属性的例子:非终结符E、T及F都有一个综合属性val,符号digit有一个综合属性,它的值由词法分析器提供。

与产生式L→E对应的语义规则仅仅是打印由E产生的算术表达式的值的一个过程,我们可认为这条规则定义了L的一个虚属性。

某些非终结符加上标是为了区分一个产生式中同一非终结符多次出现。

设表达式为3*5+4,则语义动作打印数值19。

L-属性文法:一个属性文法称为L-属性文法,如果对于每个产生式A→X1X2…Xn,满足:1、Xj(1≤j≤n)的继承属性仅依赖于下述属性值中的一种:A的继承属性或产生式右部位v于Xj左边的符号X1,X2,…,Xj-1的属性。

2、A的综合属性,仅依赖于下述属性值中的一种:A的继承属性或产生式右部符号Xj(除自身外)的任意属性。

西工大编译原理实验报告

西工大编译原理实验报告

编译原理实验报告学院:计算机学院班级:10031101姓名:学号:日期:目录1 实验情况概述 (1)2 主要功能 (2)3 软件总体结构 (4)4 详细设计 (5)5 实验总结 (8)5.1 调试和bug修改总结...................................................................... 错误!未定义书签。

5.2 测试和结果 (8)5.3 实验小结 (10)1 实验情况概述本实验的主要任务是编写一个小型类Pascal语言的编译器。

该编译器应当能够将输入的源程序文本翻译为相应的四元式,并输出符号表。

实验环境:词法分析器采用flex;语法分析器采用bison;软件开发使用Visual C++ 6.0。

功能:1.能够处理整型、实型两种类型的变量定义;2.能够识别注释;3.能够处理程序结构的定义;4.能够识别算术、关系和逻辑表达式;5.能够识别常量定义;6.能够识别顺序、赋值、循环、选择、复合语句等基本的语句类型。

输出结果:1.将输入的文本输出为四元式序列;2.输出符号表。

2 主要功能1.基本功能:根据词法分析处理说明文件(.l)和语法分析处理说明文件(.y)来识别输入的测试文件是否符合MiniPascal所规定的语法要求;若测试文件符合其语法要求,则输出程序正确运行步骤的四元式表示以及程序运行过程中所用到的的符号表;若不符合,则发生错误,程序无法运行,并提示错误信息。

四元式基本形式:(op,arg1,arg2,result),其中op为一个二元(也可以是一元或零元)运算符;arg1,arg2分别为它的两个运算(或操作)对象,它们可以是变量、常数或系统定义的临时变量名;运算结果将放入result中。

2.扩展功能:定义了如下两类四元式:(jrop,A1,A2,p)—当关系A1 rop A2成立时,转向第p四元式;(j,0,0,p)—无条件转向第p四元式。

编译原理E课内实践报告:WHILE循环语句的翻译程序设计与实现,递归下降法,输出四元式

编译原理E课内实践报告:WHILE循环语句的翻译程序设计与实现,递归下降法,输出四元式

文法及属性文法的描述 ............................................................................................... 2 2.1 2.2 文法描述 ............................................................................................................. 2 属性文法描述 ..................................................................................................... 3
2.2 属性文法描述
形式上讲,属性文法是一个三元组 :A=(G,V,F), 其中: ➢ G:是一个上下文无关文法; ➢ V:有穷的属性集,每个属性与文法的一个终结符或非终结符相连 ,这些属性代表与 文法符号相关信息; ➢ F:关于属性的属性断言或一组属性的计算规则(称为语义规则) 。 断言或语义规则 与一个产生式相联,只引用该产生式左端或右端的终结符或非终结符相联的属性。 属性文法中的属性分成两类:继承属性和综合属性。 ➢ 综合属性(synthesized attribute) :如果 b 是 A 的属性,c1 , c2 , …, ck 是产生式右 部文法符号的属性或 A 的其它属性,则称 b 是文法符号 A 的综合属性。 ➢ 继承属性(inherited attribute):如果 b 是产生式右部某个文法符号 X 的属性,并且 c1,c2,…,ck 是 A 或产生式右部文法符号的属性, 则称 b 是文法符号 X 的继承属性。
3

编译原理实验报告3

编译原理实验报告3

编译原理实验报告3编译原理实验报告——表达式语法分析——表达式语法分析表达式语法分析实验报告一、实验题目设计一个简单的表达式语法分析器(采用递归下降方法设计实现)二、实验目的1、了解形式语言基础及其文法运算;2、熟悉语法分析原理及 4 种常用的语法分析方法;其中:四种算法为(1)设计算术表达式的递归下降子程序分析算法(2)设计算术表达式的 LL(1) 分析算法(3)设计算术表达式的简单优先分析算法(4)设计算术表达式的SLR(1) 分析算法3、选择上述一种方法并设计一个表达式的语法分析器。

(本实验设计的是递归下降的表达式语法分析器)三、实验内容1.设计递归下降语法分析器算法;2.编写代码并上机调试运行通过; 3、写出试验体会及心得。

四、实验要求1、给出算术表达式文法2、进行适当的文法变换3、选择一种语法分析的方法,并说明其原理4、根据原理给出相应的算法设计,说明主要的数据结构并画出算法流程图5、编写代码并上机调试运行通过6、写出程序运行结果7、写出相应的文档以及代码注释8、输入——表达式;输出——表达式语法是否正确。

五、递归下降的表达式语法分析器设计概要1.算术表达式文法.G(E):E T F 2.文法变换:文法变换:G’(E): E->TE' E'->+TE'|ε T->FT' T'->*FT'|ε F->(E)|I E +T | T T* F | F i | (E)3. 递归下降子程序框图:递归下降子程序框图:六、实验设计源程序#includechar inputstream[50]; int temp=0; int right; void e(); void e1(); void t(); void t1(); void f(); void main() { right=1;//存储输入句子//数组下标 //判断输出信息cout<<"请输入您要分析的字符串以#结束(^为空字符):"<>inputstream; e(); if((inputstream[temp]=='#')&&right) cout<<"分析成功"<<<"e-="" cout<<"分析失败"<TE'"<<<"e'-="" e1()="" e1();="" if(inputstream[temp]="='+')" t();="" void="" {="" }="">+TE'"<e1(); } else if (inputstream[temp]!='#'||inputstream[temp]!=')') { cout<<"T'->^"<<<"t-="" else="" return="" right="0;" t()="" void="" {="" }="">FT'"<<<"t'-="" f();="" if(inputstream[temp]="='*')" t1()="" t1();="" void="" {="" }="">*FT'"<<<"t'-="" else="" f();="" if="" t1();="" temp++;="" {="" }="">^"<} } void f() { if(inputstream[temp]=='i') { cout<<"F->i"<if(inputstream[temp]=='(') { cout<<"F->(E)"<<<"f-="" e();="" if(inputstream[temp]="=')')" temp++;="" {="">(E)"<七、运行结果八、实验思考题语法分析的任务是什么?语法分析的任务是什么?答:语法分析器的任务是识别和处理比单词更大的语法单位,如:程序设计语言中的表达式、各种说明和语句乃至全部源程序,指出其中的语法错误;必要时,可生成内部形式,便于下一阶段处理。

编译原理LL1语法分析算法的实现(token转四元式)

编译原理LL1语法分析算法的实现(token转四元式)

编译原理LL1语法分析算法的实现(token转四元式)编译原理LL1语法分析算法的实现(token转四元式)博客分类:•c++/数据结构/算法算法F#J##include <stdio.h>#include <stack>#include <vector>#include <iostream>#include <fstream>#include <malloc.h>using namespace std;//token结构struct token {int code; //token的类别,code为1则是符号,为2则是数字char value; //token的值};typedef struct token tokens;vector<tokens> tokenBuffer; //用于存储token的缓冲区stack<tokens> tokenBuffers;//产生式结构struct formula {int id; //产生式编号char left; //产生式左部char right[256]; //产生式右部int r_length; //产生式右部长度};typedef struct formula formulas;formulas formulaBuffer[11]; //用于存储产生式的缓冲区//四元式结构struct expression {char symbol; //操作符char num1; //第一个操作数char num2; //第二个操作数char result; //结果变量};typedef struct expression expressions;vector<expressions> expressionBuffer; //用于存储四元式的缓冲区int expressionCount = 0; //四元式个数//分析表中每一项的结构struct analysisTable {char currentState; //分析栈的栈顶符号char currentToken; //当前字符int expressionNum; //对应的产生式编号};typedef struct analysisTable analysisT ables;vector<analysisTables> analysisTableBuffer; //LL1分析表的缓冲区stack<char> analysisStack; //分析栈stack<char> sematicStack; //语义栈//初始化LL1分析表void initialAnalysisTableBuffer() { analysisTables* temp1a = new analysisTable; analysisTables* temp1b = new analysisTable; analysisTables* temp1c = new analysisTable; analysisTables* temp2 = new analysisTable; analysisTables* temp3 = new analysisTable; analysisTables* temp4 = new analysisTable; analysisTables* temp5 = new analysisTable; analysisTables* temp6 = new analysisTable; analysisTables* temp7a = new analysisTable; analysisTables* temp7b = new analysisTable; analysisTables* temp7c = new analysisTable; analysisTables* temp8 = new analysisTable; analysisTables* temp9 = new analysisTable; analysisTables* temp10 = new analysisTable; analysisTables* temp11 = new analysisTable; analysisTables* temp12 = new analysisTable; analysisTables* temp13 = new analysisTable; analysisTables* temp14 = new analysisTable; analysisTables* temp15a = new analysisTable; analysisTables* temp15b = new analysisTable; analysisTables* temp15c = new analysisTable; analysisTables* temp16 = new analysisTable;temp1a->expressionNum = 1;temp1a->currentState = 'E';temp1a->currentT oken = 'a';temp1b->expressionNum = 1; temp1b->currentState = 'E'; temp1b->currentT oken = 'b';temp1c->expressionNum = 1; temp1c->currentState = 'E'; temp1c->currentT oken = 'c';temp2->expressionNum = 1; temp2->currentState = 'E'; temp2->currentToken = '(';temp3->expressionNum = 2; temp3->currentState = 'L'; temp3->currentToken = '+';temp4->expressionNum = 3; temp4->currentState = 'L'; temp4->currentToken = '-';temp5->expressionNum = 4; temp5->currentState = 'L'; temp5->currentToken = ')';temp6->expressionNum = 4; temp6->currentState = 'L'; temp6->currentToken = '#';temp7a->expressionNum = 5;temp7a->currentT oken = 'a';temp7b->expressionNum = 5; temp7b->currentState = 'T'; temp7b->currentT oken = 'b';temp7c->expressionNum = 5; temp7c->currentState = 'T'; temp7c->currentT oken = 'c';temp8->expressionNum = 5; temp8->currentState = 'T'; temp8->currentToken = '(';temp9->expressionNum = 8; temp9->currentState = 'M'; temp9->currentToken = '+';temp10->expressionNum = 8; temp10->currentState = 'M'; temp10->currentT oken = '-';temp11->expressionNum = 6; temp11->currentState = 'M'; temp11->currentT oken = '*';temp12->expressionNum = 7;temp12->currentT oken = '/';temp13->expressionNum = 8;temp13->currentState = 'M';temp13->currentT oken = ')';temp14->expressionNum = 8;temp14->currentState = 'M';temp14->currentT oken = '#';temp15a->expressionNum = 9;temp15a->currentState = 'F';temp15a->currentToken = 'a';temp15b->expressionNum = 9;temp15b->currentState = 'F';temp15b->currentToken = 'b';temp15c->expressionNum = 9;temp15c->currentState = 'F';temp15c->currentToken = 'c';temp16->expressionNum = 10;temp16->currentState = 'F';temp16->currentT oken = '(';analysisTableBuffer.push_back(*temp1a); analysisTableBuffer.push_back(*temp1b); analysisTableBuffer.push_back(*temp1c);analysisTableBuffer.push_back(*temp2);analysisTableBuffer.push_back(*temp3);analysisTableBuffer.push_back(*temp4);analysisTableBuffer.push_back(*temp5);analysisTableBuffer.push_back(*temp6);analysisTableBuffer.push_back(*temp7a);analysisTableBuffer.push_back(*temp7b);analysisTableBuffer.push_back(*temp7c);analysisTableBuffer.push_back(*temp8);analysisTableBuffer.push_back(*temp9);analysisTableBuffer.push_back(*temp10);analysisTableBuffer.push_back(*temp11);analysisTableBuffer.push_back(*temp12);analysisTableBuffer.push_back(*temp13);analysisTableBuffer.push_back(*temp14);analysisTableBuffer.push_back(*temp15a);analysisTableBuffer.push_back(*temp15b);analysisTableBuffer.push_back(*temp15c);analysisTableBuffer.push_back(*temp16);}//由于本次实验主要是考察语法分析和语义分析,所以为了节省时间不采用查表的方式获取token,而是直接初始化token的值。

编译原理课程设计-翻译成四元式

编译原理课程设计-翻译成四元式

编译原理课程设计一、课程设计题目:第(20)题:写一程序,演示对给定下标变量赋值语句文法,且已知建立内情向量,对给定的下标变量赋值语句翻译成四元式。

二、编程环境:在Turboc下编程运行,可随意输入数组维数,对输入的给定下标变量赋值语句翻译成四元式。

三、设计原理:一个含数组元素的赋值语句的文法模式可为下所示:A->V:=E V->i[elist]|i elist->elist,E|E E->E+E|(E)|V 即一个赋值语句A是一个V(指变量)后跟赋值号:=和一个算术表达式E。

为了计算数组元素的VARPART,需要把关于变量V的文法改写成:V->elist]|i elist->elist,E|i[E 把数组名i和最左的下标式写在一起的目的是使在整个下标串elist的翻译过程中随时都能知道数组名i的符号表入口,从而随时能够了解登记在符号表中的有关数i的全部信息。

为了计算VARPART的四元式序列,需要知道数组名的符号表入口,下标式的个数,将VARPART的中间结果单元名字在符号表中的位置等。

还要根据含有数组元素的赋值句的翻译规则进行翻译。

四、设计过程:数组元素a[i1,i2,…,in]地址D的计算公式为: D=CONSPART+VARPARTCONSPART=a-c ,其中c是常数(d2d3…dn+d3…dn+…+dn+1).由题目已知建立了内情向量表,但是为了方便起见还是要输入数组的维数以及是几乘几的数组。

为了计算常数c编了一个专门的函数Conspart(int a[],DIM);其核心是:for(j=1;j<DIM;j++)c=c*a[j]+1;为了将四元式的计算VARPART 的过程演示出来,知道其值为(i1d2d3…dn +i2d3d4…dn+…+in-1dn+in),即可通过一个循环来计算VARPART的值,如下VARPART:=VARPART*dk+1+ik+1因此也可通过循环来演示计算四元式VARPART的过程。

编译原理四元式

编译原理四元式

编译原理四元式
编译原理中的四元式是一种中间代码形式,用于表示源程序在编译过程中的中间结果。

四元式由四个部分组成,分别是操作符(operator)、操作数1(operand1)、操作数2(operand2)和结果(result)。

在编译原理中,四元式通常用于表示程序的中间代码,可以通过一系列的四元式来表达源程序的语义。

四元式的优点是可以简化编译器的实现,同时也可以方便地进行优化和代码生成等操作。

在实际的编译器实现中,四元式的具体形式和表示方法可能有所不同,但通常都包含上述四个部分。

例如,在编译器中,可以通过使用类似以下的四元式来表示一个简单的赋值语句:
代码
t1 = add(a, b)
t2 = sub(c, d)
t3 = eq(t1, t2)
其中,add和sub是操作符,a和b、c和d是操作数1和操作数2,t1、t2和t3是结果。

这个四元式组表示了以下代码:
代码
if (a + b == c - d) {
// do something
}
在编译器的后续处理中,四元式可以被进一步优化和转换,最终生成目标代码。

因此,四元式在编译器的实现中起着重要的作用。

目标代码中间代码生成-四元式设计文档

目标代码中间代码生成-四元式设计文档

工程第一神刀公子编译原理实验实验名称:中间代码生成程序设计指导老师:轻语专业:计算机科学与技术班级:LOL学号:0000001姓名:神刀公子2008.6.22实验任务:在实验4的基础上,完成以下描述赋值语句和算数表达式文法G[A]的语法制导生成中间代码四元式的过程。

A-->V:=E V--><标识符> E→E+T|E-T|T T→T*F|T/F|F F→(E)|<标识符>说明:标识符的定义参见实验一程序的功能描述从文件中读入表达式,输出其四元式的结果序列本程序只能生成赋值语句及算数表达式中间代码的四元式不能生成逻辑表达式及其他复杂语句中间代码的四元式,其功能还需要进一步完善。

程序测试方案测试用例一:d=a+b*(3*n)/(b-a)测试用例二:x=x*(x+y-(x-y)/(z+x)-y)实验总结此程序基本达到了实验要求,能够生成简单的赋值及算数表达式中间代码的四元式,但其功能实在是过于简单。

第一次调试通过后程序还存在以下不足:(1)此程序只能从文件中读入一个表达式,读入多个则会出错;(2)所读入的表达式中若含有多于一个括号,程序会出错;(3)括号内若多于一个表达式则会出错;(4)在测试用例二中的分析过程明显是错误的,这足以看出程序的漏洞很多但经过进一步优化算法,以上问题基本解决,但程序中仍然存在很多不足,例如时间效率和空间效率方面做的还不够好,要改善这些不足还需要进一步完善程序,在以后的学习生活中我会根据所学知识的不断深入而不断完善此程序,争取使其功能更加强大。

经过这次实验我更加深刻的理解了生成中间代码的算法思想,及时的将所学知识用于实践,更加深刻的掌握了所学知识。

附录#include<stdlib.h>#include<fstream>#include<iostream>using namespace std;#define MAX 100int m=0,sum=0;//sum用于计算运算符的个数//m用于标记输入表达式中字符的个数char JG='A';char str[MAX];//用于存输入表达式int token=0;//左括号的标志/***********用于更改计算后数组中的值**************/void change(int e){int f=e+2;char ch=str[f];if(ch>='A'&&ch<='Z'){for(int l=0;l<m+10;l++) {if(str[l]==ch)str[l]=JG;}}if(str[e]>='A'&&str[e]<='Z') {for(int i=0;i<m;i++){if(str[i]==str[e])str[i]=JG;}}}void chengchuchuli(int i,int m){i++;for( ;i<=m-1;i++)//处理乘除运算{if(str[i]=='*'||str[i]=='/'){cout<<"("<<str[i]<<" "<<str[i-1]<<" "<<str[i+1]<<" "<<JG<<")"<<endl;change(i-1);str[i-1]=str[i]=str[i+1]=JG;sum--;JG=(char)(int)JG++;}}void jiajianchuli(int j,int m){j++;for( ;j<=m-1;j++)//处理加减运算{if(str[j]=='+'||str[j]=='-'){cout<<"("<<str[j]<<" "<<str[j-1]<<" "<<str[j+1]<<" "<<JG<<")"<<endl;change(j-1);str[j-1]=str[j]=str[j+1]=JG;sum--;JG=(char)(int)JG++;}}}/*扫描一遍从文件中读入表达式*/void scan(FILE *fin)_ {int p[MAX];char ch='a';int c=-1,q=0;while(ch!=EOF){ch=getc(fin);while(ch==' '||ch=='\n'||ch=='\t') ch=getc(fin);//消除空格和换行符str[m++]=ch;if(ch=='='||ch=='+'||ch=='-'||ch=='*'||ch=='/') sum++;else if(ch=='('){p[++c]=m-1;}else if(ch==')'){_ q=m-1;chengchuchuli(p[c],q);//从左括号处理到又括号jiajianchuli(p[c],q);JG=(char)(int)JG--;str[p[c]]=str[m-1]=JG;c--;JG=(char)(int)JG++;}}}/*对表达是进行处理并输出部分四元式*/void siyuanshi(){for(int i=0;i<=m-1;i++)//处理乘除运算{if(str[i]=='*'||str[i]=='/'){cout<<"("<<str[i]<<" "<<str[i-1]<<" "<<str[i+1]<<"_ "<<JG<<")"<<endl;change(i-1);str[i-1]=str[i]=str[i+1]=JG;sum--;JG=(char)(int)JG++;}}for(int j=0;j<=m-1;j++)//处理加减运算{if(str[j]=='+'||str[j]=='-'){cout<<"("<<str[j]<<" "<<str[j-1]<<" "<<str[j+1]<<" "<<JG<<")"<<endl;change(j-1);str[j-1]=str[j]=str[j+1]=JG;sum--;JG=(char)(int)JG++;}}for(int k=0;k<=m-1;k++)//处理赋值运算{if(str[k]=='='){JG=(char)(int)--JG;cout<<"("<<str[k]<<" "<<str[k+1]<<" "<<" "<<" "<<str[k-1]<<")"<<endl;sum--;change(k+1);str[k-1]=JG;}}}/***************主函数*******************/void main(){char in[MAX]; //用于接收输入输出文件名FILE *fin; //用于指向输入输出文件的指针cout<<"请输入源程序文件名(例如ceshi.txt):";cin>>in;cout<<endl;if ((fin=fopen(in,"r"))==NULL) //判断输入文件名是否正确{cout<<endl<<"打开词法分析输入文件出错!"<<endl;}cout<<"四元式如下:"<<endl;scan(fin);//调用函数从文件中读入表达式/********调用生成四元式的函数********/siyuanshi();/*********判断是否成功**********/if(sum==0) cout<<"成功!"<<endl;else cout<<"有错误!"<<endl;//关闭文件fclose(fin);}。

编译原理课程设计WHILE循环语句的翻译程序设计(递归下降法、输出四元式)

编译原理课程设计WHILE循环语句的翻译程序设计(递归下降法、输出四元式)

学号:课程设计题目WHILE循环语句的翻译程序设计(递归下降法、输出四元式)学院计算机科学与技术专业计算机科学与技术班级计算机班姓名指导教师2012 年 1 月 6 日目录1.问题描述 (3)1.1问题描述 (3)1.2主要任务 (3)1.3测试数据 (3)2文法及属性文法的描述 (3)2.1文法的描述 (3)2.2 while-do循环语句的文法 (4)2.3递归文法的优化 (4)2.4属性文法的描述 (5)3.语法分析方法描述 (6)3.1程序设计对文法的要求 (6)3.2语法分析的思想 (7)3.3递归下降文法实现原理 (7)3.4中间代码形式 (8)4简要的分析与概要设计 (8)4.1全局程序的概要设计 (8)4.2词法分析 (9)4.3递归下降翻译器的设计 (9)4.4语法制导翻译 (10)5详细的算法描述 (10)5.1算法描述 (10)5.2运行结果 (14)6. 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等). 156.1研制过程 (15)6.2本设计的评价、特点 (16)6.3感受和体会 (16)6.4对程序改进的想法 (17)课程设计任务书学生姓名:专业班级:计算机班指导教师:工作单位:计算机科学与技术学院题目: WHILE循环语句的翻译程序设计(递归下降法、输出四元式)初始条件:理论:学完编译课程,掌握一种计算机高级语言的使用。

实践:计算机实验室提供计算机及软件环境。

如果自己有计算机可以在其上进行设计。

要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)(1)写出符合给定的语法分析方法的文法及属性文法。

(2)完成题目要求的中间代码四元式的描述。

(3)写出给定的语法分析方法的思想,完成语法分析和语义分析程序设计。

(4)编制好分析程序后,设计若干用例,上机测试并通过所设计的分析程序。

(5)设计报告格式按附件要求书写。

课程设计报告书正文的内容应包括:1 系统描述(问题域描述);2 文法及属性文法的描述;3 语法分析方法描述及语法分析表设计;4 按给定的题目给出中间代码形式的描述及中间代码序列的结构设计;5 编译系统的概要设计;6 详细的算法描述(流程图或伪代码);7 软件的测试方法和测试结果;8 研制报告(研制过程,本设计的评价、特点、不足、收获与体会等);9 参考文献(按公开发表的规范书写)。

逆波兰到四元式生成 -回复

逆波兰到四元式生成 -回复

逆波兰到四元式生成-回复逆波兰表示法是一种数学表达式的表示方法,也称为后缀表示法。

它与常见的中缀表示法不同,它将操作符放在操作数的后面。

逆波兰表示法使得数学表达式的计算变得简单而直观,并且可以方便地进行计算机处理。

四元式生成是一种将逆波兰表示法转换为计算机可执行指令的方法。

四元式由四个部分组成:操作符、源操作数1、源操作数2和结果操作数。

四元式是一种简单且有效的指令形式,可以直接在计算机上执行。

本文将一步一步地回答如何从逆波兰表示式生成四元式,以帮助读者更好地理解这个过程。

第一步:定义四元式的数据结构在转换逆波兰表示式为四元式之前,我们需要先定义四元式的数据结构。

一个基本的四元式可以定义如下:class Quadruple:def __init__(self, operator, source1, source2, result):self.operator = operatorself.source1 = source1self.source2 = source2self.result = result其中,operator表示操作符,可以是加减乘除等常见的算术运算符;source1和source2表示操作数;result表示运算结果。

在这个基本的四元式结构上,我们可以根据实际需求添加其他属性,比如类型、作用域等。

第二步:从逆波兰表示式中读取操作符和操作数逆波兰表示式可以用字符串或列表表示。

首先,我们需要将逆波兰表示式存储在某个数据结构中,如一个列表。

rpn_expr = ["2", "3", "+"]接下来,我们需要遍历这个列表,并按照逆波兰表示法的规则提取操作符和操作数。

quadruples = []for token in rpn_expr:if token in ["+", "-", "*", "/"]:operator = tokensource2 = quadruples.pop()source1 = quadruples.pop()result = "t" + str(len(quadruples) + 1) # 为结果操作数生成一个临时变量quadruples.append(Quadruple(operator, source1, source2, result))else:quadruples.append(token) # 将操作数直接添加到四元式列表中在遍历过程中,如果当前的操作符是加减乘除之一,那么我们就从四元式列表中弹出两个操作数,并为结果操作数生成一个临时变量。

计算机编译原理实验生成四元式序列

计算机编译原理实验生成四元式序列

西北师大学计算机科学与工程学院学生实验报告
printf("(%c %c %c) \n",string[k],string[k+1], string[k-1],tempvar);
count--;
string[k-1]=tempvar;
}
}
}
实验结果:
实验总结:
通过本次实验我完成生成四元式的语法分析程序,掌握的结合语法分析实现翻译方案的思路和方法。

本次实验还是遇到许多困难,通过上网查看以及查看许多书籍,最终还是完成了本次试验,还是收获挺大的。

但是实验中还存在着许多不足,如规则的顺序,first集合的求解等,还需不断完善。

实验评语:
该学生在本次试验中完成生成四元式的语法分析程序,基本掌握的结合语法分析实现翻译方案的思路和方法,但是程序在一些细节及特殊文法的处理上还需要进一步完善,如编程时注意编程风格:空行的使用、注释的使用、缩进的使用,如果遇到错误的表达。

4、语法制导四元式(算术表达式)生成器

4、语法制导四元式(算术表达式)生成器

辽宁师范大学计算机与信息技术学院综合性实验报告课程名称:编译技术实验题目:语法制导四元式(算术表达式)生成器学生姓名:专业:计算机科学与技术学号:实验日期:2015.06.05【实验目的】1.理解语法分析器原理、语法制导翻译的过程实质。

2.学会将语法分析所识别的语法成分变换为中间代码形式中的逆波兰记号形式的语义分析方法,编程实现在对一个算术表达式进行语法分析过程的基础上进行语义分析。

【实验内容】1.输入算术表达式源语言形式,输出语法分析过程(输入流变化过程)和四元式序列。

2.对于一个给定的算术表达式,首先通过词法分析过程识别出各类语法成分输出至文件中,然后采用预测分析的方法对其进行分析和语法检查,并给出具体的分析过程,包括分析步骤、分析栈、剩余符号以及所用的产生式。

在此基础上,向文法中插入语义动作,在语法分析过程中遇到语义动作就做相应的翻译工作,最终将结果(算术表达式的逆波兰式)输出到源文件中。

【实验过程】一、判断文法是否为LL(1)文法(1)E->E+E(2)E->E*E(3)E->i|-E由于此文法含左递归,消除左递归,确定算法优先次序,使文法变为:(1)E->TG(2)G->+TG|^(3)T->FS(4)S->*FS|^(5)F->i|-E1.可推出^2.各非终结符的FIRST集合如下:FIRST(E)={(,i}FIRST(G)={+, ∅}FIRST(T)={(,i}FIRST(S)={*,∅}FIRST(F)={(,i}3.各非终结符的FOLLOW集合为:FOLLOW(E)={),#}FOLLOW(G)={),#}FOLLOW(T)={+,),#}FOLLOW(S)={+,),#}FOLLOW(F)={*,+,),#}4.各产生式的SELECT集合为:SELECT(E->TG)={(,i}SELECT(G->+TG)={+}SELECT(G->^)={),#}SELECT(T->FS)={(,i}SELECT(S->*FS)={*}SELECT(S->^)={+,),#}SELECT(F->-E)={(}SELECT(F->i)={i}5.因为:SELECT(G->+TG)∩SELECT(G->∅) = {+}∩{),#} = ∅SELECT(S->*FS)∩SELECT(S->∅) = {*}∩{+,),#} = ∅SELECT(F->-E)∩SELECT(F->i) = {i}∩{(} = ∅所以文法是LL(1)文法。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
coun t--;
temp=(i nt)tempva叶1;
tempvห้องสมุดไป่ตู้r=(char)temp;
}
}
}
void SET Add Sub(i nt j,i nt m) //处理加减运算
{
j++;
for(;jv=m-1;j++)
{
if(stri ng[j]=='+'||stri ng[j]=='-')
{
}
}
}
/*打印*/
void prin t()
{
int i;
for(i=0;i<=m-1;i++)〃处理乘除运算
{
if(stri ng[i]=='*'||stri ng[i]=='/')
{
prin tf("(%c%c %c %c)\n",stri ng[i],stri ng[i-1],stri ng[i+1],tempvar);
prin tf("(%c%c %c %c)\n",stri ng[j],stri ng[j-1],stri ng[j+1],tempvar);
stri ng[j-1]=stri ng[j]=stri ng[j+1]=tempvar;
coun t--;
temp=(i nt)tempva叶1;
tempvar=(char)temp;
{
for(i++;i<=m-1;i++)
{
if(stri ng[i]=='*'||stri ng[i]=='/')
{
prin tf("(%c %c %c%c)\n",stri ng[i],stri ng[i-1],stri ng[i+1],
tempvar);
stri ng[i-1]=stri ng[i]=stri ng[i+1]=tempvar;
coun t--;
stri ng[k-1]=tempvar;
}
}
}
2.q =( ( x * x+w )-(y/y-e ) ) * r
实验代码:
#in clude<stdio.h>
#i nclude<stdlib.h>
#define MAX 100
void SET_Mul_Div(i nt i,i nt m);
void SET_Add_Sub( int j,i nt m);
while((ch = getchar())!='\n')
{
stri ng[m++]=ch;
if(ch=='='||ch=='+'||ch=='-'||ch=='*'||ch=='/') coun t++;
else if(ch=='(')
{
P[++c]=m-1;
}
else if(ch==')')
{
q=m-1;
stri ng[i-1]=stri ng[i]=stri ng[i+1]=tempvar;
coun t--;
temp=(i nt)tempva叶1;
tempvar=(char)temp;
}
}
int j;
for(j=0;jv=m-1;j++)〃处理加减运算
{
if(stri ng[j]=='+'||stri ng[j]=='-')
void prin t();
int m=0;
int coun t=0;
char tempvar='A';
int temp;
char stri ng[MAX];〃用于存放表达式
int main()
{
in t p[MAX];
char ch;
int c=-1,q=0;
printf("请输入赋值语句:\n");
{
prin tf("(%c%c %c %c)\n",stri ng[j],stri ng[j-1],stri ng[j+1],tempvar);
stri ng[j-1]=stri ng[j]=stri ng[j+1]=tempvar;
coun t--;
temp=(i nt)tempva叶1;
tempvar=(char)temp;
西北师范大学计算机科学与工程学院学生实验报告
学号
专业
计算机科学与技术
姓名
课程名称
计算机编译原理
班级
实验名称
实验目的:
编程实现生成四元式的语法分析程序,掌握的结合语法分析实现翻译方案的思路和
方法。
实验内容:
实验输入:输入任意的赋值语句表达式;
实验输出:相应的四元式序列。
测试实例:
输入表达式
1.a= ( (b+c) * d -e/f)*2
tempvar=(char)temp;
调用生成四元式的函数
prin t();
判断是否成功**********/
if(co un t==0)
printf("Successful!\n"); else
printf("Wrong!");
prin tf("\n");
system("pause");
}
void SET_Mul_Div(int i,int m) //处理乘除运算
}
}
int k;
for(k=0;k<=m-1;k++)//处理赋值运算
{
if(stri ng[k]=='二')
{
temp=(i nt)tempvar--;
tempvar=(char)temp;
prin tf("(%c%c %c) \n",stri ng[k],stri ng[k+1],
stri ng[k-1],tempvar);
SET_Mul_Div(p[c],q);//从左括号处理到又括号
SET_Add_Sub(p[c],q);
temp=(i nt)tempvar-1;
tempvar=(char)temp;
stri ng[p[c]]=stri ng[m-1]=tempvar;
c--;
temp=(i nt)tempva叶1;
相关文档
最新文档