语法分析递归下降分析开工
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>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="LexicalAnalyzer.cpp" />
|
<ClCompile Include="LexicalAnalyzer.cpp" />
|
||||||
|
<ClCompile Include="Parsing_RD.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="LexicalAnalyzer.h" />
|
<ClInclude Include="LexicalAnalyzer.h" />
|
||||||
|
<ClInclude Include="Parsing_RD.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
|
|
@ -18,10 +18,16 @@
|
||||||
<ClCompile Include="LexicalAnalyzer.cpp">
|
<ClCompile Include="LexicalAnalyzer.cpp">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Parsing_RD.cpp">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="LexicalAnalyzer.h">
|
<ClInclude Include="LexicalAnalyzer.h">
|
||||||
<Filter>头文件</Filter>
|
<Filter>头文件</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Parsing_RD.h">
|
||||||
|
<Filter>头文件</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
|
@ -14,6 +14,31 @@ LexicalAnalyzer::LexicalAnalyzer(){}
|
||||||
|
|
||||||
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)
|
bool LexicalAnalyzer::isLetter(char c)
|
||||||
{
|
{
|
||||||
|
@ -298,11 +323,23 @@ int main()
|
||||||
LexicalAnalyzer lexicalanalyzer;
|
LexicalAnalyzer lexicalanalyzer;
|
||||||
lexicalanalyzer.getTokenList();
|
lexicalanalyzer.getTokenList();
|
||||||
int count = lexicalanalyzer.TokenList.size();
|
int count = lexicalanalyzer.TokenList.size();
|
||||||
for (int i = 0; i < count; i++)
|
//for (int i = 0; i < count; i++)
|
||||||
{
|
//{
|
||||||
cout<< "第" << lexicalanalyzer.TokenList[i]->lineShow
|
// cout<< "第" << lexicalanalyzer.TokenList[i]->lineShow
|
||||||
<< "行 <" << ha.at(lexicalanalyzer.TokenList[i]->word.Lex)
|
// << "行 <" << ha.at(lexicalanalyzer.TokenList[i]->word.Lex)
|
||||||
<< "," << lexicalanalyzer.TokenList[i]->word.Sem
|
// << "," << lexicalanalyzer.TokenList[i]->word.Sem
|
||||||
<< ">" << endl;
|
// << ">" << 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
|
UNDERANGE
|
||||||
}LexType;
|
}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; //语义信息
|
string Sem; //语义信息
|
||||||
LexType Lex; //词法信息
|
LexType Lex; //词法信息
|
||||||
|
@ -62,14 +46,7 @@ static struct Word
|
||||||
Lex = lex;
|
Lex = lex;
|
||||||
}
|
}
|
||||||
Word() {}
|
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结构
|
//SNL的Token结构
|
||||||
struct 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