当前位置:首页 » 编程软件 » 编译原理程序分析举例

编译原理程序分析举例

发布时间: 2022-05-21 02:41:49

⑴ 如何通俗易懂地解释编译原理中语法分析的过程

分成词法分析,语法分析(LL算法,递归下降算法,LR算法),语义分析,运行时环境,中间代码,代码生成,代码优化这些部分。其实现在很多编译原理的教材都是按照85,86出版的那本龙书来安排教学内容的,所以那本龙书的内容格式几乎成了现在编译原理教材的定式,包括国内的教材也是如此。一般来说,大学里面的本科教学是不可能把上面的所有部分都认真讲完的,而是比较偏重于前面几个部分。像代码优化那部分东西,就像个无底洞一样,如果要认真讲,就是单独开一个学期的课也不可能讲得清楚。所以,一般对于本科生,对词法分析和语法分析掌握要求就相对要高一点了。

词法分析相对来说比较简单。可能是词法分析程序本身实现起来很简单吧,很多没有学过编译原理的人也同样可以写出各种各样的词法分析程序。不过编译原理在讲解词法分析的时候,重点把正则表达式和自动机原理加了进来,然后以一种十分标准的方式来讲解词法分析程序的产生。这样的做法道理很明显,就是要让词法分析从程序上升到理论的地步。

语法分析部分就比较麻烦一点了。现在一般有两种语法分析算法,LL自顶向下算法和LR自底向上算法。LL算法还好说,到了LR算法的时候,困难就来了。很多自学编译原理的都是遇到LR算法的理解成问题后就放弃了自学。其实这些东西都是只要大家理解就可以了,又不是像词法分析那样非得自己写出来才算真正的会。像LR算法的语法分析器,一般都是用工具Yacc来生成,实践中完全没有比较自己来实现。对于LL算法中特殊的递归下降算法,因为其实践十分简单,那么就应该要求每个学生都能自己写。当然,现在也有不少好的LL算法的语法分析器,不过要是换在非C平台,比如Java,Delphi,你不能运用YACC工具了,那么你就只有自己来写语法分析器。

⑵ 编译原理语法分析编程

#include <iostream>
#include <string>
#include <fstream>
#include <queue>
#include <string.h>
#include <stdio.h>

using namespace std;

enum Datatype { RESERVE_WORD=1,IDENTIFIER=2,DIGIT=3,OPERATOR=4,SEPRATOR=5 };

struct OutputStruct
{
public:
Datatype type;
string value;
};

string operate[]={"sin","cos","pow"};
string KeyWord[]={"main","int","if","char","cout"};
const int MAX_SIZE=255;
char BUFF[MAX_SIZE]; //buffer to contain a char line.
ifstream inFile;
ofstream outFileStream;
queue<OutputStruct> tt;

bool IsKeyWord(string& cs)
{
for(int i=0;i<5;++i)
if(cs==KeyWord[i])
return true; //Exist
return false;
}

