【题目要求】
基于已编写的C++语法分析器,分析当前目录下input.txt文件中的语义并生成中间代码。
input.txt中的待分析代码必须以begin开头、以end结尾,文件最后以#结束。
输出结果存放到当前目录下的output.txt文件中。
【可分析语法】
算术表达式
多条简单赋值语句
【操作步骤】
1、在input.txt文件中输入或更改待分析的C源程序段(段末请以#结尾)。
2、双击程序exe文件即可完成语义分析程序的运行。
3、在output.txt文件中查看语义分析结果。
begin
int a = 12;
int b = 1 + 2 * 3 - (a - 4) / 8;
a = b % 5;
end#
Your words(must start with 'begin', and end with 'end'):
---------------------------------
begin
int a = 12;
int b = 1 + 2 * 3 - (a - 4) / 8;
a = b % 5;
end
---------------------------------
The result of semantic analysis:
(1) a = 12
(2) t1 = 2 * 3
(3) t2 = 1 + t1
(4) t3 = a - 4
(5) t4 = t3 / 8
(6) t5 = t2 - t4
(7) b = t5
(8) t6 = b % 5
(9) a = t6
CodeBlocks 10.05
运用递归下降语法制导翻译法,修改语法分析器,在语法分析部分插入语义动作。
struct /*四元式表*/
{
char result[8];
char ag1[8];
char op[8];
char ag2[8];
}quad[21];
void emit(char *result,char *ag1,char *op,char *ag2); /*声明四元式生成函数*/
char* newtemp(); /*临时变量生成函数*/
int quadIndex = 0; /*四元式下标*/
int k = 0; /*临时变量下标*/
int sum = 0; /*十进制数字*/
int main()
{
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
inputBufferIndex = 0; // 初始化输入缓冲区下标
scanf("%[^#]s", inputBuffer); // 读入源程序字符串到缓冲区,以#结束,允许多行输入,#会读成'\0'
printf("Your words(must start with 'begin', and end with 'end'):\n\n");
printf("---------------------------------\n");
printf("%s\n", inputBuffer);
printf("---------------------------------\n\n");
printf("The result of semantic analysis:\n\n");
oneWord = scaner(); // 获得一个新单词
lrparser();
if(lexicalError == true && syntacticError == true)
{
printf("\nPlease correct the above lexical errors and syntactic errors for semantic analysis!\n");
}
else
{
if(lexicalError == true)
{
printf("\nPlease correct the above lexical errors for semantic analysis!\n");
}
else if(syntacticError == true)
{
printf("\nPlease correct the above syntactic errors for semantic analysis!\n");
}
}
return 0;
}
/*四元式生成函数*/
void emit(char *result,char *ag1,char *op,char *ag2)
{
strcpy(quad[quadIndex].result,result); // 无法识别'->',得用'.'
strcpy(quad[quadIndex].ag1,ag1);
strcpy(quad[quadIndex].op,op);
strcpy(quad[quadIndex].ag2,ag2);
++quadIndex;
}
/*临时变量生成函数*/
char* newtemp()
{
char *p;
char m[8];
p = (char*)malloc(8);
itoa(++k,m,10);
strcpy(p+1,m);
p[0] = 't';
return p;
}
int lrparser()
{
int schain = 0;
while(isLineBreak()); // 判断是否存在换行
if(oneWord -> categoryCode != 1) // 'begin'的种别码
{
cout << "missing 'begin' error in line " << rowNumber << "!" << endl;
syntacticError = true;
}
else
{
oneWord = scaner(); // 获得一个新单词
}
schain = statementString(); // 调用语句串分析函数
if(oneWord -> categoryCode != 12)
{
cout << "missing 'end' error in line " << rowNumber << "!" << endl;
syntacticError = true;
}
else
{
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
if(oneWord -> categoryCode == 1000 && syntacticError == false && lexicalError == false) // '\0'的种别码
{
for(int i = 0; i < quadIndex; ++i)
{
cout << "(" << i + 1 << ") ";
cout << quad[i].result << " = ";
cout << quad[i].ag1 << " ";
cout << quad[i].op << " ";
cout << quad[i].ag2 << endl;
}
}
else
{
if(oneWord -> categoryCode != 1000)
{
cout << "the syntax after the first 'end' is invalid in line " << rowNumber << "!" << endl;
syntacticError = true;
}
while(true)
{
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
isLexicalError(); // 调用检测词法错误函数
if(oneWord -> categoryCode == 1000)
{
break;
}
}
}
}
return schain;
}
int statementString()
{
int schain = 0;
while(isLineBreak()); // 判断是否存在换行
schain = statement(); // 调用语句分析函数
while(oneWord -> categoryCode == 64) // ';'的种别码
{
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
isLexicalError(); // 调用检测词法错误函数
schain = statement(); // 调用语句分析函数
}
return schain;
}
int statement()
{
char tt[8];
char eplace[8];
int schain = 0;
switch (oneWord -> categoryCode)
{
case 1:
{
cout << "only the first 'begin' is valid in line " << rowNumber << "!" << endl;
oneWord -> categoryCode = 64;
syntacticError = true;
break;
}
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
case 11:
case 13:
{
if(oneWord -> categoryCode >= 2 && oneWord -> categoryCode <= 11)
{
oneWord = scaner(); // 获得一个新单词
isLexicalError(); // 调用检测词法错误函数
if(oneWord -> categoryCode == 64 || oneWord -> categoryCode == 12 || oneWord -> categoryCode == 1000
|| oneWord -> categoryCode == 20) // 说明出现char;或char end或char'\0'或char'\n'的情况
{
if(oneWord -> categoryCode == 20)
{
cout << "statement error in line " << (rowNumber - 1) << "!" << endl;
oneWord -> categoryCode = 64;
}
else
{
cout << "statement error in line " << rowNumber << "!" << endl;
}
syntacticError = true;
}
}
strcpy(tt,wordBuffer);
oneWord = scaner(); // 获得一个新单词
isLexicalError(); // 调用检测词法错误函数
if(oneWord -> categoryCode == 20)
{
cout << "missing ';' error in line " << (rowNumber - 1) << "!" << endl;
oneWord -> categoryCode = 64;
syntacticError = true;
}
else if(oneWord -> categoryCode == 12 || oneWord -> categoryCode == 1000)
{
cout << "missing ';' error in line " << rowNumber << "!" << endl;
syntacticError = true;
}
else if(oneWord -> categoryCode >= 42 && oneWord -> categoryCode <= 52)
// '='、'+='、'-='、'*='、'/='、'%='、'>>='、'<<='、'&='、'^='、'|='的种别码
{
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
isLexicalError(); // 调用检测词法错误函数
strcpy(eplace,expression()); // 调用(等号右边的)表达式分析函数
emit(tt,eplace,"","");
schain = 0;
if(oneWord -> categoryCode != 64) // 表达式一定以分号为结束
{
if(oneWord -> categoryCode == 20) // 说明是换行符
{
cout << "missing ';' error in line " << (rowNumber - 1) << "!" << endl;
oneWord -> categoryCode = 64;
}
else
{
cout << "missing ';' error in line " << rowNumber << "!" << endl;
}
syntacticError = true;
}
}
else if(oneWord -> categoryCode != 64)
{
cout << "missing equal sign error in line " << rowNumber << "!" << endl;
syntacticError = true;
}
return schain;
break;
}
case 12:
case 1000:
{
break;
}
default:
{
cout << "statement error in line " << rowNumber << "!" << endl;
syntacticError = true;
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
isLexicalError(); // 调用检测词法错误函数
while(oneWord -> categoryCode != 64 && oneWord -> categoryCode != 12
&& oneWord -> categoryCode != 1000)
{
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
isLexicalError(); // 调用检测词法错误函数
}
}
}
}
char* expression()
{
char *tp;
char *ep2;
char *eplace;
char *tt;
tp = (char*)malloc(12);
ep2 = (char*)malloc(12);
eplace = (char*)malloc(12);
tt = (char*)malloc(12);
strcpy(eplace,term()); // 调用项分析函数生成表达式计算的第一项eplace
while(oneWord -> categoryCode == 21 || oneWord -> categoryCode == 22) // '+'或'-'的种别码
{
strcpy(tt,oneWord -> value);
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
isLexicalError(); // 调用检测词法错误函数
strcpy(ep2,term()); // 调用项分析函数生成表达式计算的第二项ep2
strcpy(tp,newtemp()); // 调用newtemp产生临时变量tp存储计算结果
emit(tp,eplace,tt,ep2); // 生成四元式送入四元式表
strcpy(eplace,tp); // 将计算结果作为下一次表达式计算的第一项eplace
}
return eplace;
}
char* term()
{
char *tp;
char *ep2;
char *eplace;
char *tt;
tp = (char*)malloc(12);
ep2 = (char*)malloc(12);
eplace = (char*)malloc(12);
tt = (char*)malloc(12);
strcpy(eplace,factor()); // 调用因子分析函数生成表达式计算的第一项eplace
while(oneWord -> categoryCode >= 23 && oneWord -> categoryCode <= 25) // '*'、'/'、'%'的种别码
{
strcpy(tt,oneWord -> value);
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
isLexicalError(); // 调用检测词法错误函数
strcpy(ep2,factor()); // 调用因子分析函数生成表达式计算的第二项ep2
strcpy(tp,newtemp()); // 调用newtemp产生临时变量tp存储计算结果
emit(tp,eplace,tt,ep2); // 生成四元式送入四元式表
strcpy(eplace,tp); // 将计算结果作为下一次表达式计算的第一项eplace
}
return eplace;
}
char* factor()
{
char *fplace;
fplace = (char*)malloc(12);
strcpy(fplace," ");
if(oneWord -> categoryCode == 13) // 单词的种别码
{
strcpy(fplace,oneWord -> value);
oneWord = scaner(); // 获得一个新单词
isLexicalError(); // 调用检测词法错误函数
}
else if(oneWord -> categoryCode == 14) // 数字的种别码
{
itoa(sum,fplace,10);
oneWord = scaner(); // 获得一个新单词
isLexicalError(); // 调用检测词法错误函数
}
else if(oneWord -> categoryCode == 56) // '('的种别码
{
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
isLexicalError(); // 调用检测词法错误函数
fplace = expression(); // 调用(等号右边的)表达式分析函数
if(oneWord -> categoryCode == 57) // ')'的种别码
{
oneWord = scaner(); // 获得一个新单词
while(isLineBreak()); // 判断是否存在换行
isLexicalError(); // 调用检测词法错误函数
}
else
{
cout << "missing ')' error in line " << rowNumber << "!" << endl;
syntacticError = true;
}
}
else
{
cout << "expression error in line " << rowNumber << "!" << endl;
syntacticError = true;
}
return fplace;
}
如果文章内容出错或者您有更好的解决方法,欢迎到评论区指正和讨论!