语法分析递归下降分析开工
This commit is contained in:
parent
ae404364a2
commit
ca494463e3
|
@ -0,0 +1,60 @@
|
|||
// Microsoft Visual C++ 生成的资源脚本。
|
||||
//
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 从 TEXTINCLUDE 2 资源生成。
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 中文(简体,中国) 资源
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
LANGUAGE 4, 2
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
#endif // 中文(简体,中国) 资源
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 从 TEXTINCLUDE 3 资源生成。
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // 不是 APSTUDIO_INVOKED
|
|
@ -140,9 +140,11 @@
|
|||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="LexicalAnalyzer.cpp" />
|
||||
<ClCompile Include="Parsing_RD.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="LexicalAnalyzer.h" />
|
||||
<ClInclude Include="Parsing_RD.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
@ -18,10 +18,16 @@
|
|||
<ClCompile Include="LexicalAnalyzer.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Parsing_RD.cpp">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="LexicalAnalyzer.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Parsing_RD.h">
|
||||
<Filter>头文件</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -14,6 +14,31 @@ LexicalAnalyzer::LexicalAnalyzer(){}
|
|||
|
||||
LexicalAnalyzer::~LexicalAnalyzer(){}
|
||||
|
||||
Word keyWords[21] =
|
||||
{
|
||||
{"program",PROGRAM},{"type",TYPE},{"var",VAR},
|
||||
{"procedure",PROCEDURE},{"begin",BEGIN},{"end",END1},{"array",ARRAY},
|
||||
{"of",OF},{"record",RECORD},{"if",IF},{"then",THEN},{"else",ELSE},{"fi",FI},
|
||||
{"while",WHILE},{"do",DO},{"endwh",ENDWH},{"read",READ},{"write",WRITE},
|
||||
{"return",RETURN1},{"integer",INTEGER},{"char",CHAR1}
|
||||
};//保留字
|
||||
|
||||
//类型哈希表
|
||||
unordered_map<int, string> ha =
|
||||
{
|
||||
{0, "ENDFILE1"}, {1, "ERROR1"}, {2, "PROGRAM"}, {3,"PROCEDURE"},
|
||||
{4, "TYPE"}, {5, "VAR"}, {6, "IF"}, {7, "THEN"},
|
||||
{8, "ELSE"}, {9, "FI"}, {10, "WHILE"}, {11, "DO"},
|
||||
{12, "ENDWH"}, {13, "BEGIN"}, {14, "END1"}, {15, "READ"},
|
||||
{16, "WRITE"}, {11, "ARRAY"}, {12, "OF"}, {13, "RECORD"},
|
||||
{20, "RETURN1"}, {21, "INTEGER"}, {22, "CHAR1"}, {23, "ID"},
|
||||
{24, "INTC"}, {25, "CHARC"}, {26, "ASSIGN"}, {27, "EQ"},
|
||||
{28, "LT"}, {29, "PLUS"}, {30, "MINUS"}, {31, "TIMES"},
|
||||
{32, "OVER"}, {33, "LPAREN"}, {34, "RPAREN"}, {35, "DOT"},
|
||||
{36, "COLON"}, {37, "SEMI"}, {38, "COMMA"}, {39, "LMIDPAREN"},
|
||||
{40, "RMIDPAREN"}, {41, "UNDERANGE"}
|
||||
};
|
||||
|
||||
/*=====字符 / 字符串的类型判断=====*/
|
||||
bool LexicalAnalyzer::isLetter(char c)
|
||||
{
|
||||
|
@ -298,11 +323,23 @@ int main()
|
|||
LexicalAnalyzer lexicalanalyzer;
|
||||
lexicalanalyzer.getTokenList();
|
||||
int count = lexicalanalyzer.TokenList.size();
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
cout<< "第" << lexicalanalyzer.TokenList[i]->lineShow
|
||||
<< "行 <" << ha.at(lexicalanalyzer.TokenList[i]->word.Lex)
|
||||
<< "," << lexicalanalyzer.TokenList[i]->word.Sem
|
||||
<< ">" << endl;
|
||||
}
|
||||
//for (int i = 0; i < count; i++)
|
||||
//{
|
||||
// cout<< "第" << lexicalanalyzer.TokenList[i]->lineShow
|
||||
// << "行 <" << ha.at(lexicalanalyzer.TokenList[i]->word.Lex)
|
||||
// << "," << lexicalanalyzer.TokenList[i]->word.Sem
|
||||
// << ">" << endl;
|
||||
//}
|
||||
|
||||
//ofstream file;
|
||||
//file.open("tokenList.txt");
|
||||
//for (int i = 0; i < count; i++)
|
||||
//{
|
||||
// file << lexicalanalyzer.TokenList[i]->lineShow
|
||||
// << ' ' << lexicalanalyzer.TokenList[i]->word.Lex
|
||||
// << ' ' << lexicalanalyzer.TokenList[i]->word.Sem
|
||||
// << '\n';
|
||||
//}
|
||||
|
||||
cout << "运行成功" << endl;
|
||||
}
|
|
@ -35,24 +35,8 @@ typedef enum
|
|||
UNDERANGE
|
||||
}LexType;
|
||||
|
||||
//ÀàÐ͹þÏ£±í
|
||||
unordered_map<int, string> ha =
|
||||
{
|
||||
{0, "ENDFILE1"}, {1, "ERROR1"}, {2, "PROGRAM"}, {3,"PROCEDURE"},
|
||||
{4, "TYPE"}, {5, "VAR"}, {6, "IF"}, {7, "THEN"},
|
||||
{8, "ELSE"}, {9, "FI"}, {10, "WHILE"}, {11, "DO"},
|
||||
{12, "ENDWH"}, {13, "BEGIN"}, {14, "END1"}, {15, "READ"},
|
||||
{16, "WRITE"}, {11, "ARRAY"}, {12, "OF"}, {13, "RECORD"},
|
||||
{20, "RETURN1"}, {21, "INTEGER"}, {22, "CHAR1"}, {23, "ID"},
|
||||
{24, "INTC"}, {25, "CHARC"}, {26, "ASSIGN"}, {27, "EQ"},
|
||||
{28, "LT"}, {29, "PLUS"}, {30, "MINUS"}, {31, "TIMES"},
|
||||
{32, "OVER"}, {33, "LPAREN"}, {34, "RPAREN"}, {35, "DOT"},
|
||||
{36, "COLON"}, {37, "SEMI"}, {38, "COMMA"}, {39, "LMIDPAREN"},
|
||||
{40, "RMIDPAREN"}, {41, "UNDERANGE"}
|
||||
};
|
||||
|
||||
//单词的语义信息
|
||||
static struct Word
|
||||
struct Word
|
||||
{
|
||||
string Sem; //语义信息
|
||||
LexType Lex; //词法信息
|
||||
|
@ -62,14 +46,7 @@ static struct Word
|
|||
Lex = lex;
|
||||
}
|
||||
Word() {}
|
||||
}keyWords[21] =
|
||||
{
|
||||
{"program",PROGRAM},{"type",TYPE},{"var",VAR},
|
||||
{"procedure",PROCEDURE},{"begin",BEGIN},{"end",END1},{"array",ARRAY},
|
||||
{"of",OF},{"record",RECORD},{"if",IF},{"then",THEN},{"else",ELSE},{"fi",FI},
|
||||
{"while",WHILE},{"do",DO},{"endwh",ENDWH},{"read",READ},{"write",WRITE},
|
||||
{"return",RETURN1},{"integer",INTEGER},{"char",CHAR1}
|
||||
};//±£Áô×Ö
|
||||
};
|
||||
|
||||
//SNL的Token结构
|
||||
struct Token
|
||||
|
|
|
@ -0,0 +1,372 @@
|
|||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include<string>
|
||||
#include<unordered_map>
|
||||
#include<algorithm>
|
||||
#include<set>
|
||||
#include<vector>
|
||||
#include<iomanip>
|
||||
#include<sstream>
|
||||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include"Parsing_RD.h"
|
||||
|
||||
FILE* fin;
|
||||
FILE* flisting;
|
||||
int tokenNum; //读到第几个token序列了
|
||||
bool Error;
|
||||
Token token; //正在判断的token序列
|
||||
int line0; //代码行数
|
||||
|
||||
void RecursiveDescentParsing::initial()
|
||||
{
|
||||
Error = false;
|
||||
tokenNum = 0;
|
||||
line0 = 0;
|
||||
fopen_s(&flisting, "parseError.txt", "w");
|
||||
}
|
||||
|
||||
void RecursiveDescentParsing::ReadNextToken()
|
||||
{
|
||||
FILE* fp;
|
||||
fopen_s(&fp, "tokenList.txt", "rb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
printf("tokenList打开失败!\n");
|
||||
Error = true;
|
||||
exit(0);
|
||||
}
|
||||
fseek(fp, tokenNum * (sizeof(Token) + 2 * sizeof(' ') + sizeof('\n')), 0);
|
||||
fscanf_s(fp,"%d%d%s",&token.lineShow, &token.word.Lex, token.word.Sem);
|
||||
char* temp;
|
||||
fread(&temp, sizeof('\n'), 1, fp);
|
||||
tokenNum++;
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
void RecursiveDescentParsing::syntaxError(string errorMessage)
|
||||
{
|
||||
fprintf(flisting, "Syntax error, line %d : %s\n\n", token.lineShow, errorMessage);
|
||||
Error = true;
|
||||
}
|
||||
|
||||
void RecursiveDescentParsing::match(LexType lt)
|
||||
{
|
||||
if (token.word.Lex == lt)
|
||||
{
|
||||
ReadNextToken();
|
||||
line0 = token.lineShow;
|
||||
}
|
||||
else
|
||||
{
|
||||
syntaxError("not match error ");
|
||||
ReadNextToken();
|
||||
}
|
||||
}
|
||||
|
||||
TreeNode* RecursiveDescentParsing::parse(void)
|
||||
{
|
||||
ReadNextToken();
|
||||
|
||||
TreeNode* t = NULL;
|
||||
t = Program();
|
||||
|
||||
//if (token.word.Lex != ENDFILE1)
|
||||
// syntaxError("Code ends before file", token.lineShow);
|
||||
return t;
|
||||
}
|
||||
|
||||
TreeNode* RecursiveDescentParsing::Program(void)
|
||||
{
|
||||
TreeNode* t = ProgramHead();
|
||||
TreeNode* q = DeclarePart();
|
||||
TreeNode* s = ProgramBody();
|
||||
|
||||
//建立根节点
|
||||
TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
|
||||
if (root == NULL)
|
||||
{
|
||||
fprintf(flisting, "内存溢出:第 0 行\n");
|
||||
Error = true;
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 3; i++)
|
||||
root->child[i] = NULL;
|
||||
root->sibling = NULL;
|
||||
root->nodekind = ProK;
|
||||
root->lineno = 0;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
root->name[i] = "\0";
|
||||
root->table[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (root != NULL)
|
||||
{
|
||||
root->lineno = 0;
|
||||
if (t != NULL)
|
||||
root->child[0] = t;
|
||||
else
|
||||
syntaxError("缺少程序头");
|
||||
if (q != NULL) root->child[1] = q;
|
||||
if (s != NULL) root->child[2] = s;
|
||||
else syntaxError("缺少程序头");
|
||||
}
|
||||
match(DOT);
|
||||
|
||||
return root;
|
||||
}
|
||||
|
||||
TreeNode* RecursiveDescentParsing::ProgramHead(void)
|
||||
{
|
||||
TreeNode* t = (TreeNode*)malloc(sizeof(TreeNode));
|
||||
if (t == NULL)
|
||||
{
|
||||
syntaxError("内存溢出");
|
||||
Error = true;
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 3; i++) t->child[i] = NULL;
|
||||
t->sibling = NULL;
|
||||
t->nodekind = PheadK;
|
||||
t->lineno = token.lineShow;
|
||||
t->idnum = 0;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
t->name[i] = "\0";
|
||||
t->table[i] = NULL;
|
||||
}
|
||||
}
|
||||
match(PROGRAM);
|
||||
if ((t != NULL) && (token.word.Lex == ID))
|
||||
{
|
||||
t->lineno = 0;
|
||||
t->name[0] = token.word.Sem;
|
||||
}
|
||||
match(ID);
|
||||
return t;
|
||||
}
|
||||
|
||||
TreeNode* RecursiveDescentParsing::DeclarePart(void)
|
||||
{
|
||||
//newDecANode
|
||||
TreeNode* typeP = (TreeNode*)malloc(sizeof(TreeNode));
|
||||
if (typeP == NULL)
|
||||
{
|
||||
syntaxError("内存溢出");
|
||||
Error = true;
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 3; i++)
|
||||
typeP->child[i] = NULL;
|
||||
typeP->sibling = NULL;
|
||||
typeP->nodekind = TypeK;
|
||||
typeP->lineno = token.lineShow;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
typeP->name[i] = "\0";
|
||||
typeP->table[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TreeNode* pp = typeP;
|
||||
if (typeP != NULL)
|
||||
{
|
||||
typeP->lineno = 0;
|
||||
TreeNode* tp1 = TypeDec();
|
||||
if (tp1 != NULL)
|
||||
typeP->child[0] = tp1;
|
||||
else
|
||||
{
|
||||
free(typeP);
|
||||
typeP = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TreeNode* varP = (TreeNode*)malloc(sizeof(TreeNode));
|
||||
if (varP == NULL)
|
||||
{
|
||||
syntaxError("内存溢出");
|
||||
Error = true;
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 3; i++)
|
||||
varP->child[i] = NULL;
|
||||
varP->sibling = NULL;
|
||||
varP->nodekind = VarK;
|
||||
varP->lineno = token.lineShow;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
varP->name[i] = "\0";
|
||||
varP->table[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (varP != NULL)
|
||||
{
|
||||
varP->lineno = 0;
|
||||
TreeNode* tp2 = VarDec();
|
||||
if (tp2 != NULL)
|
||||
varP->child[0] = tp2;
|
||||
else
|
||||
{
|
||||
free(varP);
|
||||
varP = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
TreeNode* s = ProcDec();
|
||||
|
||||
if (varP == NULL)
|
||||
varP = s;
|
||||
|
||||
if (typeP == NULL)
|
||||
pp = typeP = varP;
|
||||
|
||||
//?typeP = varP, VarP = s
|
||||
if (typeP != varP)
|
||||
{
|
||||
typeP->sibling = varP;
|
||||
typeP = varP;
|
||||
}
|
||||
|
||||
if (varP != s)
|
||||
{
|
||||
varP->sibling = s;
|
||||
varP = s;
|
||||
}
|
||||
|
||||
return pp;
|
||||
}
|
||||
|
||||
//?predict集合
|
||||
TreeNode* RecursiveDescentParsing::TypeDec(void)
|
||||
{
|
||||
TreeNode* t = NULL;
|
||||
if (token.word.Lex == TYPE)
|
||||
t = TypeDeclaration();
|
||||
|
||||
else if (token.word.Lex == VAR || token.word.Lex == PROCEDURE || token.word.Lex == BEGIN ){}
|
||||
|
||||
else
|
||||
{
|
||||
ReadNextToken();
|
||||
syntaxError("意外符号");
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
TreeNode* RecursiveDescentParsing::TypeDecList(void)
|
||||
{
|
||||
TreeNode* t = (TreeNode*)malloc(sizeof(TreeNode));
|
||||
if (t == NULL)
|
||||
syntaxError("内存溢出");
|
||||
else {
|
||||
for (int i = 0; i < 3; i++)
|
||||
t->child[i] = NULL;
|
||||
t->sibling = NULL;
|
||||
t->nodekind = DecK;
|
||||
t->lineno = token.lineShow;
|
||||
t->idnum = 0;
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
t->name[i] = "\0";
|
||||
t->table[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (t != NULL)
|
||||
{
|
||||
t->lineno = line0;
|
||||
TypeId(t);
|
||||
match(EQ);
|
||||
TypeName(t);
|
||||
match(SEMI);
|
||||
TreeNode* p = TypeDecMore();
|
||||
if (p != NULL)
|
||||
t->sibling = p;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
//?predict集合
|
||||
TreeNode* RecursiveDescentParsing::TypeDecMore(void)
|
||||
{
|
||||
TreeNode* t = NULL;
|
||||
if (token.word.Lex == VAR || token.word.Lex == PROCEDURE || token.word.Lex == BEGIN) {}
|
||||
else if (token.word.Lex == ID)
|
||||
t = TypeDecList();
|
||||
else
|
||||
{
|
||||
ReadNextToken();
|
||||
syntaxError("意外符号");
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
void RecursiveDescentParsing::TypeId(TreeNode* t)
|
||||
{
|
||||
if (t != NULL)
|
||||
{
|
||||
int temp = t->idnum;
|
||||
if ((token.word.Lex == ID) && (t != NULL))
|
||||
{
|
||||
t->name[temp] = token.word.Sem;
|
||||
temp++;
|
||||
}
|
||||
t->idnum = temp;
|
||||
match(ID);
|
||||
}
|
||||
}
|
||||
|
||||
//?predict集合
|
||||
void RecursiveDescentParsing::TypeName(TreeNode* t)
|
||||
{
|
||||
if (t != NULL)
|
||||
{
|
||||
if (token.word.Lex == INTEGER || token.word.Lex == CHAR1)
|
||||
BaseType(t);
|
||||
else if (token.word.Lex == ARRAY || token.word.Lex == RECORD)
|
||||
StructureType(t);
|
||||
else if (token.word.Lex == ID)
|
||||
{
|
||||
t->kind.dec = IdK;
|
||||
t->attr.type_name = token.word.Sem;
|
||||
match(ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadNextToken();
|
||||
syntaxError("意外符号");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//?predict集合
|
||||
void RecursiveDescentParsing::BaseType(TreeNode* t)
|
||||
{
|
||||
if (t != NULL)
|
||||
{
|
||||
if (token.word.Lex == INTEGER)
|
||||
{
|
||||
match(INTEGER);
|
||||
t->kind.dec = IntegerK;
|
||||
}
|
||||
else if (token.word.Lex == CHAR1)
|
||||
{
|
||||
match(CHAR1);
|
||||
t->kind.dec = CharK;
|
||||
}
|
||||
else
|
||||
{
|
||||
ReadNextToken();
|
||||
syntaxError("意外符号");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
#pragma once
|
||||
#include <iostream>
|
||||
#include<fstream>
|
||||
#include<string>
|
||||
#include<unordered_map>
|
||||
#include<algorithm>
|
||||
#include<set>
|
||||
#include<vector>
|
||||
#include<iomanip>
|
||||
#include<sstream>
|
||||
#include"LexicalAnalyzer.h"
|
||||
using namespace std;
|
||||
|
||||
/******************************************************
|
||||
****************** 语法分析树 ********************
|
||||
******************************************************/
|
||||
|
||||
/*语法树根节点ProK,程序头结点PheadK,声明类型节点DecK,
|
||||
标志子结点都是类型声明的结点TypeK,标志子结点都是变量声明的结点VarK,
|
||||
函数声明结点FuncDecK,语句序列节点StmLK,语句声明结点StmtK,
|
||||
表达式结点ExpK*/
|
||||
typedef enum { ProK, PheadK, DecK, TypeK, VarK, ProcDecK, StmLK, StmtK, ExpK }
|
||||
NodeKind;
|
||||
|
||||
/*声明类型Deckind 类型的枚举定义:
|
||||
数组类型ArrayK,字符类型CharK,
|
||||
整数类型IntegerK,记录类型RecordK,
|
||||
以类型标识符作为类型的IdK*/
|
||||
typedef enum { ArrayK, CharK, IntegerK, RecordK, IdK } DecKind;
|
||||
|
||||
/* 语句类型StmtKind类型的枚举定义: *
|
||||
* 判断类型IfK,循环类型WhileK *
|
||||
* 赋值类型AssignK,读类型ReadK *
|
||||
* 写类型WriteK,函数调用类型CallK */
|
||||
typedef enum { IfK, WhileK, AssignK, ReadK, WriteK, CallK, ReturnK } StmtKind;
|
||||
|
||||
|
||||
/* 表达式类型ExpKind类型的枚举定义: *
|
||||
* 操作类型OpK,常数类型ConstK,变量类型VarK */
|
||||
typedef enum { OpK, ConstK, VariK } ExpKind;
|
||||
|
||||
|
||||
/* 变量类型VarKind类型的枚举定义: *
|
||||
* 标识符IdV,数组成员ArrayMembV,域成员FieldMembV*/
|
||||
typedef enum { IdV, ArrayMembV, FieldMembV } VarKind;
|
||||
|
||||
|
||||
/* 类型检查ExpType类型的枚举定义: *
|
||||
* 空Void,整数类型Integer,字符类型Char */
|
||||
typedef enum { Void, Integer, Boolean } ExpType;
|
||||
|
||||
/* 参数类型ParamType类型的枚举定义: *
|
||||
* 值参valparamType,变参varparamType */
|
||||
typedef enum { valparamType, varparamType } ParamType;
|
||||
|
||||
/*提前声明符号表结构*/
|
||||
struct symbtable;
|
||||
|
||||
/********** 语法树节点treeNode类型 *********/
|
||||
typedef struct treeNode
|
||||
|
||||
{
|
||||
struct treeNode* child[3]; /* 子节点指针 */
|
||||
struct treeNode* sibling; /* 兄弟节点指针 */
|
||||
int lineno; /* 源代码行号 */
|
||||
NodeKind nodekind; /* 节点类型 */
|
||||
union
|
||||
{
|
||||
DecKind dec;
|
||||
StmtKind stmt;
|
||||
ExpKind exp;
|
||||
} kind; /* 具体类型 */
|
||||
|
||||
int idnum; /* 相同类型的变量个数 */
|
||||
|
||||
string name[10]; /* 标识符的名称 */
|
||||
|
||||
struct symbtable* table[10]; /* 与标志符对应的符号表地址,在语义分析阶段填入*/
|
||||
|
||||
struct
|
||||
{
|
||||
struct
|
||||
{
|
||||
int low; /* 数组下界 */
|
||||
int up; /* 数组上界 */
|
||||
DecKind childtype; /* 数组的子类型 */
|
||||
}ArrayAttr; /* 数组属性 */
|
||||
|
||||
struct
|
||||
{
|
||||
ParamType paramt; /* 过程的参数类型 */
|
||||
}ProcAttr; /* 过程属性 */
|
||||
|
||||
struct
|
||||
{
|
||||
LexType op; /* 表达式的操作符*/
|
||||
int val; /* 表达式的值 */
|
||||
VarKind varkind; /* 变量的类别 */
|
||||
ExpType type; /* 用于类型检查 */
|
||||
}ExpAttr; /* 表达式属性 */
|
||||
|
||||
string type_name; /* 类型名是标识符 */
|
||||
|
||||
} attr; /* 属性 */
|
||||
}TreeNode;
|
||||
|
||||
class RecursiveDescentParsing
|
||||
{
|
||||
public:
|
||||
void initial(); //全局变量初始化
|
||||
void ReadNextToken(); //读文件
|
||||
void syntaxError(string errorMessage); //输出语法错误
|
||||
void match(LexType lt);
|
||||
|
||||
TreeNode* parse(void);
|
||||
TreeNode* Program(void);
|
||||
TreeNode* ProgramHead(void);
|
||||
TreeNode* DeclarePart(void);
|
||||
TreeNode* TypeDec(void);
|
||||
TreeNode* TypeDecList(void);
|
||||
TreeNode* TypeDecMore(void);
|
||||
void TypeId(TreeNode* t);
|
||||
void TypeName(TreeNode* t);
|
||||
void BaseType(TreeNode* t);
|
||||
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
1 2 program
|
||||
1 23 p
|
||||
2 4 type
|
||||
2 23 t
|
||||
2 27 =
|
||||
2 21 integer
|
||||
2 37 ;
|
||||
3 5 var
|
||||
3 23 t
|
||||
3 23 v1
|
||||
3 37 ;
|
||||
4 22 char
|
||||
4 23 v2
|
||||
4 37 ;
|
||||
5 13 begin
|
||||
6 15 read
|
||||
6 33 (
|
||||
6 23 v1
|
||||
6 34 )
|
||||
6 37 ;
|
||||
7 23 v1
|
||||
7 26 :=
|
||||
7 23 v1
|
||||
7 29 +
|
||||
7 24 10
|
||||
7 37 ;
|
||||
8 16 write
|
||||
8 33 (
|
||||
8 23 v1
|
||||
8 34 )
|
||||
9 14 end
|
||||
9 1 .
|
||||
9 0 ÿ
|
Loading…
Reference in New Issue