void ReadLineAndAnalyze()
{
int strSize=0;
int i;
int errFlag=0;
char ch;
string outStructStr,str;
struct OutputStruct outStruct;
{
i=0;
inFile.getline(BUFF,MAX_SIZE,'\n');
strSize=inFile.gcount();
cout<<BUFF;
do{
str="";
do{
ch=BUFF[i];
i++;
}while(ch==' '||ch==' '||ch=='\n');
switch(ch)
{

case '+':
case '-':
case '*':
case '/':
outStruct.type=OPERATOR;
outStruct.value=ch;
break;
case '=':
case '>':
case '<':
outStructStr=ch;
if(BUFF[i]=='=')
{
outStruct.type=OPERATOR;
outStructStr+=BUFF[i];
outStruct.value=outStructStr;
i++;
}
else
{
outStruct.type=OPERATOR;
outStruct.value=ch;
};
break;

case ',':
case ';':
case '{':
case '}':
case '(':
case ')':
case '[':
case ']':
case '\"':
outStruct.type=SEPRATOR;
outStruct.value=ch;
break;

case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
outStructStr+=ch;
while(BUFF[i]>='0'&&BUFF[i]<='9'||BUFF[i]=='.')
{
outStructStr+=BUFF[i];
i++;
}//while
outStruct.type=DIGIT;
outStruct.value=outStructStr;
break;

default:
if(ch>='a'&&ch<='z'||ch>='A'&&ch<='Z')
{
outStructStr+=ch;
while(BUFF[i]>='a'&&BUFF[i]<='z'||BUFF[i]>='A'&&BUFF[i]<='Z')
{
outStructStr+=BUFF[i];
i++;
}//while
if(IsKeyWord(outStructStr))
{
outStruct.type=RESERVE_WORD;
outStruct.value=outStructStr;
}
else
{
outStruct.type=IDENTIFIER;
outStruct.value=outStructStr;
}
break;
}
else
errFlag=1;
}//switch;
if(!errFlag)
tt.push(outStruct);
errFlag=0;
outStructStr="";
}while(i<strSize-1);

}//while(i<MAX_SIZE&&!inFile.eof());//do_while
return;
}

float F();
float T();
float E();
float S();

float F()
{
float ret;
if((tt.front().type==IDENTIFIER)||(tt.front().type==DIGIT))
{
ret=atof(tt.front().value.c_str());
if(tt.empty())
{
cout<<"END"<<endl;exit(0);
}
tt.pop();
return ret;
}
if(tt.front().value=="(")
{
if(tt.empty())
{
cout<<"END"<<endl;exit(0);
}
tt.pop();
ret=E();
if(tt.front().value==")")
{
if(tt.empty())
{
cout<<"END"<<endl;exit(0);
}
tt.pop();
return ret;
}
else
{
cout<<"\b ----ERROR! "<<tt.front().value<<" 缺少右括号"<<endl;
cout<<"Press \"enter\" to modify the data file!";
getchar();
system("notepad data.txt");
exit(0);
}
}
else
{
cout<<"\b ----ERROR! "<<tt.front().value<<" 缺少因子"<<endl;
cout<<"Press \"enter\" to modify the data file!";
getchar();
system("notepad data.txt");
exit(0);
}
}
float T()
{
float i,j;
i=F();
if(tt.front().value=="*")
{
if(tt.empty())
{
cout<<"END"<<endl;exit(0);
}
tt.pop();
j=T();
return i*j;
}
else if(tt.front().value=="/")
{
if(tt.empty())
{
cout<<"END"<<endl;exit(0);
}
tt.pop();
j=T();
if(abs(j)<0.0000001)
{
cout<<"\b ----ERROR! 除数为零!"<<endl;
cout<<"Press \"enter\" to modify the data file!";
getchar();
system("notepad data.txt");
exit(0);
}
return i/j;
}
return i;
}

float E()
{
float i,j;
i=T();
if(tt.front().value=="+")
{
if(tt.empty())
{
cout<<"END"<<endl;exit(0);
}
tt.pop();
j=E();
i=i+j;
}
else if(tt.front().value=="-")
{
if(tt.empty())
{
cout<<"END"<<endl;exit(0);
}
tt.pop();
j=E();
i=i-j;
}
if(tt.front().value==";"||tt.front().type==OPERATOR||tt.front().value==")")
return i;
else
{
cout<<"\b ----ERROR! "<<tt.front().value<<" 缺少运算符"<<endl;
cout<<"Press \"enter\" to modify the data file!";
getchar();
system("notepad data.txt");
exit (0);
}
}

float S()
{
float i;
i=E();
if(tt.front().value==";")
{
if(tt.empty())
{
cout<<"END"<<endl;exit(0);
}
tt.pop();
return i;
}
cout<<"\b ----ERROR! "<<tt.front().value<<" 缺少左括号"<<endl;
cout<<"Press \"enter\" to modify the data file!";
getchar();
system("notepad data.txt");
exit(0);
}

