语法分析递归下降分析开工

This commit is contained in:
不点 小 2022-03-17 13:53:42 +08:00
parent ae404364a2
commit ca494463e3
9 changed files with 645 additions and 32 deletions

View File

@ -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

View File

@ -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">

View File

@ -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>

View File

@ -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;
}

View File

@ -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

372
Parsing_RD.cpp Normal file
View File

@ -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("意外符号");
}
}
}

126
Parsing_RD.h Normal file
View File

@ -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 *
* WriteKCallK */
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
parseError.txt Normal file
View File

33
tokenList.txt Normal file
View File

@ -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 ÿ