【www.bbjkw.net--实习报告】
【www.wudu001.com - 范文】 欢迎来到五度学习网http://www.wudu001.com/,本文为大家带来《实验报告》范文,希望能帮助到你实验报告
1.实验目的:
c—语言的句法分析器。读入一个C--语言程序,判断该程序是不是一个合法的C--语言程序。如果程序有语法和语义错误,
请给出错误信息。至少处理以下错误:
(1)所有语法错误。C――的语法参见C――的文档;
(2)语义错误:
2a:标志符未定义错误,多次定义错误(需要采用符号表。关于符号表的实现,请大家参阅第7章。)
2b: 类型错误。判断运算符的参数是否具有所需要的类型。注意:算术运算符包括:+,-,*,/,%只作用于整数。
关系运算符(<,>,等)可以作用于整数表达式,字符表达式,但是不要求作用于字符串表达式(
否则C--就不是C语言的子集了,虽然理论上支持“ab” < “ac”还是挺有意思的)。类型错误包括函数调用的参数。
2.程序要做成命令行程序,带一个参数,表示输入的C--文件名。
3,设计思想:
1. 基于yacc 工具的使用 ,了解yacc 的语法规则。
2. 通过了解C—-语言的文法的了解。
3. 书上的类型错误检查知识了解。
4. 符号表的建立,插入,查找。
4,花了多少时间:三个下午。
5,是否独立完成:是;
6,采用什么编译器,flex 和yacc ,visual c++6.0
7,遇到什么问题,如何解决的。
1.语法错误少一个 ; 号;
处理在 var_declar : type_spec ID ';'
| type_spec ‘*’ ID ';'
| type_spec ID '[' NUM ']' ';'
| type_spec ‘*’ ID '[' NUM ']' ';'
| error '\n' 这个用于变量声明时的;缺少。
fun_declar : type_spec fun_tag '(' LL params ')' comp_stmt
|type_spec fun_tag '(' LL params ')' ';'
|ype_spec fun_tag '(' LL params ')'
这个用于变量声明时的;缺少。
2,函数声明时与函数的定义的函数参数个数及参数的类型的确定
1. 首先声明 变量
%type <value> params
%type <value> param
%type <value> param_list
用这些变量记录函数的参数个数值。 如下:
params : param_list { $$ = $1; }
|VOID{ trace("params => VOID \n"); $$ = 0; }
;
param_list : param_list ',' param { $$ = $1+$3; }
| param{ $$ = $1; }
;
2.自己创建一个函数的参数键表用于记录函数参数的类型
typedef struct aa
{ int type;
struct aa *next;
} fun_type;
采用的是插入到funtype键表的尾部, 如下的是键表的建立
param : type_spec ID
{ $$ = 1;
{
struct table * tp = table_stack[table_len-1];
if(lookupred($2,tp)==0){
symbol * p = insert($2, tp);
int width=0;
fun_type *tmp; fun_type *pp;
tmp=(fun_type *)malloc(sizeof(fun_type));
tmp->type=$1;
tmp->next=0;
if(funtype==0) {
funtype=tmp;
}
else {
pp=funtype;
while(pp->next){
pp=pp->next;
}
pp->next=tmp;
}
p->type = $1;
p->offset = offset_stack[offset_len-1];
}else printf("line %3d error: %s :redefinition\n", nline, $2);
}
$$ = 1;
}
| type_spec '*' ID
| type_spec ID '[' ']'
这两个类似的做法 不显示过程。
3. 函数的定义类型与声明的比较以及函数的调用的参数类型的比较。
1.. 函数的定义类型与声明的比较:
fun_declar : type_spec fun_tag '(' LL params ')' comp_stmt
if($2->isdeclar==1) {//如果函数已经声明则进行函数的参数类型
及个数进行比较
fun_type *p1=$2->functype,*p2=funtype;int i;
//参数的个数不同时
if($2->funargc != $5) printf(" Type mismatch(defined more than declartion) in redeclaration of %s\n",$2->name);
for(i=1;i<=$5;i++)
{
if(p1==0||p2==0) break;
if(p1->type!=p2->type) //定义和声明函数参数的每一个类型的比较若不同则显示出错两个类型不一致。
printf("Parater %d Type mismatch in redeclaration of %s\n",i,$2->name);
p1=p1->next; p2=p2->next;
}
}
//若之前没有函数的声明 则直接把参数的个数及参数的类型键表赋给fun_tag的结构体的functype的指针。
else { $2->funargc=$5; $2->functype=funtype; }
offset_len--; table_len--; level--; funtype=0;
2..函数的声明:
|type_spec fun_tag '(' LL params ')' ';'
$2->isdeclar=1; 标记函数的已经被声明了
$2->funargc=$5; 标记函数的参数个数
$2->functype=funtype; 标记函数的返回值类型。
funtype=0; 设置funtype的头键表为空 可以让下一函数键表的建立
table_len--;
level--;
3..函数的调用的参数类型的匹配问题。
1.。同上,函数调用也存在记录函数的参数个数和参数的类型问题。
就要创建参数类型的键表 大致的作法如上。
如下:%type <value> param_list
%type <value> args
%type <value> arg_list
args : arg_list
{ $$=$1;trace("args => arg_list\n"); }
|
{ $$=0; trace("args => ε\n"); }
;
arg_list : arg_list ',' expr
{
fun_type *tmp; fun_type *pp;
tmp=(fun_type *)malloc(sizeof(fun_type));
tmp->type=$3.type;
tmp->next=0;
if(funtype==0) {
funtype=tmp;
}
else {
pp=funtype;
while(pp->next){
pp=pp->next;
}
pp->next=tmp;
}
$$=$1 + 1;
trace("arg_list => arg_list , expr\n");
}
| expr
{
fun_type *tmp; fun_type *pp;
tmp=(fun_type *)malloc(sizeof(fun_type));
tmp->type=$1.type;
tmp->next=0;
if(funtype==0) {
funtype=tmp;
}
else {
pp=funtype;
while(pp->next){
pp=pp->next;
}
pp->next=tmp;
}
$$=1;trace("arg_list => expr\n");
}
;
2…..参数的类型匹配比较 也如上
call : ID '(' args ')'
{
symbol *tmp = lookup($1, table_stack[table_len-1]);
trace("call => ID ( args )\n");
if(0!=tmp) { $$.type=tmp->type; }
if (0 == tmp) {
printf("line %3d error: %s :undeclared function\n", nline, $1);
}
else {
fun_type *p1=tmp->functype,*p2=funtype;int i;
if(tmp->funargc>$3) printf("line %d Too fewer (%d)parameters in call to fuction of %s \n",nline,tmp->funargc-$3,tmp->name);
else if(tmp->funargc<$3) printf("line %d Too much (%d)parameters in call to fuction of %s \n",nline,$3-tmp->funargc,tmp->name);
for(i=1;i<=$3;i++)
{
if(p1==0||p2==0) break;
if(p1->type!=p2->type) printf("line %d Parater %d Type mismatch in call to fuction of %s \n",nline,i,tmp->name);
p1=p1->next; p2=p2->next;
}
}
funtype=0;
}
;
4.就是类型错误。
1….. 通过各种的非终接符的.type属性传递各个非终接符的.type 如下:
expr : var '=' expr
| logic_expr{
trace("expr => logic_expr ; \n");
$$.type=$1.type;
2.。类型的检查。
expr : var '=' expr
{ char code [1000];
trace("expr => var '=' expr \n");
if ($1 != 0) {
if ($1->type != $3.type) {
printf("var type is %d expr type is %d \n",$1->type,$3.type);
printf("line %3d error: = :the left and the right type does not match\n", nline, $1);
}
$$.type = $1->type;
}
8,测试程序的结果及使用方法。
运行:
测试的文件1 mytest.c 如下:
1 int i;
2 int arr[5];
3 char str[6];
4 char *strp;
5 char k;
6 int i; //i 被重复定义
7 int *i //少一个;
8 int i[7] ; //i 被重复定义
9 int *i[8] //i 被重复定义 少一个;
10 int aa(int k ,char i);//函数aa声明
11 int aa(char k,int i){}//函数a声明 两者的类型不一致
12 int a(int i,int j) //函数a声明 少一个;
13-void b(int a,char i){ //函数b定义
14 int i; //声明变量与函数的参数的变量 重复定义
15 k=i;
16 }
17-int main(int argc,char *argv){
18 int i;
19 int *j;
20
21 "hello"<="olleh"; //字符串的比较
22 'a'>='b'; //字符的比较
23 i=='d' ; //少一个;
24 "hello"==i;
25 arr[4]="dfdfs"; //左右两边的类型不一致的赋值
26 str[3]=arr[4]; //左右两边的类型不一致的赋值
27 if(i>=1) i=i+1;else i=i-1;
28- while( i+3==b(1,'d')+3) { //左右两边的类型不一致
29 i=i+1;
30 m=5; //没有定义就使用的变量
31 }
32 b(i,'d');
33 b(3) ; // 调用函数的参数个数太少
34 b(4,3,"dfdf"); //调用函数的参数个数太多
35 j=c(); //未声明或者定义就使用函数
36 j=bc(); //不存在的函数调用
37 return 1;
38 }
39- int a(int a,char i){ //函数a定义 函数定义的类型与声明的不一致
40 k='a';//k为全局变量
41 k=1;//左右两边的类型不一致的赋值
42 b(k); // 调用函数的参数个数太少
43 }
44-int c(int a,int i){ //函数c 定义
45 k=1;
46 }
测试的结果如下:
C:\Documents and Settings\黄丽福\桌面\ext\src>y.tab mytest.c
line 8: error: i :redefinition
line 10 :syntax error at token INT
line 10 :type name expected
line 10 error: i :redefinition
line 12 :syntax error at token INT
line 12 :type name expected
_aa :
Parater 1 Type mismatch in redeclaration of aa
Parater 2 Type mismatch in redeclaration of aa
line 14:function a declaration missing ;
line 16: error: i :redefinition
_b :
line 27 :error : = :the left and the right type does not match
line 28 :error : = :the left and the right type does not match
line 30 Parater 2 Type mismatch in call to fuction of b
line 30 error: + :illegal, left operand is not constant
line 32 :undeclared identifier: m
line 34 Parater 2 Type mismatch in call to fuction of b
line 35 Too fewer (1)parameters in call to fuction of b
line 36 Too much (1)parameters in call to fuction of b
line 36 Parater 3 Type mismatch in call to fuction of b
line 37 error: c :undeclared function
line 37 :error : = :the left and the right type does not match
line 38 error: bc :undeclared function
line 38 :error : = :the left and the right type does not match
_main :
line 43 :error : = :the left and the right type does not match
line 44 Too fewer (1)parameters in call to fuction of b
_a :
line 47 :error : = :the left and the right type does not match
_c :
compiling to s2.asm, takes 0.0 seconds.
测试的文件2 s2.c如下:
1
2 int min(int i, int j)
3-{
4 if (i < j) return i; else return j;
5 }
6
7
8 void main(void)
9-{
10 int i;
11 int j;
12 j=6;
13 i=j+4;
14 i=4+6;
15 j=min(i, j);
16 }
测试的结果如下:
没有错误:
C:\Documents and Settings\黄丽福\桌面\ext\src>y.tab s2.c
_min :
_main :
compiling to s2.asm, takes 0.0 seconds.
测试的文件三 s3.c如下:
1
2 int min(int i, int j)
3-{
4 if (i < j) return i; else return j;
5 }
6
7
8 void main(void)
9-{
10 int i;
11 int j;
12 j=6;
13 i=j+4;
14 i=4+6;
15 j=min(i, "wrong");
16 }
测试的结果如下:
C:\Documents and Settings\黄丽福\桌面\ext\src>y.tab s3.c
_min :
line 15 Parater 2 Type mismatch in call to fuction of min
_main :
compiling to s3.asm, takes 0.0 seconds.
以上就是五度学习网http://www.wudu001.com/带给大家不一样的精彩范文。想要了解更多精彩的朋友可以持续关注五度学习网,我们将会为你奉上最全最新鲜的内容哦! 五度学习网,因你而精彩。
本文来源:http://www.wudu001.com/fanwen/184326/本文来源:https://www.bbjkw.net/fanwen343399/
推荐访问:实验报告模板 化学实验报告 实验报告格式 物理实验报告 实习报告 erp实验报告 实验报告评语 matlab实验报告 牛顿环实验报告 实验报告总结 单片机实验报告 生物实验报告 数据库实验报告 统计学实验报告 计算机实验报告 会计实验报告 java实验报告 spss实验报告 实验报告封面 excel实验报告 审计实验报告