void GrammaAnalize()
{
float i;
if(tt.empty())
{
cout<<"END"<<endl;exit(0);
}
i=S();
cout<<"\b="<<i<<endl;
}

int main()
{
inFile.open("data.txt");
if(!inFile)
{
cout<<"打开源文件失败!";
return 1;
}
while(!inFile.eof())
{
ReadLineAndAnalyze();
GrammaAnalize();
}
inFile.close();
return 0;
}

⑶ 编译原理,递归下降子程序语法分析

没学过编译原理,看描述,是让写一个脚本执行软件。
终结符我查了下,就是不可再分的。比如iε。
输入是EGTSFI*/ε组成的字符串。
规则需要预处理。注意转意符在字符串中的效果。因为有/字符。

不会c或c++,只会c#。你可以到贴吧发帖。强人工智能吧 就挺好。算法吧有点乱。

最重要的,不要钱。

⑷ 求C语言编译原理语法分析程序

一继承的词法来自

http://blog.sina.com.cn/s/blog_67c9fc300100srad.html
二语法

用扩充的BNF表示如下:

⑴<程序>::=begin<语句串>end

⑵<语句串>::=<语句>{;<语句>}

⑶<语句>::=<赋值语句>

⑷<赋值语句>::=ID:=<表达式>

⑸<表达式>::=<项>{+<项> | -<项>}

⑹<项>::=<因子>{*<因子> | /<因子>

⑺<因子>::=ID | NUM | (<表达式>)

三要求

输入单词串,以“#”结束,如果是文法正确的句子,则输出成功信息,打印“success”,否则输出“error”。

例如:

输入 begin a:=9; x:=2*3; b:=a+x end #

输出 success!

输入 x:=a+b*c end #

输出 error!

⑸ C语言编译原理是什么

编译共分为四个阶段:预处理阶段、编译阶段、汇编阶段、链接阶段。

1、预处理阶段:

主要工作是将头文件插入到所写的代码中,生成扩展名为“.i”的文件替换原来的扩展名为“.c”的文件,但是原来的文件仍然保留,只是执行过程中的实际文件发生了改变。(这里所说的替换并不是指原来的文件被删除)

2、汇编阶段:

插入汇编语言程序,将代码翻译成汇编语言。编译器首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,编译器把代码翻译成汇编语言,同时将扩展名为“.i”的文件翻译成扩展名为“.s”的文件。

3、编译阶段:

将汇编语言翻译成机器语言指令,并将指令打包封存成可重定位目标程序的格式,将扩展名为“.s”的文件翻译成扩展名为“.o”的二进制文件。

4、链接阶段:

在示例代码中,改代码文件调用了标准库中printf函数。而printf函数的实际存储位置是一个单独编译的目标文件(编译的结果也是扩展名为“.o”的文件),所以此时主函数调用的时候,需要将该文件(即printf函数所在的编译文件)与hello world文件整合到一起,此时链接器就可以大显神通了,将两个文件合并后生成一个可执行目标文件。

⑹ 编译原理LL1语法分析的例子谁有

这个句子要分成两大部分看:1.He said that....2.All things considered, he thought it was a bad idea.
2是1的宾语从句,但复杂的是在2这个宾语从句中包含了一个独立主格结构(All things considered),其实2的核心主语和谓语应该是he和thought,此时all things是独立于这个核心主语的,我们叫它独立主格,此时considered不是谓语动词,而是非谓语,在这里表示被动,所以all things considered不是一句完整的话(完整的应该是all things are considered)这里all things 是独立主格considered是它的非谓语,一起构成一个独立主格结构,和后面句子放在一起构成主句的宾语从句,是符合语法的。

⑺ 编译原理

编译原理):利用编译程序从源语言编写的源程序产生目标程序的过程; 用编译程序产生目标程序的动作。 编译就是把高级语言变成计算机可以识别的2进制语言,计算机只认识1和0,编译程序把人们熟悉的语言换成2进制的。

