实验二
题目;语法分析(一)
目的:通过该实验使学生掌握描述语法的文法和并能利用递归下降分析方法对表达式进行语法分析
要求:在实验一的基础上,对符号表中的单词采用递归下降分析方法进行语法分析,对不符合给定的文法的字符串,给出错误信息。
内容:给定描述语法的文法为:
E→E+T|E-T|T
T→T*F|T/F|F
F→F^P|P
P→i
注:i为实验一中分析得到的整型数值型数据,+、-、*和/为实验一文法二所描述的算符。
使用的数据结构:
1.定义一个结构体,利用该结构体定义一个数组stable,用来存放字符串中字符的属性(类型class和值value)。(与实验一同用)
2.定义一个整型数组eft,大小与stable数组相同,记录对应单词位置是否有语法错误
#include <iostream>
#include <cstring>
#define MAX 100
#define DIGIT 0
#define OPER 1
#define ERROR -1
struct node
{
char charType;
union {
/* data */
char valChar;
int valInt;
};
};
char in[MAX]; // input String
int eft[MAX]; // error table
struct node stable[MAX];
bool isFrontDigit = false;
bool isError = false;
int stableIndex = 0;
int analysisIndex = 0;
void A();
void B();
void F();
void E();
void T();
void match(char);
void init()
{
memset(eft, 0, sizeof(eft));
memset(in, 0, sizeof(in));
memset(stable, 0, sizeof(stable));
}
int decideType(char c)
{
if (c >= '0' && c <= '9')
return DIGIT;
else if (c == '+' || c == '-' || c == '*' || c == '/')
return OPER;
else
return ERROR;
}
void errorLexical(char in[], int eft[], int index)
{
int lexicalError = 0;
while (in[index] != '\0')
{
if (decideType(in[index]) == ERROR)
{
eft[index] = 1;
lexicalError++;
}
++index;
}
printf("Lexical %d error(s):\n", lexicalError);
// output error position
int i;
for (i = 0; i < index; ++i)
{
if (eft[i] == 1)
printf(" index:%d -> %c\n", i + 1, in[i]);
}
}
/**
* 0 error
* 1 true
*/
int buildStable()
{
int i = 0;
while (in[i] != '\0')
{
// ignore spacebar
if (in[i] == ' ')
{
++i;
continue;
}
else
{
// lexical error break
if (decideType(in[i]) == ERROR)
{
errorLexical(in, eft, i);
isError = true;
return 0;
}
// is character
else if (decideType(in[i]) == OPER)
{
stable[stableIndex].charType = 'o';
stable[stableIndex].valChar = in[i];
++stableIndex;
isFrontDigit = false;
}
// is digit
else if (decideType(in[i]) == DIGIT)
{
if (isFrontDigit)
{
--stableIndex;
stable[stableIndex].valInt = stable[stableIndex].valInt * 10 + in[i] - '0';
++stableIndex;
}
else
{
stable[stableIndex].charType = 'n';
stable[stableIndex].valInt = in[i] - '0';
++stableIndex;
isFrontDigit = true;
}
}
}
++i;
}
return 1;
}
void errorSyntax()
{
printf("Syntax error:\n");
printf(" index:%d -> ", analysisIndex + 1);
if (stable[analysisIndex].charType == 'o')
printf("%c\n", stable[analysisIndex].valChar);
else
printf("%d\n", stable[analysisIndex].valInt);
exit(0);
}
void SyntaxAnalysis()
{
analysisIndex = 0;
E();
}
void E()
{
if (stable[analysisIndex].charType == 'n')
{
T();
A();
}
else
errorSyntax();
}
void A()
{
if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '+')
{
match('+');
T();
A();
}
else if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '-')
{
match('-');
T();
A();
}
else if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '#')
{
analysisIndex++;
return;
}
else
errorSyntax();
}
void T()
{
if (stable[analysisIndex].charType == 'n')
{
F();
B();
}
else
errorSyntax();
}
void B()
{
if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '*')
{
match('*');
F();
B();
}
else if (stable[analysisIndex].charType == 'o' && stable[analysisIndex].valChar == '/')
{
match('/');
F();
B();
}
else if (stable[analysisIndex].charType == 'o' && (stable[analysisIndex].valChar == '+' || stable[analysisIndex].valChar == '-' || stable[analysisIndex].valInt == '#'))
{
return;
}
else
errorSyntax();
}
void F()
{
if (stable[analysisIndex].charType == 'n')
{
analysisIndex++;
return;
}
else
errorSyntax();
}
void match(char ch)
{
if (analysisIndex < stableIndex && stable[analysisIndex].valChar == ch)
analysisIndex++;
else
errorSyntax();
}
int main()
{
init();
std::cin.getline(in, MAX);
if (buildStable() == true)
{
// add end flag
stable[stableIndex].charType = 'o';
stable[stableIndex].valChar = '#';
stableIndex++;
// output result
printf("Lexical Complete!\n");
printf("result: ");
for (int i = 0; i < stableIndex; ++i)
{
if (stable[i].charType == 'o')
printf("%c", stable[i].valChar);
else if (stable[i].charType == 'n')
printf("%d", stable[i].valInt);
else
{
printf("Program error!");
exit(0);
}
}
printf("\n");
SyntaxAnalysis();
}
return 0;
}
版权属于:moluuser
本文链接:https://archive.moluuser.com/archives/24/
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
网上搜代码竟然搜到校友了OωO
你也是清华的?