编译原理实验报告
姓名:布凡
学号:04070008
指导老师:蒋宗礼
完成日期:2007-6-19
实验一:词法分析
1. 实验目的
实现一个词法分析程序,将输入字符串流分解成终结符流供语法分析使用。
2. 实验内容
编制一个能够分析三种整数、三种浮点数、标识符、主要运算符和主要关键字的词法分
析程序。
3. 实验要求
编写能识别下列正规式的词法分析程序。
标识符 <字母>(<字母>|<数字字符 >)*(ε|_|.)(<字母>|<数字字符 >)*
十进制实数 (0|(1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9) *).(0|1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9) *
八进制实数 0(0|1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7) * .(0|1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7) *
十 六 进 制 实 数
0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)
* .(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f) *
十进制整数 0 | (1|2|3|4|5|6|7|8|9)(0|1|2|3|4|5|6|7|8|9) *
八进制整数 0(0|1|2|3|4|5|6|7)(0|1|2|3|4|5|6|7) *
十六进制整数 0x(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f)(0|1|2|3|4|5|6|7|8|9|a|b|c|d|e|f) *
运算符和分隔符 + - * / > < = ( ) ;{ } || && ! == #
关键字 if then else while do
4. 词法的状态转换图
ε
1---9
0---9
.
0---9
1
2
5
6
7
0---9
0---7
.
0
0---7
8
9
0---7
.
0---f
x
12
0---7
11
10
0---f
.
0---f
0---f
13
14
15
ε
ε
3
3
0---9| a---z | A---Z
0---9| a---z | A---Z
a---z | A---Z
.|_
a---z | A---Z|0--9
16
17
18
+ - * / > < = ( ) ; # || { } && == #
19
2
temp.code=28;
5. 词法分析的数据结构
typedef struct{
int code; //分析出的词元的编号
char value[VALUELEN];// 分析出的词元
的值(标识符或数值)
}Elem;
6.词法分析的算法
Elem Scan()
{
Elem temp;
int vlen=0;
GetBC();
if(curchar=='#')
{
temp.value[vlen++]='\0';
}
if(IsLetter(curchar))
{
while(IsLetter(curchar)||IsDigit(curchar))
{
}
while(IsLetter(curchar)||IsDigit(curchar))
if(curchar=='_'||curchar=='.')
{
Concat(temp.value,vlen);
{
Concat(temp.value,vlen);
GetChar();
}
Concat(temp.value,vlen);
GetChar();
return temp;
GetChar();
3
{
return temp;
temp.value[0]='\0';
if(curchar=='0')
{
if(temp.code!=0)
}
temp.value[vlen++]='\0';
temp.code=IsKeyWord(temp.value);
Retract();
}
else if(IsDigit(curchar))
{
Concat(temp.value,vlen);
GetChar();
if(!IsOctDigit(curchar)&&curchar!='.'&&curc
har!='x'&&curchar!='X')//int10 (0)
temp.code=2;
else if(curchar=='.')//real10 (0.)
Concat(temp.value,vlen);
GetChar();
{
while(IsDigit(curchar))
{
Concat(temp.value,vlen);
temp.code=5;
temp.value[vlen++]='\0';
temp.value[vlen++]='\0';
Retract();
return temp;
GetChar();
Retract();
return temp;
}
if(IsDigit(curchar))
}
{
{
}
{
}
else
{
if(IsHexDigit(curchar))
Concat(temp.value,vlen);
GetChar();
return temp;
Error(3);
temp.code=-1;
}
else
if(curchar=='x'||curchar=='X')//int16 real16
GetChar();
{
while(IsHexDigit(curchar))
Concat(temp.value,vlen);
temp.code=3;
temp.value[vlen++]='\0';
ToDecimal(temp.value,16);
Concat(temp.value,vlen);
GetChar();
if(IsHexDigit(curchar))
{
while(IsHexDigit(curchar))
{
if(curchar!='.')
{
Retract();
return temp;
}
}
4
}
}
return temp;
else
{
Retract();
}
else
{
GetChar();
return temp;
Concat(temp.value,vlen);
temp.code=6;
temp.value[vlen++]='\0';
ToDecimal(temp.value,1616);
}
Error(3);
temp.code=-1;
Error(4);
temp.code=-1;
}
else //int8 real8
while(IsOctDigit(curchar))
{
Concat(temp.value,vlen);
temp.code=1;
temp.value[vlen++]='\0';
GetChar();
return temp;
}
if(curchar!='.')
{
Retract();
}
{
}
Retract();
return temp;
}
GetChar();
GetChar();
if(IsOctDigit(curchar))
{
ToDecimal(temp.value,8);
Concat(temp.value,vlen);
while(IsOctDigit(curchar))
{
Concat(temp.value,vlen);
temp.code=4;
temp.value[vlen++]='\0';
ToDecimal(temp.value,88);
Error(3);
temp.code=-1;
while(IsDigit(curchar))
{
Concat(temp.value,vlen);
temp.code=2;
return temp;
}
else //int10 or real10
{
GetChar();
}
if(curchar!='.')
{
temp.value[vlen++]='\0';
}
else
{
return temp;
}
}
5
temp.value[vlen++]='\0';
Retract();
}
{
}
Retract();
return temp;
GetChar();
GetChar();
if(IsDigit(curchar))
{
return temp;
}
else
{
Concat(temp.value,vlen);
while(IsDigit(curchar))
Concat(temp.value,vlen);
temp.code=5;
Error(3);
temp.code=-1;
}
else if(curchar=='+')
{
temp.code=12;
}
else if(curchar=='-')
{
temp.code=13;
}
else if(curchar=='*')
{
temp.code=14;
temp.value[vlen++]='\0';
return temp;
temp.value[vlen++]='\0';
return temp;
return temp;
temp.value[vlen++]='\0';
}
}
temp.value[vlen++]='\0';
return temp;
temp.value[vlen++]='\0';
return temp;
temp.value[vlen++]='\0';
return temp;
return temp;
}
else if(curchar=='/')
{
temp.code=15;
}
else if(curchar=='>')
{
temp.code=16;
}
else if(curchar=='<')
{
temp.code=17;
}
else if(curchar=='=')
{
GetChar();
temp.code=27;
temp.code=18;
}
else if(curchar=='(')
{
temp.code=19;
}
else if(curchar==')')
{
temp.code=20;
return temp;
}
if(curchar=='=')
{
temp.value[vlen++]='\0';
Retract();
return temp;
temp.value[vlen++]='\0';
temp.value[vlen++]='\0';
return temp;
temp.value[vlen++]='\0';
return temp;
temp.value[vlen++]='\0';
return temp;
}
else if(curchar==';')
{
temp.code=21;
}
else if(curchar=='{')
{ temp.code=22;
temp.value[vlen++]='\0';
return temp; }
else if(curchar=='}')
{
temp.code=23;
}
else if(curchar=='|')
{
temp.code=-1;
return temp;}
temp.code=24;
}
else if(curchar=='&')
{
Error(1);
temp.code=-1;
temp.code=25;
}
GetChar();
if(curchar!='&')
{
temp.value[vlen++]='\0';
return temp;
temp.value[vlen++]='\0';
return temp;
GetChar();
if(curchar!='|')
{ Error(1);
temp.value[vlen++]='\0';
return temp;
return temp;
}
6
实验二/三:语法制导的三地址代码生成程序
1. 实验目的
通过实现一个词法及语义分析程序掌握计算机语言的语法分析程序设计与属性文法应
用的实现方法。
2. 实验内容
编制一个 LR(1)自动生成程序,并用生成的 LR(1)分析表进行语法分析,生成三地址
代码。
3. 实验要求
1,自动生成 LR(1)分析表
2,采用 LR(1)分析法分析用类 c 语言文法编制的程序段。
3,从文件中读入源程序段。
4,根据下文中语法制导定义给出的属性文法生成三地址码。
4.文法的定义(消除二义性之后)
S'→ S #
S → U
S → M
U → while ( C ) S1
U → if ( C ) S1
U → if ( C ) M else U
M → if ( C ) M else M
M → id = E ;
M → {B}
B → S
B → S B
C → C || P
C → P
P → P && Q
P → Q
Q → ! Q
Q → ( C )
Q → E > E
Q → E < E
Q → E == E
E → E + T
E → E - T
E → T
T → F
8