编译程序把一个源程序翻译成目标程序的工作过程分为五个阶段:词法分析;语法分析;语义检查和中间代码生成

(7)编译原理程序分析举例扩展阅读:

编译程序的语法分析器以单词符号作为输入,分析单词符号串是否形成符合语法规则的语法单位,如表达式、赋值、循环等,最后看是否构成一个符合要求的程序,按该语言使用的语法规则分析检查每条语句是否有正确的逻辑结构,程序是最终的一个语法单位。

编译程序的语法规则可用上下文无关文法来刻画。语法分析的方法分为两种:自上而下分析法和自下而上分析法。自上而下就是从文法的开始符号出发,向下推导,推出句子。

而自下而上分析法采用的是移进归约法,基本思想是:用一个寄存符号的先进后出栈,把输入符号一个一个地移进栈里,当栈顶形成某个产生式的一个候选式时,即把栈顶的这一部分归约成该产生式的左邻符号。

⑻ 编译原理词法分析程序

(一)Block子程序分析

procere enter(k: object1); //填写符号表
begin {enter object into table}
tx := tx + 1; //下标加1,tx的初始值为零,零下标不地址不填写标志符,用于查找失败使用
with table[tx] do //填入内容,保存标志符名和类型
begin name := id; kind := k;
case k of //根据类型判断是否正确
constant: begin if num > amax then //如果是常量,判断是否大于最大值,若是则报30号错
begin error(30); num :=0 end;
val := num //否则保存数值
end;
varible: begin level := lev; adr := dx; dx := dx + 1; //如果是变量,填写变量内部表示,LEVEl是变量的层次,adr为地址
end;
proc: level := lev //如果是过程,保存过程的层次
end
end
end {enter};

//查找符号表的位置
function position(id: alfa): integer;
var i: integer;
begin {find indentifier id in table} //从后向前查找
table[0].name := id; i := tx; //找到保存类型
while table[i].name <> id do i := i-1;
position := i //返回标志符在符号表中的位置
end {position};

procere block(lev,tx: integer; fsys: symset);
var dx: integer; {data allocation index} //数据分配索引
tx0: integer; {initial table index} //初始符号表索引
cx0: integer; {initial code index} //初始代码索引
procere enter(k: object1); //填写符号表,下次分析
begin {enter object into table}
tx := tx + 1;
with table[tx] do
begin name := id; kind := k;
case k of
constant: begin if num > amax then
begin error(30); num :=0 end;
val := num
end;
varible: begin level := lev; adr := dx; dx := dx + 1;
end;
proc: level := lev
end
end
end {enter};

function position(id: alfa): integer; //查找符号表,下次分析
var i: integer;
begin {find indentifier id in table}
table[0].name := id; i := tx;
while table[i].name <> id do i := i-1;
position := i
end {position};

procere constdeclaration; //常量声明
begin if sym = ident then //如果是标志符,读入一个TOKEN
begin getsym;
if sym in [eql, becomes] then //读入的是等号或符值号继续判断
begin if sym = becomes then error(1); //如果是“=”报1号错
getsym; //读入下一个TOKEN
if sym = number then //读入的是数字,填写符号表
begin enter(constant); getsym
end
else error(2) //如果不是数字,报2号错
end else error(3) //不是等号或符值号,报3号错
end else error(4) //如果不是标志符,报4号错
end {constdeclaration};

procere vardeclaration; //变量声明
begin if sym = ident then //读入的是标志符,填写符号表
begin enter(varible); getsym
end else error(4) //不是标志符,报4号错
end {vardeclaration};

procere listcode;
var i: integer;
begin {list code generated for this block}
for i := cx0 to cx-1 do
with code[i] do
writeln(i:5, mnemonic[f]:5, 1:3, a:5)
end {listcode};

