编译原理实验报告三Word文档下载推荐.docx
- 文档编号:22323354
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:29
- 大小:156.37KB
编译原理实验报告三Word文档下载推荐.docx
《编译原理实验报告三Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《编译原理实验报告三Word文档下载推荐.docx(29页珍藏版)》请在冰豆网上搜索。
#defineIS19//14至18被五个关键字占用
#defineID20
#defineMAX_KEY_NUMBER20/*关键字的数量*/
#defineKEY_WORD_END"
waitingforyourexpanding"
/*关键字结束标记*/
char*KeyWordTable[MAX_KEY_NUMBER]={"
begin"
"
end"
"
if"
then"
else"
KEY_WORD_END};
charTOKEN[20]="
"
;
//存储已扫描的单词
charch='
'
//用于存储带判断的字符
introw=1;
////////////////////////无符号数部分
#defineDIGIT1
#definePOINT2
#defineOTHER3
#definePOWER4
#definePLUS5
#defineMINUS6
#defineClassOther200
#defineEndState-1
intindex=0;
intw,n,p,e,d;
intClass;
//Usedtoindicateclassoftheword
intICON;
floatFCON;
staticintCurrentState;
//Usedtopresentcurrentstate,theinitialvalue:
////////////////////////语法分析部分
////////////////////////产生式
//1、E->
E+T2、E->
E-T3、E->
T4、T->
T*F5、T->
T/F6、T->
F7、F->
(E)8、F->
i
#defineSMAX256
///////////////////////goto表的列项
#defineE0
#defineT1
#defineF2
intStateStack[SMAX];
//状态栈
intStackPoint;
//状态栈指针
intTopState;
//作为状态栈盏栈顶指针
intInputWordType;
//输入的单词类型
////////////////()+-*/i#
charAction[16][8][4]={"
s4"
"
s5"
"
s6"
s7"
A"
"
r3"
s8"
s9"
r6"
r8"
s15"
r1"
r2"
r4"
r5"
"
r7"
};
//action表
//ETF
intGoto[16][3]={{1,2,3},
{-1,-1,-1},
{10,2,3},
{-1,11,3},
{-1,12,3},
{-1,-1,13},
{-1,-1,14},
{-1,-1,-1},};
//goto表
////////////////////////语义分析部分
#definePMAX5//define后面不加括号,定义产生式符号属性字符串的长度
intNXQ=0;
/*全局变量NXQ用于指示所要产生的下一个四元式的编号*/
intNXTemp=1;
//整型变量NXTemp指示临时变量的编号
intSentenceCount=1;
//存放文件中句子的个数
structQUATERNION/*四元式表的结构*/
{
charop[PMAX];
/*操作符*/
chararg1[PMAX];
/*第一个操作数*/
chararg2[PMAX];
/*第二个操作数*/
charresult[PMAX];
/*运算结果*/
}pQuad[256];
/*存放四元式的数组*/
charEBracket_Place[PMAX];
//(E)的语义属性
chari_Place[PMAX];
charE_Place[PMAX];
charT_Place[PMAX];
charF_Place[PMAX];
intEXCUTE(intstate,intsymbol,FILE*fp,charJudgeStr[],introw,intindex);
intGetChar(charch);
intHandleError(charStrJudge[],introw);
intPush(intState);
intPop(intcount);
intSLRControl(FILE*fp);
voidGEN(char*Op,char*Arg1,char*Arg2,char*Result);
char*NewTemp(void);
voidNextSentence(FILE*fp);
//当语法或者词法产生错误的时候,跳过当前错误的句子,将文件指针指向下一个句子的开始
////////////////////////查保留字表,判断是否为关键字
intlookup(char*token)
intn=0;
while(strcmp(KeyWordTable[n],KEY_WORD_END))//strcmp比较两串是否相同,若相同返回0
{
if(!
strcmp(KeyWordTable[n],token))//比较token所指向的关键字和保留字表中哪个关键字相符
{
returnn+1;
//根据单词分类码表I,设置正确的关键字类别码,并返回此类别码的值
break;
}
n++;
}
return6;
//单词不是关键字,而是标识符
}
////////////////////////输出分析结果
voidout(inti,char*pStr)
charMnemonic[5];
if(0==i)
strcpy(Mnemonic,"
LB"
);
elseif(1==i)
RB"
elseif(2==i)
PL"
elseif(3==i)
MI"
elseif(4==i)
MU"
elseif(5==i)
DI"
elseif(6==i)
UCON"
elseif(7==i)
OVER"
elseif(8==i)
LT"
elseif(9==i)
LE"
elseif(10==i)
EQ"
elseif(11==i)
NE"
elseif(12==i)
GT"
elseif(13==i)
GE"
elseif(14==i)
BEGIN"
elseif(15==i)
END"
elseif(16==i)
IF"
elseif(17==i)
THEN"
elseif(18==i)
ELSE"
elseif(19==i)
IS"
elseif(20==i)
ID"
else
UnkownType"
printf("
(%s)对应%s\n"
Mnemonic,pStr);
////////////////////////报错部分
voidreport_error(introw)
%s无法识别的单词!
Inthe%drow\n"
TOKEN,row);
////////////////////////扫描程序部分
voidscanner(FILE*fp)
inti,c;
fseek(fp,-1,1);
//首先回溯一个字符,就是将文件所有的字符都在scanner内部判断,外部while循环不会浪费任何字符
ch=fgetc(fp);
//scanner中要想判断字符,必须开头先读一个字符
while('
==ch||'
\n'
\t'
==ch)//消耗文件中空字符串
if('
==ch)
row++;
ch=fgetc(fp);
if(EOF==ch)
return;
if(isalpha(ch))/*itmustbeaidentifer!
*/
TOKEN[0]=ch;
i=1;
while(isalnum(ch))
TOKEN[i]=ch;
i++;
ch=fgetc(fp);
TOKEN[i]='
\0'
fseek(fp,-1,1);
/*retract*/
c=lookup(TOKEN);
if(c!
=6)out(c+13,TOKEN);
elseout(c+14,TOKEN);
//此处加13或者14因为一些常量的定义产生冲突,被迫修改以适应
elseif(isdigit(ch)||'
.'
fseek(fp,-1,1);
//回溯一个字符,为下面循环内部使用先读字符后判断的格式。
intType;
CurrentState=0;
i=0;
do
ch=fgetc(fp);
i++;
TOKEN[i]='
Type=GetChar(ch);
EXCUTE(CurrentState,Type,fp,TOKEN,row,i);
}while(CurrentState!
=EndState);
}else
switch(ch)
case'
<
'
:
ch=fgetc(fp);
if(ch=='
='
)out(LE,"
="
elseif(ch=='
>
)out(NE,"
else
{
out(LT,"
}
break;
ch=fgetc(fp);
if('
{
out(EQ,"
=="
}
else
out(IS,"
)out(GE,"
out(GT,"
+'
InputWordType=PL;
out(PL,"
+"
-'
InputWordType=MI;
out(MI,"
-"
*'
InputWordType=MU;
out(MU,"
*"
/'
InputWordType=DI;
out(DI,"
/"
('
InputWordType=LB;
out(LB,"
("
)'
InputWordType=RB;
out(RB,"
)"
#'
InputWordType=OVER;
out(OVER,"
#"
default:
InputWordType=UNKNOWN;
report_error(row);
}break;
return;
/////////////////////////无符号数判断矩阵执行程序
intEXCUTE(intstate,intsymbol,FILE*fp,charJudgeStr[],introw,intindex)//row用于指示出错的行数,index用于为待输出的字符串赋结束符‘\0’时用
switch(state)
case0:
switch(symbol)
caseDIGIT:
n=0;
p=0;
e=1;
w=d;
CurrentState=1;
Class=UCON;
break;
casePOINT:
w=0;
n=0;
CurrentState=3;
default:
{
Class=ClassOther;
CurrentState=EndState;
printf("
无符号数的第一个字符是非法的!
\n"
break;
case1:
w=w*10+d;
//CurrentState=1
CurrentState=2;
casePOWER:
CurrentState=4;
if(ch!
=EOF)//如果是因为读到文件结束字符而终止识别(是正确识别一个无符号数结束),就不应该回退,否则可能造成死循环
fseek(fp,-1,1);
//遇到其他的字符,可能是一条语句中的其他字符,需后退,因为主函数外层循环每次都要读一个字符进行判断,而这个判读不回溯,所以在内部把这个多读的字符回溯
ICON=w;
CurrentState=EndState;
JudgeStr[index-1]='
InputWordType=UCON;
(UCON,%i)对应%s\n"
ICON,JudgeStr);
case2:
n++;
w=w*10+d;
=EOF)
fseek(fp,-1,1);
FCON=w*pow(10,e*p-n);
JudgeStr[index-1]='
InputWordType=UCON;
(UCON,%f)对应于%s\n"
FCON,JudgeStr);
case3:
CurrentState=2;
HandleError(JudgeStr,row);
case4:
p=p*10+d;
CurrentState=6;
caseMINUS:
e=-1;
CurrentState=5;
casePLUS:
CurrentState=5;
case5:
//判断一个无符号数的最后一个字符应该都是多余读取的,所以为了防止引起后面再次判断下一无符号数时产生呑字符的现象,都应该回溯一个字符
HandleError(JudgeS
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 编译 原理 实验 报告