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