procere statement(fsys: symset);
var i, cx1, cx2: integer;
procere expression(fsys: symset); //表达式分析
var addop: symbol;
procere term(fsys: symset); //项分析
var mulop: symbol;
procere factor(fsys: symset); //因子分析
var i: integer;
begin test(facbegsys, fsys, 24); //读入的是“(”,标志符或数字
while sym in facbegsys do
begin
if sym = ident then //是标志符,查表
begin i:= position(id);
if i = 0 then error(11) else //未找到,报11号错
with table[i] do //找到,读入标志符类型
case kind of
constant: gen(lit, 0, val); //写常量命令
varible: gen(lod, lev-level, adr);//写变量命令
proc: error(21) //过程名,报21号错
end;
getsym //读入下一个TOKEN
end else
if sym = number then //读入的是数字
begin if num > amax then //如果数字大于最大数,报30号错误
begin error(30); num := 0
end;
gen(lit, 0, num); getsym //调用数字命令,读入下一个TOKEN
end else
if sym = lparen then //读入的是“(”
begin getsym; expression([rparen]+fsys); //调用表达式分析函数
if sym = rparen then getsym else error(22) //如果“(”后无“)”,报22号错
end;
test(fsys, [lparen], 23)
end
end {factor};//因子分析结束

//项分析
begin {term} factor(fsys+[times, slash]); //调用因子分析程序
while sym in [times, slash] do //取得是乘、除号循环
begin mulop:=sym;getsym;factor(fsys+[times,slash]); //记录符号,调用因子分析
if mulop=times then gen(opr,0,4) else gen(opr,0,5) //写乘除指令
end
end {term};
begin {expression}
if sym in [plus, minus] then //如果是加减号
begin addop := sym; getsym; term(fsys+[plus,minus]); //记录符号,调用项分析程序
if addop = minus then gen(opr, 0,1) //写加减指令
end else term(fsys+[plus, minus]);
while sym in [plus, minus] do //如果是加减号循环
begin addop := sym; getsym; term(fsys+[plus,minus]);
if addop=plus then gen(opr,0,2) else gen(opr,0,3)
end
end {expression};

//条件过程
procere condition(fsys: symset);
var relop: symbol;
begin
if sym = oddsym then //如果是判奇符
begin getsym; expression(fsys); gen(opr, 0, 6) //取下一个TOKEN,调用expression,填指令
end else
begin expression([eql, neq, lss, gtr, leq, geq]+fsys);
if not(sym in [eql, neq, lss, leq, gtr, geq]) then //如果不是取到逻辑判断符号,出错.20
error(20) else
begin relop := sym; getsym; expression(fsys);
case relop of
eql: gen(opr, 0, 8); // =,相等
neq: gen(opr, 0, 9); // #,不相等
lss: gen(opr, 0, 10); // <,小于
geq: gen(opr, 0, 11); // ],大于等于
gtr: gen(opr, 0, 12); // >,大于
leq: gen(opr, 0, 13); // [,小于等于
end
end
end
end {condition};

