diff --git a/Course_Design_of_Compiling.rc b/Course_Design_of_Compiling.rc
new file mode 100644
index 0000000..0fded0b
--- /dev/null
+++ b/Course_Design_of_Compiling.rc
@@ -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
diff --git a/Course_Design_of_Compiling.vcxproj b/Course_Design_of_Compiling.vcxproj
index 03bf43c..d8c8837 100644
--- a/Course_Design_of_Compiling.vcxproj
+++ b/Course_Design_of_Compiling.vcxproj
@@ -140,9 +140,11 @@
+
+
diff --git a/Course_Design_of_Compiling.vcxproj.filters b/Course_Design_of_Compiling.vcxproj.filters
index 782bdcb..09b6a24 100644
--- a/Course_Design_of_Compiling.vcxproj.filters
+++ b/Course_Design_of_Compiling.vcxproj.filters
@@ -18,10 +18,16 @@
婧愭枃浠
+
+ 婧愭枃浠
+
澶存枃浠
+
+ 澶存枃浠
+
\ No newline at end of file
diff --git a/LexicalAnalyzer.cpp b/LexicalAnalyzer.cpp
index 8f0a6ed..dd83f12 100644
--- a/LexicalAnalyzer.cpp
+++ b/LexicalAnalyzer.cpp
@@ -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 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;
}
\ No newline at end of file
diff --git a/LexicalAnalyzer.h b/LexicalAnalyzer.h
index d5a256f..6f9fba4 100644
--- a/LexicalAnalyzer.h
+++ b/LexicalAnalyzer.h
@@ -35,24 +35,8 @@ typedef enum
UNDERANGE
}LexType;
-//类型哈希表
-unordered_map 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
diff --git a/Parsing_RD.cpp b/Parsing_RD.cpp
new file mode 100644
index 0000000..deb7bb6
--- /dev/null
+++ b/Parsing_RD.cpp
@@ -0,0 +1,372 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#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("意外符号");
+ }
+ }
+}
+
+
diff --git a/Parsing_RD.h b/Parsing_RD.h
new file mode 100644
index 0000000..dcfc8e1
--- /dev/null
+++ b/Parsing_RD.h
@@ -0,0 +1,126 @@
+#pragma once
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#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);
+
+};
\ No newline at end of file
diff --git a/parseError.txt b/parseError.txt
new file mode 100644
index 0000000..e69de29
diff --git a/tokenList.txt b/tokenList.txt
new file mode 100644
index 0000000..58d0241
--- /dev/null
+++ b/tokenList.txt
@@ -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