编译原理 | 课程设计 — PL/0编译程序语义分析
1、任务描述
基于第二章的词法分析程序和第三章的语法分析程序,使用C/C++语言编写PL/0编译程序的语义分析程序,并生成四元式形式的中间代码。
2、编程要求
完成上述编程任务,将C/C++语言源程序复制粘贴到右侧代码编辑器,点击“评测”按钮,运行程序,系统会自动进行结果对比。
3、测试说明
平台会对你编写的代码进行测试:
测试输入:
const a = 10; var b, c; //单行注释 /* * 多行注释 */ procedure p; if a <= 10 then begin c := b + a; end; begin read(b); while b # 0 do begin call p; write(2 * c); read(b); end; end.
预期输出:
语义正确 中间代码: (1)(syss,_,_,_) (2)(const,a,_,_) (3)(=,10,_,a) (4)(var,b,_,_) (5)(var,c,_,_) (6)(procedure,p,_,_) (7)(j<=,a,10,$8) (8)(+,b,a,c) (9)(ret,_,_,_) (10)(read,b,_,_) (11)(j#,b,0,$13) (12)(j=,b,0,$17) (13)(call,p,_,_) (14)(*,2,c,T1) (15)(write,T1,_,_) (16)(read,b,_,_) (17)(syse,_,_,_) 符号表: const a 10 var b 0 var c 0 procedure p
测试输入:
const a = 10; var a, b, c; procedure p; if a <= 10 then begin c := b + a; end; begin read(b); while b # 0 do begin call p; write(2 * c); read(b); end; end.
预期输出:
(语义错误,行号:2)
测试输入:
const a = 10; var b, c; //单行注释 /* * 多行注释 */ procedure p; if a <= 10 then begin c := b + a; end; begin read(p); while b # 0 do begin call p; write(2 * c); read(b); end; end.
预期输出:
(语义错误,行号:16)
测试输入:
const a = 10; var b, c; //单行注释 /* * 多行注释 */ procedure p; if a <= 10 then begin c := b + a; end; begin read(p); while b # 0 do begin call q; write(2 * c); read(b); end; end.
预期输出:
(语义错误,行号:19)
测试输入:
const a = 10; var a, b, c; //单行注释 /* * 多行注释 */ procedure p; if a <= 10 then begin c := b + a; end; begin read(p); while b # 0 do begin call q; write(2 * d); read(b); end; end.
预期输出:
(语义错误,行号:2) (语义错误,行号:16) (语义错误,行号:19) (语义错误,行号:20)
4、代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
/* ------------ 全局变量声明定义 ------------ */
/* 单词表 */
typedef struct WordTable{
int type; // 所属类型
char id[20]; // 标识识别符值
int lineNum; // 所在的行
int flag = 0;
};
WordTable wordTable[100]; // 单词表
char word[20] = "\0"; // 存储单个字符,添加到 wordTable 中
/* 符号表 */
typedef struct SymbolTable {
char type[20];
char variable[20];
int value;
};
SymbolTable symbolTable[50]; // 符号表
/* 内部代码 */
typedef struct InterCode {
char op[20];
char arg1[20];
char arg2[20];
char result[20];
};
InterCode interCode[50];
/* 标签表 */
typedef struct LabelTable {
char name[10];
int value = -1;
};
LabelTable lableTable[50]; // 标签表
int count_grammarError = 0; // 语法错误个数
int count_semanticError = 0; // 语义错误个数
int grammarErrorLine = 0; // 语法错误行号
int quaternionLine = 0; // 四元式行号
int wordIndex = 0; // 记录当前 wordTable 的下标
int symbolIndex = 0; // 记录当前 symbolTable 的下标
int lableIndex = 0; // 记录当前 lableTable 的下标
char allWord[39][20] ={
"begin","call","const","do","end","if","odd","procedure",
"read","then","var","while","write","(",")",",",";",".",
"+","-","*","/","=","#","<",">","<=",">=",":=","0","1","2","3",
"4","5","6","7","8","9",
};
char reservedWord[20][20] ={ // 保留字
"begin","call","const","do","end","if","odd","procedure",
"read","then","var","while","write"
};
/* ------------ 函数声明 ------------ */
void LexicalAnalysis(); // 词法分析
void SemanticAnalysis(); // 语义分析
void GrammarErrorPrint(int a); // 语义错误打印
void SemanticErrorPrint(); // 语义错误打印
void GenerateQuaternion(const char* op, const char* arg1, const char* arg2, const char* result, int e); // 生成中间代码四元式
int IsReservedWord(char* s); //是否保留字
int Pow(int num, int j); // 阶乘
char* newlabel(); // 新标签
void label(char s[]); // 标签
char* id(); // 变量名声明判断
void number(int a); // 数字
void identifier(int a); // 标识符
void constant(int a); //常量
void variable(int a); // 变量
void procedure(); // 程序
void subroutine(char* Snext); // 子程序
void sentence(char* a); // 语句
void condition(char* Etrue, char* Efalse); // 条件
void expression(); // 表达式
void term(); // 项
void factor(); // 因子
/* ------------ 函数定义 ------------ */
//词法分析
void LexicalAnalysis() {
int i = 0, key = 0, lineNum = 1, inputFlag = 0, wordFlag = 0;
char input;
while ((input = getchar()) != EOF) {
if ((input >= 'a' && input <= 'z') || (input >= 'A' && input <= 'Z') || (input >= '0' && input <= '9')) {
if (!key) {
if (input >= '0' && input <= '9') {
inputFlag = 1;
}
}
else {
if (inputFlag) {
if ((input >= 'a' && input <= 'z') || (input >= 'A' && input <= 'Z')) {
wordFlag = 1;
}
}
}
word[key++] = input; //连续几个字母,数字的连成单词
word[key] = '\0';
continue;
}
else {
if (strcmp(word, "") != 0) {
strcpy(wordTable[i].id, word); //将单词拷贝到结构数组中
wordTable[i].lineNum = lineNum;
strcpy(word, "");
key = 0; //回到临时数组的开始位置
if (wordFlag) {
wordFlag = 0;
wordTable[i].flag = 1;
}
if (strlen(wordTable[i].id) > 8) {
wordTable[i].flag = 1;
}
i++; //结构数组的下标加1
inputFlag = 0;
}
//去掉空格、回车和tab键
if (input == ' ' || input == 10 || input == 13 || input == ' ') {
// 换行,回车,所在行数增加
if (input == '\n')
lineNum++;
continue;
}
else {
word[0] = input;
if (word[0] == ':' || word[0] == '>' || word[0] == '<') {
input = getchar();
if (input == '=') {
word[1] = input;
word[2] = '\0';
}
strcpy(wordTable[i].id, word);//将非字母数字符号拷贝到结构数组中
wordTable[i].lineNum = lineNum;
strcpy(word, "");
key = 0;
i++;
}
else if (word[0] == '/') {
strcpy(word, "");
key = 0;
input = getchar();
if (input == '/') {
input = getchar();
while (input != 10) {
input = getchar();
}
lineNum++;
}
else if (input == '*') {
input = getchar();
if (input == 10) {
lineNum++;
}
while (1) {
char c;
input = getchar();
if (input == 10) {
lineNum++;
}
if (input == '*' && (c = getchar()) == '/') {
break;
}
}
}
}
else {
word[1] = '\0';
strcpy(wordTable[i].id, word);//将非字母数字符号拷贝到结构数组中
wordTable[i].lineNum = lineNum;
strcpy(word, "");
key = 0;
i++;
}
}
}
}
for (int j = 0; j < i; j++) {
for (int k = 0; k < 38; k++) {
if ((strcmp(wordTable[j].id, allWord[k])) == 0) {
if (k >= 0 && k < 13) {
wordTable[j].type = 1;//保留字
wordTable[j].flag = 0;
}
else if (k >= 13 && k < 18)
wordTable[j].type = 5;//分隔符
else if (k >= 18 && k < 29)
wordTable[j].type = 4;//运算符
else if (k >= 29 && k < 39)
wordTable[j].type = 3;//数字
break;
}
else if (wordTable[j].id[0] >= '0' && wordTable[j].id[0] <= '1' && wordTable[j].flag == 0) {
wordTable[j].type = 6;//无符号数
}
else if (wordTable[j].id[0] == '@' || wordTable[j].id[0] == '&' || wordTable[j].id[0] == '!') {
wordTable[j].type = 7;//非法字符 (串)
wordTable[j].flag = 1;
}
else if (strlen(wordTable[j].id) > 8) {
if (wordTable[j].id[0] >= '0' && wordTable[j].id[0] <= '1') {
wordTable[j].type = 8;//无符号整数越界
}
else {
wordTable[j].type = 10;//标识符长度超长
}
}
else if (wordTable[j].flag == 1) {
wordTable[j].type = 9;//非法字符 (串)
}
else {
wordTable[j].type = 2;//标识符
}
}
}
}
// 语义分析
void SemanticAnalysis() {
procedure();
if (count_semanticError == 0) {
printf("语义正确\n");
for (int o = 0; o < lableIndex; o++) {
for (int p = 0; p < quaternionLine; p++) {
if (strcmp(interCode[p].result, lableTable[o].name) == 0) {
char typ[10];
char tem[3];
strcpy(typ, "$");
if (lableTable[o].value + 1 < 10) {
tem[0] = (char)(lableTable[o].value + 1 + 48);
tem[1] = '\0';
}
else {
tem[0] = (char)((lableTable[o].value + 1) / 10 + 48);
tem[1] = (char)((lableTable[o].value + 1) % 10 + 48);
tem[2] = '\0';
}
strcat(typ, tem);
strcpy(interCode[p].result, typ);
}
}
}
printf("中间代码:\n");
for (int i = 0; i < quaternionLine; i++)
printf("(%d)(%s,%s,%s,%s)\n", i + 1, interCode[i].op, interCode[i].arg1, interCode[i].arg2, interCode[i].result);
printf("符号表:\n");
for (int i = 0; i < symbolIndex; i++) {
if (strcmp(symbolTable[i].type, "procedure") == 0) {
if (i != symbolIndex - 1)
printf("%s %s\n", symbolTable[i].type, symbolTable[i].variable);
else
printf("%s %s", symbolTable[i].type, symbolTable[i].variable);
}
else {
if (i != symbolIndex - 1)
printf("%s %s %d\n", symbolTable[i].type, symbolTable[i].variable, symbolTable[i].value);
else
printf("%s %s %d", symbolTable[i].type, symbolTable[i].variable, symbolTable[i].value);
}
}
}
}
// 语义错误打印
void SemanticErrorPrint() {
printf("(语义错误,行号:%d)\n", wordTable[wordIndex - 1].lineNum);
count_semanticError++;
}
// 语法错误打印
void GrammarErrorPrint(int type) {
if (type == 1) {
if (grammarErrorLine != wordTable[wordIndex - 1].lineNum) {
grammarErrorLine = wordTable[wordIndex - 1].lineNum;
printf("(语法错误,行号:%d)\n", wordTable[wordIndex - 1].lineNum);
count_grammarError++;
}
}
else {
if (grammarErrorLine != wordTable[wordIndex - 1].lineNum) {
grammarErrorLine = wordTable[wordIndex - 1].lineNum;
printf("(语法错误,行号:%d)\n", wordTable[wordIndex - 1].lineNum);
count_grammarError++;
}
}
}
//是否保留字
int IsReservedWord(char* s){
for (int i = 0; i < 20; i++)
if (strcmp(reservedWord[i], s) == 0)
return 1;
return 0;
}
// 阶乘
int Pow(int num, int j) {
for (int a = 1; a < j; a++) {
num = num * num;
}
return num;
}
// 生成中间代码四元式
void GenerateQuaternion(const char* op, const char* arg1, const char* arg2, const char* result, int e) {
strcpy(interCode[e].op, op);
strcpy(interCode[e].arg1, arg1);
strcpy(interCode[e].arg2, arg2);
strcpy(interCode[e].result, result);
}
// 新标签
char* newlabel() {
char temp[3];
if (lableIndex < 10) {
temp[0] = (char)(lableIndex + 48);
temp[1] = '\0';
}
else {
temp[0] = (char)(lableIndex / 10 + 48);
temp[1] = (char)(lableIndex % 10 + 48);
temp[2] = '\0';
}
strcpy(lableTable[lableIndex].name, "L");
strcat(lableTable[lableIndex].name, temp);
int lold = lableIndex;
lableIndex++;
return lableTable[lold].name;
}
// 标签
void label(char s[]) {
for (int j = 0; j < lableIndex; j++) {
if (strcmp(lableTable[j].name, s) == 0) {
lableTable[j].value = quaternionLine;
return;
}
}
}
// 程序
void procedure() {
char Snext[4];
GenerateQuaternion("syss", "_", "_", "_", quaternionLine++);
strcpy(Snext, newlabel());
subroutine(Snext);
if (strcmp(wordTable[wordIndex].id, ".") == 0)
{
label(Snext);
GenerateQuaternion("syse", "_", "_", "_", quaternionLine++);
}
else { GrammarErrorPrint(0); return; }
}
// 子程序
void subroutine(char* Snext) {
char S1next[4];
strcpy(S1next, newlabel());
if (strcmp(wordTable[wordIndex].id, "const") == 0)
{
wordIndex++;
constant(symbolIndex++);
while (strcmp(wordTable[wordIndex].id, ",") == 0)
{
wordIndex++;
constant(symbolIndex++);
}
if (strcmp(wordTable[wordIndex].id, ";") == 0) {
wordIndex++;
char S2next[4];
strcpy(S2next, newlabel());
subroutine(S2next);
label(S2next);
}
else {
GrammarErrorPrint(0);
}
}
else if (strcmp(wordTable[wordIndex].id, "var") == 0) {
wordIndex++;
for (int o = 0; o < symbolIndex; o++) {
if (strcmp(symbolTable[o].variable, wordTable[wordIndex].id) == 0) {
SemanticErrorPrint();
}
}
variable(symbolIndex++);
while (strcmp(wordTable[wordIndex].id, ",") == 0)
{
wordIndex++;
variable(symbolIndex++);
}
if (strcmp(wordTable[wordIndex].id, ";") == 0) {
wordIndex++;
char S2next[4];
strcpy(S2next, newlabel());
subroutine(S2next);
label(S2next);
}
else {
GrammarErrorPrint(0);
}
}
else if (strcmp(wordTable[wordIndex].id, "procedure") == 0) {
wordIndex++;
id();
GenerateQuaternion("procedure", wordTable[wordIndex - 1].id, "_", "_", quaternionLine++);
strcpy(symbolTable[symbolIndex].type, "procedure");
strcpy(symbolTable[symbolIndex].variable, wordTable[wordIndex - 1].id);
symbolIndex++;
if (strcmp(wordTable[wordIndex].id, ";") == 0)
{
wordIndex++;
char S2next[4];
strcpy(S2next, newlabel());
subroutine(S2next);
label(S2next);
if (strcmp(wordTable[wordIndex].id, ";") == 0)
{
wordIndex++;
}
else {
GrammarErrorPrint(1);
}
}
else {
GrammarErrorPrint(0);
}
while (strcmp(wordTable[wordIndex].id, "procedure") == 0)
{
wordIndex++;
id();
GenerateQuaternion("procedure", wordTable[wordIndex - 1].id, "_", "_", quaternionLine++);
strcpy(symbolTable[symbolIndex].type, "procedure");
strcpy(symbolTable[symbolIndex].variable, wordTable[wordIndex - 1].id);
symbolIndex++;
if (strcmp(wordTable[wordIndex].id, ";") == 0)
{
wordIndex++;
char S3next[4];
strcpy(S3next, newlabel());
subroutine(S3next);
label(S3next);
if (strcmp(wordTable[wordIndex].id, ";") == 0) {
wordIndex++;
}
else GrammarErrorPrint(1);
}
else {
GrammarErrorPrint(0);
}
}
}
sentence(S1next);
label(S1next);
}
// 常量
void constant(int a) {
strcpy(symbolTable[a].type, "const");
identifier(a);
GenerateQuaternion(symbolTable[a].type, symbolTable[a].variable, "_", "_", quaternionLine++);
if (strcmp(wordTable[wordIndex].id, "=") == 0)
{
wordIndex++;
number(a);
GenerateQuaternion("=", wordTable[wordIndex - 1].id, "_", wordTable[wordIndex - 3].id, quaternionLine++);
}
else { GrammarErrorPrint(0); }
}
// 变量
void variable(int a) {
strcpy(symbolTable[a].type, "var");
id();
strcpy(symbolTable[a].variable, wordTable[wordIndex - 1].id);
GenerateQuaternion(symbolTable[a].type, symbolTable[a].variable, "_", "_", quaternionLine++);
}
// 语句
void sentence(char* Snext) {
if (strcmp(wordTable[wordIndex].id, "if") == 0) {
wordIndex++;
char Etrue[4];
char Efalse[4];
strcpy(Etrue, newlabel());
strcpy(Efalse, Snext);
condition(Etrue, Efalse);
if (strcmp(wordTable[wordIndex].id, "then") == 0) {
char S1next[4];
label(Etrue);
strcpy(S1next, Snext);
wordIndex++;
sentence(S1next);
}
else { GrammarErrorPrint(0); }
}
else if (strcmp(wordTable[wordIndex].id, "while") == 0) {
wordIndex++;
char Ebegin[4];
char Etrue[4];
char Efalse[4];
strcpy(Ebegin, newlabel());
label(Ebegin);
strcpy(Etrue, newlabel());
strcpy(Efalse, Snext);
condition(Etrue, Efalse);
if (strcmp(wordTable[wordIndex].id, "do") == 0) {
char S1next[4];
strcpy(S1next, newlabel());
label(Etrue);
strcpy(S1next, Ebegin);
wordIndex++;
sentence(S1next);
}
else {
GrammarErrorPrint(1);
}
}
else if (strcmp(wordTable[wordIndex].id, "call") == 0) {
wordIndex++;
GenerateQuaternion("call", wordTable[wordIndex].id, "_", "_", quaternionLine++);
char* c = id();
int flag = 0;
for (int j = 0; j < symbolIndex; j++) {
if (strcmp(symbolTable[j].variable, c) == 0) {
if (strcmp(symbolTable[j].type, "procedure") != 0) {
SemanticErrorPrint();
}
flag = 1;
}
}
if (flag == 0) {
SemanticErrorPrint();
}
}
else if (strcmp(wordTable[wordIndex].id, "read") == 0) {
wordIndex++;
if (strcmp(wordTable[wordIndex].id, "(") == 0) {
wordIndex++;
GenerateQuaternion("read", wordTable[wordIndex].id, "_", "_", quaternionLine++);
char* c = id();
int flag = 0;
for (int j = 0; j <= symbolIndex; j++) {
if (strcmp(symbolTable[j].variable, c) == 0) {
if (strcmp(symbolTable[j].type, "procedure") == 0) {
SemanticErrorPrint();
}
flag = 1;
}
}
if (flag == 0) {
SemanticErrorPrint();
}
while (strcmp(wordTable[wordIndex].id, ",") == 0) {
wordIndex++;
char* ch = id();
int flag1 = 0;
for (int j = 0; j <= symbolIndex; j++) {
if (strcmp(symbolTable[j].variable, ch) == 0) {
if (strcmp(symbolTable[j].type, "procedure") == 0) {
SemanticErrorPrint();
}
flag1 = 1;
}
}
if (flag == 0) {
SemanticErrorPrint();
}
}
if (strcmp(wordTable[wordIndex].id, ")") == 0) {
wordIndex++;
}
else GrammarErrorPrint(1);
}
else GrammarErrorPrint(0);
}
else if (strcmp(wordTable[wordIndex].id, "write") == 0) {
wordIndex++;
if (strcmp(wordTable[wordIndex].id, "(") == 0) {
wordIndex++;
expression();
GenerateQuaternion(wordTable[wordIndex - 2].id, wordTable[wordIndex - 3].id, wordTable[wordIndex - 1].id, "T1", quaternionLine++);
while (strcmp(wordTable[wordIndex].id, ",") == 0) {
wordIndex++;
expression();
}
if (strcmp(wordTable[wordIndex].id, ")") == 0) {
wordIndex++;
GenerateQuaternion("write", "T1", "_", "_", quaternionLine++);
}
else GrammarErrorPrint(0);
}
else {
GrammarErrorPrint(1);
expression();
while (strcmp(wordTable[wordIndex].id, ",") == 0) {
wordIndex++;
expression();
}
if (strcmp(wordTable[wordIndex].id, ")") == 0) {
wordIndex++;
}
else GrammarErrorPrint(0);
}
}
else if (strcmp(wordTable[wordIndex].id, "begin") == 0) {
wordIndex++;
char S1next[4];
strcpy(S1next, newlabel());
sentence(S1next);
label(S1next);
if (strcmp(wordTable[wordIndex].id, ";") == 0) {
wordIndex++;
char S2next[4];
strcpy(S2next, newlabel());
sentence(S2next);
label(S2next);
}
else {
GrammarErrorPrint(0);
}
while (strcmp(wordTable[wordIndex].id, ";") == 0) {
wordIndex++;
char S3next[4];
strcpy(S3next, newlabel());
sentence(S3next);
label(S3next);
}
if (strcmp(wordTable[wordIndex].id, "end") == 0) {
wordIndex++;
}
else { GrammarErrorPrint(0); return; }
}
else {
int tt = 0;
for (tt = 0; tt < strlen(wordTable[wordIndex].id); tt++) word[tt] = wordTable[wordIndex].id[tt];
word[tt] = '\0';
if (!IsReservedWord(word) && word[0] != '.') {
id();
if (strcmp(wordTable[wordIndex].id, ":=") == 0) {
wordIndex++;
expression();
GenerateQuaternion(wordTable[wordIndex - 2].id, wordTable[wordIndex - 3].id, wordTable[wordIndex - 1].id, wordTable[wordIndex - 5].id, quaternionLine++);
GenerateQuaternion("ret", "_", "_", "_", quaternionLine++);
}
}
}
}
// 条件
void condition(char* Etrue, char* Efalse) {
expression();
char op1[5];
strcpy(op1, "j");
char op2[5];
strcpy(op2, "j");
char ch[6][3] = { "=","<",">","<=",">=","#" };
if (strcmp(wordTable[wordIndex].id, "=") == 0 || strcmp(wordTable[wordIndex].id, "#") == 0 || strcmp(wordTable[wordIndex].id, "<") == 0 || strcmp(wordTable[wordIndex].id, "<=") == 0 || strcmp(wordTable[wordIndex].id, ">") == 0 || strcmp(wordTable[wordIndex].id, ">=") == 0) {
int oldi = wordIndex;
int la;
for (int o = 0; o < 6; o++) {
if (strcmp(ch[o], wordTable[wordIndex].id) == 0) {
la = o;
break;
}
}
strcat(op1, ch[la]);
strcat(op2, ch[5 - la]);
wordIndex++;
expression();
GenerateQuaternion(op1, wordTable[oldi - 1].id, wordTable[oldi + 1].id, Etrue, quaternionLine++);
if (strcmp(wordTable[oldi - 2].id, "while") == 0) {
GenerateQuaternion(op2, wordTable[oldi - 1].id, wordTable[oldi + 1].id, Efalse, quaternionLine++);
}
}
else if (strcmp(wordTable[wordIndex].id, "odd") == 0) {
wordIndex++;
expression();
}
else GrammarErrorPrint(0);
}
// 表达式
void expression() {
term();
if (strcmp(wordTable[wordIndex].id, "+") == 0 || strcmp(wordTable[wordIndex].id, "-") == 0){
char ch = wordTable[wordIndex].id[0];
wordIndex++;
term();
while (strcmp(wordTable[wordIndex].id, "+") == 0 || strcmp(wordTable[wordIndex].id, "-") == 0){
char ch = wordTable[wordIndex].id[0];
wordIndex++;
term();
}
}
}
// 项
void term() {
factor();
while (strcmp(wordTable[wordIndex].id, "*") == 0 || strcmp(wordTable[wordIndex].id, "/") == 0) {
wordIndex++;
factor();
}
}
// 因子
void factor() {
if (strcmp(wordTable[wordIndex].id, "(") == 0) {
wordIndex++;
expression();
if (strcmp(wordTable[wordIndex].id, ")") == 0) {
wordIndex++;
}
else GrammarErrorPrint(0);
}
else {
if (wordTable[wordIndex].type == 2) {
int flag = 0;
for (int j = 0; j < symbolIndex; j++) {
if (strcmp(wordTable[wordIndex].id, symbolTable[j].variable) == 0) {
flag = 1;
}
}
if (flag == 0) {
SemanticErrorPrint();
}
}
wordIndex++;
}
}
// 数字
void number(int a) {
int num = 0;
int j = strlen(wordTable[wordIndex].id) - 1;
while (j >= 0) {
num += (int)(wordTable[wordIndex].id[j] - 48) * Pow(10, j);
j--;
}
symbolTable[a].value = num;
wordIndex++;
}
// 标识符
void identifier(int a) {
strcpy(symbolTable[a].variable, wordTable[wordIndex].id);
wordIndex++;
}
// 变量名声明判断
char* id(){
int tt = 0;
for (tt = 0; tt < strlen(wordTable[wordIndex].id); tt++) word[tt] = wordTable[wordIndex].id[tt];
word[tt] = '\0';
if (!IsReservedWord(word) && word[0] != '.'){
wordIndex++;
return wordTable[wordIndex - 1].id;
}
else GrammarErrorPrint(1);
}
int main() {
LexicalAnalysis();
SemanticAnalysis();
return 0;
}