begin {statement}
if sym = ident then //如果是标识符
begin i := position(id); //查找符号表
if i = 0 then error(11) else //未找到,标识符未定义,报11号错
if table[i].kind <> varible then //如果标识符不是变量,报12号错
begin {assignment to non-varible} error(12); i := 0
end;
getsym; if sym = becomes then getsym else error(13); //如果是变量读入下一个TOKEN,不是赋值号,报13好错;是则读入一个TOKEN
expression(fsys); //调用表达是过程
if i <> 0 then //写指令
with table[i] do gen(sto, lev-level, adr)
end else
if sym = callsym then //如果是过程调用保留字,读入下一个TOKEN
begin getsym;
if sym <> ident then error(14) else //不是标识符报14号错
begin i := position(id);
if i = 0 then error(11) else //是标识符,未定义,报13号错
with table[i] do // 已定义的标识符读入类型
if kind=proc then gen(cal, lev-level, adr) //是过程名写指令
else error(15); //不是过程名,报15号错
getsym
end
end else
if sym = ifsym then //如果是IF
begin getsym; condition([thensym, dosym]+fsys); //读入一个TOKEN,调用条件判断过程
if sym = thensym then getsym else error(16); //如果是THEN,读入一个TOKEN,不是,报16号错
cx1 := cx; gen(jpc, 0, 0); //写指令
statement(fsys); code[cx1].a := cx
end else
if sym = beginsym then //如果是BEGIN
begin getsym; statement([semicolon, endsym]+fsys); //读入一个TOKEN
while sym in [semicolon]+statbegsys do
begin
if sym = semicolon then getsym else error(10); //如果读入的是分号
statement([semicolon, endsym]+fsys)
end;
if sym = endsym then getsym else error(17) //如果是END 读入一个TOKEN,不是,报17号错
end else
if sym = whilesym then //如果是WHILE
begin cx1 := cx; getsym; condition([dosym]+fsys); //调用条件过程
cx2 := cx; gen(jpc, 0, 0); //写指令
if sym = dosym then getsym else error(18); //如果是DO读入下一个TOKEN,不是报18号错
statement(fsys); gen(jmp, 0, cx1); code[cx2].a := cx
end;
test(fsys, [], 19)
end {statement};

begin {block}
dx:=3;
tx0:=tx;
table[tx].adr:=cx;
gen(jmp,0,0);
if lev > levmax then error(32);
repeat
if sym = constsym then //如果是CONST
begin getsym; //读入TOKEN
repeat constdeclaration; //常量声明
while sym = comma do
begin getsym; constdeclaration
end;
if sym = semicolon then getsym else error(5) //如果是分号读入下一个TOKEN,不是报5号错
until sym <> ident //不是标志符常量声明结束
end;
if sym = varsym then 如果是VAR
begin getsym; 读入下一个TOKEN
repeat vardeclaration; //变量声明
while sym = comma do
begin getsym; vardeclaration
end;
if sym = semicolon then getsym else error(5) //如果是分号读入下一个TOKEN,不是报5号错
until sym <> ident; //不是标志符常量声明结束
end;
while sym = procsym do //过程声明
begin getsym;
if sym = ident then
begin enter(proc); getsym
end
else error(4); //不是标志符报4号错
if sym = semicolon then getsym else error(5); //如果是分号读入下一个TOKEN,不是报5号错
block(lev+1, tx, [semicolon]+fsys);
if sym = semicolon then //如果是分号,取下一个TOKEN,不是报5号错
begin getsym;test(statbegsys+[ident,procsym],fsys,6)
end
else error(5)
end;
test(statbegsys+[ident], declbegsys, 7)
until not(sym in declbegsys); //取到的不是const var proc结束
code[table[tx0].adr].a := cx;
with table[tx0] do
begin adr := cx; {start adr of code}
end;
cx0 := 0{cx}; gen(int, 0, dx);
statement([semicolon, endsym]+fsys);
gen(opr, 0, 0); {return}
test(fsys, [], 8);
listcode;
end {block};

⑼ 编译原理 词法分析程序的设计与实现实验题

说他像苍蝇,是骂苍蝇呢还是骂他呢?

热点内容
鼠标如何编程 发布:2025-05-16 02:29:09 浏览:815
安卓70能用什么软件 发布:2025-05-16 01:45:09 浏览:480
编程发展史 发布:2025-05-16 01:38:52 浏览:528
android图片气泡 发布:2025-05-16 01:38:40 浏览:886
文件加密编辑器下载 发布:2025-05-16 01:30:41 浏览:343
linuxapacheyum安装 发布:2025-05-16 01:30:31 浏览:476
大连宾利浴池wifi密码是多少 发布:2025-05-16 01:25:36 浏览:172
缓存数据生产服务 发布:2025-05-16 01:08:58 浏览:585
普通电脑服务器图片 发布:2025-05-16 01:04:02 浏览:971
服务器地址和端口如何区分 发布:2025-05-16 01:03:17 浏览:834