[精]编译程序实验指导
编译程序实验指导书
实验目的:用C语言对一个C语言的子集编制一个一遍扫描的编译程序,以加深对编译原
理的理解,掌握编译程序的实现
和技术。
1(词法分析
1.1 实验目的
设计、编制并测试一个词法分析程序,加深对词法分析原理的理解。
1.2 实验要求
1.2.1 待分析的C语言子集的词法
1. 关键字
main if else int char for while
所有的关键字都是小写。
2(专用符号
= + - * / < <= > >= == != ; : , { } [ ] ( ) 3(其他标记ID和NUM
通过以下正规式定义其他标记:
*ID?letter(letter|digit)
*NUM?digit digit
letter?a|…|z|A|…|Z
digit?0|…|9…
4(空格由空白、制
符和换行符组成
空格一般用来分隔ID、NUM、专用符号和关键字,词法分析阶段通常被忽略。
1.2.2 各种单词符号对应的种别码
表1 各种单词符号的种别码
单词符号 种别码 单词符号 种别码 单词符号 种别码
main 1 = 21 , 32
int 2 + 22 : 33
char 3 - 23 ; 34
if 4 * 24 > 35
else 5 / 25 < 36
for 6 ( 26 >= 37
while 7 ) 27 <= 38
ID 10 [ 28 == 39
MUN 20 ] 29 != 40
{ 30 „\0? 1000
} 31 ERROR -1
1.2.3 词法分析程序的功能
输入:所给文法的源程序字符串。
输出:二元组(syn,token或sum)构成的序列。其中,
. syn为单词种别码。
. Token为存放的单词自身字符串。
. Sum为整型常量。
具体实现时,可以将单词的二元组用结构进行处理。
例如,对源程序
main()
{
int i=10;
while(i) i=i-1;
}
的源文件,经词法分析后输出如下序列:
(1,main) (26,() (27,)) (30,{} (2,int) (10,i) (21,=) (20,10) (34,;) (7,while)
(26,() (10,i) (27,)) (10,i) (21,=) (10,i) (23,-) (20,1) (34,;) (31,))
1.3 词法分析程序的主要算法思想
算法的基本任务是从字符串表示的源程序中识别出具有独立意义的单词符号,其基本思想是
根据扫描到的单词符号的第一个字符的种类,拼出相应的单词符号。
1. 主程序示意图
主程序示意图如图1所示。
置初值
调用扫描子程序
输出单词二元组
否 输入串结束
是
结束
图1 词法分析主程序示意图
其中初值包括如下两方面:
(1) 关键字表初值
关键字作为特殊标识符处理,把它们预先安排在一张表格中(称为关键字表),当扫描程序识
别出标识符时,查关键字表。如能查到匹配的单词,则该单词为关键字,否则为一般标识符。关
键字表为一个字符串数组,其描述如下:
char *KEY_WORDS[8]={“main”,”int”,”char”,”if”,”else”,”for”,”while”};
为分析方便,这里把main作关键字处理。
(2) 程序中需要用到的主要变量:syn,token和sum。
2. 扫描子程序的算法思想
首先设置三个变量:token用来存放构成单词符号的字符串;sum用来存放整型单词;syn
用来存放单词符号的种别编码。扫描子程序主要部分
如图2所示。
变量初始化
忽略空格
是 返回 是否文件结束
否
运算符,界字母 数字 其他符号 符等符号 拼字符串 拼数
否 是否关键字 对不同符号给出
相应的syn值 是
Syn=10
Syn为对应关键 Syn=11 报错 字的单词种别码
返回
图2 词法分析程序流程
2(语法分析
2.1 实验目的
编制一个递归下降分析程序, 实现对词法分析程序所提供的单词序列进行语法检查和结构
分析。
2.2 实验要求
利用C语言编制递归下降分析程序,并对C语言的简单子集进行分析。 2.2.1 待分析的C语言子集的语法
用扩充的BNF表示如下:
(1) <程序>?=main( )<语句块>
(2) <语句块>?=?{?<语句串>?}?
(3) <语句串>?=<语句>{;<语句>};
(4) <语句>?=<赋值语句>|<条件语句>|<循环语句>
(5) <赋值语句>?=ID=<表达式>
(6) <条件语句>?=if(<条件>)<语句块> (7) <循环语句>?=while<条件><语句块> (8) <条件>?=<表达式><关系运算符><表达式> (9) <表达式>?=<项>{+<项>|-<项>} (10)<项>?=<因子>{*<因子>|/<因子>} (11)<因子>?=ID|NUM|(<表达式>)
(12)<关系运算符>?=<|<=|>|>=|==|!=
2.3 语法分析程序的算法思想
(1) 主程序示意图如图3所示。
置初值
调用scaner读下一个单词符号
调用lrparser
结束
图3 语法分析主程序示意图
(2) 递归下降分析程序示意图如图4所示。
lrparser
否 否 是否单词串main()
是
调用scaner
调用语句块分析函数 出错处理
否 源程序是否结束
是
打印分析成功
图4递归下降分析程序示意图
(3) 语句块分析过程示意图如图5所示。
否 是否{
是
调用scaner
调用语句串分析过程 出错处理
否 是否}
是
出口
图5语句块分析示意图
(4) 语句串分析过程示意图如图6所示。
调用statement函数
否
否 是否;
是
调用scaner
调用statement函数
出错处理
图6语句串分析示意图
(5) statement (语句) 函数流程如图7所示; (6) expression(表达式)分析过程如图8所示; (7) term(项)分析过程如图9所示; (8) condition(条件)分析过程如图10所示; (9) factor(因子)分析过程如图11所示。
否 否 否
是否标识符 是否if 是否while
ififfifififif是 是 是 是否标识符
是否标识符 调用scaner 调用scaner 调用scaner
标识符
否
是否= 调用condition 调用condition
是
调用语句块 调用语句块 调用scaner
调用expression 出错处理
图7 statement函数流程
调用factor 调用term 调用ffactor
否 否 是否*、/ 是否+、- 是 是
调用scaner 出错处理 调用scaner 出错处理
调用factor 调用term
图8 expression分析过程示意图 图9 term分析过程示意图
调用expression
否 是否逻辑运算符
是
出错处理 调用scaner
调用expression 图10 condition分析过程示意图
是 是否标识符
否
是
是否数字
否
是否(
否
是
调用scaner
调用expression 调用scaner
否 是否)
是
出错处理 调用scaner
图11 factor分析过程示意图
3(语义分析产生中间代码
3.1 实验目的
通过上机实验,加深对语法制导翻译原理的理解,掌握将语法分析所识别的语法成分变换
为中间代码的语义翻译方法。
3.2 实验要求
采用递归下降语法制导翻译法对算术表达式、赋值语句、条件语句、循环语句进行语义分
析生成四元式序列。
3.2.1 实验的输入和输出
输入是语法分析提供的正确的单词串,输出是四元式序列。 例如,对于语句串
i=2*3+4;
if (i>10) j=3;
while j>10 k=1;
输出的四元式序列如下:
(1) (*,2,3,T1)
(2) (+,2,T1,T2)
(3) (=,T2, ,i)
(4) (j>,i,10,6)
(5) (j<, , ,7))
(6) (=,3, ,j)
(7) (j<,j,10,9)
(8) (j, , ,11)
(9) (=,1, ,k)
(10)(j, , ,7)
(11) ......
3.2.2 算法思想
1. 设置语义过程
(1). int gen(op,arg1,arg2,result) 该函数是将四元式(op,arg1,arg2,result)送到四元式表中。 (2). char *newtemp( )
该函数回送一个新的临时变量名,临时变量名产生的顺序为T1,T2,.... (3). int merg(p1,p2)
该函数将以p1和p2为头指针的两条链合并为一,合并后的链首为返回值。 (4). int bp(p,t)
该函数的功能是把p所链接的每个四元式的第四区段都填为t。 2. 主程序示意图
置初值
调用scaner
…
调用lrparser
打印四元式列表
结束
图12 语义分析主程序示意图
3. 函数lrparser在原来语法分析的基础上插入相应的语义动作 将输入串翻译成四元式序列。在实验中我们只对表达式、if语句和while语句进行翻译,
其具体翻译程序见实验实例。
4(实验实例
/****************************************************/
/*文件:globals.h */ /*定义分析器需要的一些数据结构、宏等 */
/*本头文件必须在其他文件前引用 */
/***************************************************/
# ifndef _GLOBALS_H
# define _GLOBALS_H
# include
# include
# include
/*单词种别码*/
# define _SYN_MAIN 1
# define _SYN_INT 2
# define _SYN_CHAR 3
# define _SYN_IF 4
# define _SYN_ELSE 5
# define _SYN_FOR 6
# define _SYN_WHILE 7
/*以上为关键字的单词种别码*/
# define _SYN_ID 10 /*标识符的单词种别码*/
# define _SYN_NUM 20 /*整数的单词种别码*/
# define _SYN_ASSIGN 21 /* = */ # define _SYN_PLUS 22 /* + */ # define _SYN_MINUS 23 /* - */ # define _SYN_TIMES 24 /* * */ # define _SYN_DIVIDE 25 /* / */ # define _SYN_LPAREN 26 /* ( */ # define _SYN_RPAREN 27 /* ) */ # define _SYN_LEFTBRACKET1 28 /* [ */ # define _SYN_RIGHTBRACKET1 29 /* ] */ # define _SYN_LEFTBRACKET2 30 /* { */ # define _SYN_RIGHTBRACKET2 31 /* } */ # define _SYN_COMMA 32 /* , */ # define _SYN_COLON 33 /* : */ # define _SYN_SEMICOLON 34 /* ; */
# define _SYN_LG 35 /* > */ # define _SYN_LT 36 /* < */ # define _SYN_ME 37 /* >= */ # define _SYN_LE 38 /* <= */ # define _SYN_EQ 39 /* == */ # define _SYN_NE 40 /* != */ # define _SYN_END 1000 /* 源程序结束标志 */
# define _SYN_ERROR -1 /* error */
# define MAXLENGTH 255 /* 一行允许的字符个数 */
union WORDCONTENT { /*存放单词的联合*/
char T1[MAXLENGTH];
int T2;
char T3;
};
typedef struct WORD { /*单词二元组*/
int syn;
union WORDCONTENT value;
} WORD;
# endif
/**************************************************/ /*文件:scan.h */ /*定义词法分析器的接口 */
/**************************************************/ # ifndef _SCAN_H
# define _SCAN_H
/* 一个TAB占用的空格数 */
# define _TAB_LENGTH 4
*/ /* 关键字结束标记
# define _KEY_WORD_END "waiting for your expanding" /* 函数 Scaner 得到源程序里的下一个单词符号 */
void Scaner(void);
# endif
/**************************************************/ /*文件:scan.c */ /*分析器的词法扫描部分 */
/**************************************************/ # include "globals.h"
# Include "scan.h"
void Do_Tag(char *strSource); /* 识别标识符的中间状态 */
void Do_Digit(char *strSource); /* 识别数字的中间状态 */
void Do_EndOfTag(char *strSource); /* 识别标识符最后的一个状态 */
void Do_EndOfDigit(char *strSource); /* 识别数字最后的一个状态 */
void Do_EndOfEqual(char *strSource); /* =,== */ void Do_EndOfPlus(char *strSource); /* + */
void Do_EndOfSubtraction(char *strSource); /* - */ void Do_EndOfMultiply(char *strSource); /* * */ void Do_EndOfDivide(char *strSource); /* / */ void Do_EndOfLParen(char *strSource); /* ( */ void Do_EndOfRParen(char *strSource); /* ) */ void Do_EndOfLeftBracket1(char *strSource); /* [ */ void Do_EndOfRightBracket1(char *strSource); /* ] */ void Do_EndOfLeftBracket2(char *strSource); /* { */ void Do_EndOfRightBracket2(char *strSource); /* } */ void Do_EndOfColon(char *strSource); /* : */ void Do_EndOfComma(char *strSource); /* , */ void Do_EndOfSemicolon(char *strSource); /* ; */ void Do_EndOfMore(char *strSource); /* >,>= */ void Do_EndOfLess(char *strSource); /* <,<= */
' \0 ' 作为源程序结束 */ void Do_EndOfEnd(char *strSource); /* 用
void PrintError(int nColumn,int nRow,char chInput); /* 词法分析错误输出 */
void Scaner(void); /* 词法扫描函数 */
extern char *strSource; /* 待分析的源程序 */
extern FILE *fw ; /* 结果输出文件 */
int gnColumn,gnRow, /* 行列号 */
gnLocate, /* 下一个字符脚标 */
gnLocateStart; /* 下一个单词开始位置 */
Word uWord; /* 扫描出的单词 */
/* 关键字表 */
char
*KEY_WORDS[20]={"main","int","char","if","else","for","while","void",_KEY_WORD_END};
int IsDigit(char chInput) /* 判断扫描的字符是否数字 */
{
if (chInput<='9' && chInput>='0') return 1;
else return 0;
}
int IsChar(char chInput) /* 判断扫描的字符是否字母 */
{
if ((chInput<='z' && chInput>='a')
|| (chInput<='Z' && chInput>='A'))
return 1;
else return 0;
}
void Do_Start(char *strSource) /* 开始识别最先一个单词 */
{
gnLocateStart=gnLocate;
switch (strSource[gnLocate]) { /* 根据第一个字符判断 */
case '+': Do_EndOfPlus(strSource); break;
case '-': Do_EndOfSubtraction(strSource); break;
case '*': Do_EndOfMultiply(strSource); break;
case '/': DoEndOfDivide(strSource); break;
case '(': Do_EndOfLParen(strSource); break;
case ')': Do_EndOfRParen(strSource); break;
case '[': Do_EndOfLeftBracket1(strSource); break;
case ']': Do_EndOfRightBracket1(strSource); break;
case '{': Do_E.dOfLeftBracket2(strSource); break;
case '}': Do_EndOfRightBracket2(strSource); break;
case ':': Do_EndOfColon(strSourcei; break;
case ',': Do_EndOfComma(strSource); break;
case ';': Do_EndOfSemicolon(strSource); break;
case '>': Do_EndOfMore(strSource); break;
case '<': Do_EndOfLess(strSource); break;
case '=': Do_EndOfEqual(strSource); break;
case '\0': Do_EndOfEnd(strSource); break;
default:
if (IsChar(strSource[gnLocate])) { /* 是标识符或关键字 */
Do_Tag(strSource);
}
else if (IsDigit(strSource[gnLocate])) { /* 可能是整数 */
uWord.value.T2=strSource[gnLocate]-'0';
Do_Digit(strSource);
}
else { /* 其他符号 */
if (strSource[gnLocate]!=' ' && strSource[gnLocate]!='\t'
&& strSource[gnLocate]!=' \n' && strSource[gnLocate]!='\r'] {
PrintError(gnColumn,gnRow,strSource[gnLocate]);
}
if (strSource[gnLocate]=='\n ' || strSource[gnLocate}=='\r') {
gnColumn++;
gnRow=1;
}
else if (strSource[gnLocate]=='\t') {
gnColumn+=_TAB_LENGTH;
}
else gnRow++;
gnLocate++;
Do_Start(strSouce);
}
break;
}
return;
}
void Do_Tag(char *strSource) /* 识别标识符的中间状态 */ {
gnLocate++;
gnRow++;
if (IsChar(strSource[gnLocate]) || IsDigit(strSource[gnLocate])) {
/* 是数字或者字母 */
Do_Tag(strSource);
}
else Do_EndOfTag(strSource);
return;
}
void Do_Digit(char *strSource) /* 识别整数的中间状态 */ {
gnLocate++;
gnRow++;
if (IsDigit(strSource[gnLocate])) { /* 是数字 */
uWord.value.T2=uWord.value.T2*10
+strSource[gnLocate]-'0'; /* 累加识别的数字 */
Do_Digit(strSource);
}
else Do_EndOfDigit(strSource);
return;
}
void Do_EndOfTag(char *strSource) /* 标识符的最后状态 */ {
int nLoop;
uWord.syn=_SYN_ID; /* 单词种别码缺省为标识符 */ /* 记录标识符 */
strncpy(uWord.value.T1,strSource+gnLocateStart,gnLocate-gnLocateStart);
uWord.value.T1[gnLocate-gnLocateStart]='\0';
nLoop=0;
while (strcmp(KEY_WORDS[nLoop],_KEY_WORD_END)) {
/* 查关键字表,是否关键字 */
if (! strcmp(KEY_WORDS[nLoop],uWord.value.T1)) {
/* 比较和某关键字相符 */
uWord.syn=nLoop+1; /* 设置正确的 syn */
break;
}
nLoop++;
}
return;
}
void Do_EndOfDigit(char *strSource) /* 识别数字的最后状态 */ {
uWord.syn=_SYN_NUM;
return;
}
void Do_EndOfEqual(char *strSource) /* =,== */
{
if (strSource[gnLocate+1]!='=') { /* = */
uWord.syn=_SYN_ASSIGN;
uWord.value.T3=strSource[gnLocate];
}
else { /* == */
gnLocate++;
gnRow++;
uWord.syn=_SYN_EQ;
strcpy(uWord.value.T1,"==");
}
gnLocate++;
gnRow++;
return;
}
void Do_EndOfPlus(char *strSource) /* + */
{
uWord.syn=_SYN_PLUS;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfSubtraction(char *strSource) /* - */
{
uWord.syn=_SYN_MINUS;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfMultply(char *strSource) /* * */ {
uWord.syn=_SYN_ TIMES;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfDivide(char *strSource) /* / */ {
uWord.syn=_SYN_DIVIDE;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfLParen(char *strSource) /* ( */ {
uWord.syn=_SYN_LPAREN;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfRParen(char *strSource) /* ( */ {
uWord.syn=_SYN_RPAREN;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfLeftBracket1(char *strSource) /* [ */
{
uWord.syn=_SYN_LEFTBRACKET1;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfRightBracket1(char *strSource) /* ] */
{
uWord.syn=_SYN_RIGHTBRACKET1;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfLeftBracket2(char *strSource) /* { */
{
uWord.syn=_SYN_LEFTBRACKET2;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfRightBracket2(char *strSource) /* } */
{
uWord.syn=_SYN_RIGHTBRACKET2;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfColon(char *strSource) /* : */ {
uWord.syn=_SYN_COLON;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfComma(char *strSource) /* , */ {
uWord.syn=_SYN_COMMA;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfSemicolon(char *strSource) /* ; */ {
uWord.syn=_SYN_SEMICOLON;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void Do_EndOfMore(char *strSource) /* >,>= */ {
if (strSource[gnLocate+1]!='=') { /* > */
uWord.syn=_SYN_LG;
uWord.value.T3=strSource[gnLocate];
}
else { /*>= */
gnLocate++;
gnRow++;
uWord.syn=_SYN_ME;
strcpy(uWord.value.T1,">=");
}
gnLocate++;
gnRow++;
return;
}
void Do_EndOfLess(char *strSource) /* <,<= */ {
if (strSource[gnLocate+1]!='=') { /* < */
uWord.syn=_SYN_LT;
uWord.value.T3=strSource[gnLocate];
}
else { /*<= */
gnLocate++;
gnRow++;
uWord.syn=_SYN_LE;
strcpy(uWord.value.T1,"<=");
}
gnLocate++;
gnRow++;
return;
}
'\0',源程序结束 */ void Do_EndOfEnd(char *strSource) /* 读到
{
uWord.syn=_SYN_END;
uWord.value.T3=strSource[gnLocate];
gnLocate++;
gnRow++;
return;
}
void PrintWord(Word uWord) /* 打印二元组 */
{
if (uWord.syn<=_SYN_ID /* 关键字、标识符或者有错误 */
|| uWord.syn==_SYN_ME /* >= */
|| uWord.syn==_SYN_LE /* <= */
|| uWord.syn==_SYN_EQ) { /* == */
fprintf(fw,"\n(%d,\t%s)",uWord.syn,uWord.value.T1);
}
else if (uWord.syn==_SYN_NUM) { /* 数字 */
fprintf(fw,"\n(%d,\t%d)",uWord.syn,uWord.value.T2);
}
else { /* 其他符号 */
fprintf(fw,"\n(%d,\t%c)",uWord.syn,uWord.value.T3);
}
return;
}
void ApartWord(char *strSource) /* 根据输入的源程序识别所有的单词 */ {
gnColumn=gnRow=1;
gnLocate=gnLocateStart=0;
while (strSource[gnLocate]) {
Scaner( );
}
return;
}
void Scaner(void) /* 词法扫描函数 */
{
Do_Start(strSource); /* 识别出一个单词 */
printWord(uWord); /* 打印二元组 */
return;
}
void PrintError(int nColumn,int nRow,char chInput) /* 打印词法扫描发现的错误 */ {
fprintf(fw,"\n 无法识别的单词 --->Col:%d\tRow:%d\tChar:%c",nColumn,nRow,chInput);
return;
}
/**************************************************/
/*文件:semanteme.h */
/*定义语法(语义)分析器的接口 */
/**************************************************/
# ifndef _SEMANTEME_H
# define _SEMANTEME_H
/* 四元组的结构 */
typedef struct QUAD {
char op[MAXLENGTH]; /* 操作符 */
char argv1[MAXLENGTH]; /* 第一个操作数 */
char argv2[MAXLENGTH]; /* 第二个操作数 */
char result[MAXLENGTH]; /* 运算结果 */
}QUATERNION;
void lrparse(void); /* 语法语义分析主函数 */
# endif
/**************************************************/
/*文件:semanteme.c */
/*分析器的语法语义扫描部分 */
/**************************************************/
# include "globals.h"
# include "scan.h"
# include "semanteme.h"
QUATERNION *pQuad; /* 存放四元组的元组 */ int nSuffix,nNXQ, /* 临时变量的编号 */
ntc,nfc;
extern Word uWord; /* 扫描得到的单词 */
extern int gnColumn,gnRow; /* 行列号 */
FILE *fw; /* 打印结果的文件指针 */
char *strFileName; /* 打印结果的文件名 */
char *strSource; /* 源程序 */
char *Expression(void);
char *Term(void);
char *Factor(void);
void Statement_Block(int *nChain);
void LocateError(int nColumn,int nRow) /* 定位语法错误 */ {
fprintf(fw,"\nCol:%d\tRow:%d--->",nColumn+1,nRow);
}
void error(char *strError) /* 输出扫描发现的错误 */ {
LocateError(gnColumn,gnRow);
fprintf(fw,"%s",strError);
return;
}
void Match(int syn,char *strError) /* 判断当前识别出的单词是否需要的单词,
如果不是则报错,否则扫描下一个单词 */ {
if (syn==uWod.syn) Scaner( );
else error(strError);
return;
}
void gen(char *op,char *argv1,char *argv2,char *result) /* 生成一个四元式 */ {
sprintf(pQuad[nNXQ].op,op);
sprintf(pQuad[nNXQ].argv1,argv1);
sprintf(pQuad[nNXQ].argv2,argv2);
sprintf(pQuad[nNXQ].result,result);
nNXQ++;
return;
}
void PrintQuaternion(void) /* 打印一个四元式 */
{
int nLoop;
for (nLoop=1;nLoop=_SYN_LG) {
swich (uWord.syn) {
case _SYN_LT:
case _SYN_LG:
sprintf(opp,"%c",uWord.value.T3);
break;
default:
sprintf(opp,"%s",uWord.value.T1);
break;
}
Scaner( );
eplace2=Expression( );
*etc=nNXQ;
*efc=nNXQ+1;
sprintf(strTemp,"j%s",opp);
gen(strTemp,eplace1,eplace2,"0");
gen("j","","","0");
}
else error("关系运算符");
}
void Statement(int *nChain) /* 语句分析函数 */
{
char strTemp[MAXLENGTH],eplace[MAXLENGTH];
int nChainTemp,nWQUAD;
switch (uWord.syn) {
case _SYN_ID:
strcpy(strTemp,uWord.value.T1);
Scaner( );
Match(_SYN_ASSIGN,”=”);
Strcpy(eplace,Expression( ));
Match(_SYN_SEMICOLON,";");
gen("=",eplace,"",strTemp);
*nChain=0;
break;
case _SYN_IF:
Match(_SYN_IF,"if");
Match(_SYN_LPAREN,"(");
Condition(&ntc,&nfc);
bp(ntc,nNXQ);
Match(_SYN_RPAREN,")");
Statement_Block(&nChainTemp);
*nChain=merg(nChainTemp,nfc);
break;
case _SYN_WHILE:
Match(_SYN_WHILE,"while");
nWQUAD=nNXQ;
Match(_SYN_LPAREN,"(");
Condition(&ntc,&nfc);
bp(ntc,nNXQ);
Match(_SYN_RPAREN,")");
Statement_Block(&nChainTemp);
bp(nChainTemp,nWQUAD);
sprintf(strTemp,"%d",nWQUAD);
gen("j","","",strTemp);
*nChain=nfc;
break;
}
return;
}
void Statement_Sequence(int *nChain) /* 语句串分析函数 */ {
Statement(nChain);
while (uWord.syn==_SYN_ID || uWord.syn==_SYN_IF
|| uWord.syn==_SYN_WHILE) { /* id if while */
bp(*nChain,nNXQ);
Statement(nChain);
}
bp(*nChain,nNXQ);
return;
}
void Statement_Block(int *nChain) /* 语句块分析函数 */ {
Match(_SYN_LEFTBRACKET2,"{");
Statement_Sequence(nChain);
Match(_SYN_RIGHTBRACKET2,"}"); }
void Parse(void)
{
int *nChain;
Scaner( );
Match(_SYN_MAIN,"main");
Match(_SYN_LPAREN,"(");
Match(_SYN_RPAREN,")");
Statement_Block(&nChain);
if (uWord.syn!=_SYN_END) fprintf(fw," 源程序非正常结束~");
PrintQuaternion( );
}
void lrparse(void) /* 语法语义分析主函数 */
{
pQuad=(QUATERNION *) malloc(strlen(strSource) * sizeof(QUATERNION));
nSuffix=0;
nfc=ntc=nNXQ=1;
fw=fopen(strFileName,"w");
Parse( );
fclose(fw);
}