├── CompilePrinciple 1 ├── InputReader.class.h ├── func_lib.h ├── getsym.cpp ├── keyword.cpp ├── main.cpp └── operator.cpp ├── CompilePrinciple 2 ├── LexicalAnalyzer.class.h ├── declare.h ├── details.cpp ├── main.cpp ├── program.cpp └── statement.cpp ├── CompilePrinciple 3 ├── LexicalAnalyzer.class.h ├── LexicalAnalyzer.cpp ├── SyntacticAnalyzer.class.h ├── details.cpp ├── func_lib.h ├── getsym.cpp ├── keyword.cpp ├── keywordlist.h ├── main.cpp ├── operator.cpp ├── operatorlist.h ├── program.cpp ├── statement.cpp └── wordlist.h ├── CompilePrinciple 4 ├── LexicalAnalyzer.class.h ├── LexicalAnalyzer.cpp ├── SyntacticAnalyzer.class.h ├── details.cpp ├── func_lib.h ├── getsym.cpp ├── keyword.cpp ├── keywordlist.h ├── main.cpp ├── operator.cpp ├── operatorlist.h ├── program.cpp ├── statement.cpp └── wordlist.h ├── CompilePrinciple 5 ├── LexicalAnalyzer.class.h ├── LexicalAnalyzer.cpp ├── SyntacticAnalyzer.class.cpp ├── SyntacticAnalyzer.class.h ├── details.cpp ├── func_lib.h ├── getsym.cpp ├── keyword.cpp ├── keywordlist.h ├── main.cpp ├── operator.cpp ├── operatorlist.h ├── program.cpp ├── statement.cpp └── wordlist.h ├── CompilePrincipleInterpreter ├── CompilePrincipleInterpreter.class.cpp ├── CompilePrincipleInterpreter.class.h └── main.cpp ├── LexicalAnalyzer.class.h ├── LexicalAnalyzer.cpp ├── SyntacticAnalyzer.class.cpp ├── SyntacticAnalyzer.class.h ├── details.cpp ├── func_lib.h ├── getsym.cpp ├── intermediatecodelist.h ├── keyword.cpp ├── keywordlist.h ├── main.cpp ├── operator.cpp ├── operatorlist.h ├── program.cpp ├── statement.cpp └── wordlist.h /CompilePrinciple 1/InputReader.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __INPUTREADER_CLASS_H 2 | #define __INPUTREADER_CLASS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class InputReader 9 | { 10 | protected: 11 | int curline,curchar,curindex; 12 | public: 13 | InputReader() 14 | { 15 | reset(); 16 | } 17 | virtual char peekchar() const=0; 18 | virtual char getchar()=0; 19 | virtual void reset() 20 | { 21 | this->curline=this->curchar=1; 22 | this->curindex=0; 23 | } 24 | virtual int get_curline() const 25 | { 26 | return this->curline; 27 | } 28 | virtual int get_curchar() const 29 | { 30 | return this->curchar; 31 | } 32 | virtual int get_curindex() const 33 | { 34 | return this->curindex; 35 | } 36 | virtual bool eof() const=0; 37 | }; 38 | 39 | class ConsoleInputReader:public InputReader 40 | { 41 | public: 42 | char peekchar() const 43 | { 44 | if(eof()) return -1; 45 | return std::cin.peek(); 46 | } 47 | char getchar() 48 | { 49 | if(eof()) return -1; 50 | char c=std::cin.get(); 51 | ++this->curindex; 52 | if(c=='\n') 53 | { 54 | ++this->curline; 55 | this->curchar=1; 56 | } 57 | else ++this->curchar; 58 | return c; 59 | } 60 | bool eof() const 61 | { 62 | return std::cin.eof(); 63 | } 64 | }; 65 | 66 | class FileReader:public InputReader 67 | { 68 | private: 69 | std::string buffer; 70 | public: 71 | void open(const std::string& path) 72 | { 73 | std::ifstream file(path.c_str(),std::ios::in); 74 | std::getline(file,this->buffer,(char)-1); 75 | file.close(); 76 | reset(); 77 | } 78 | char peekchar() const 79 | { 80 | if(eof()) return -1; 81 | return this->buffer[this->curindex]; 82 | } 83 | char getchar() 84 | { 85 | char c=peekchar(); 86 | ++this->curindex; 87 | if(c=='\n') 88 | { 89 | ++this->curline; 90 | this->curchar=1; 91 | } 92 | else ++this->curchar; 93 | return c; 94 | } 95 | bool eof() const 96 | { 97 | return this->curindex >= this->buffer.size(); 98 | } 99 | }; 100 | 101 | #endif 102 | 103 | 104 | -------------------------------------------------------------------------------- /CompilePrinciple 1/func_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUNC_LIB_H 2 | #define __FUNC_LIB_H 3 | 4 | #define CHAR_CHARACTER 1 5 | #define CHAR_NUMBER 2 6 | #define CHAR_OTHER 3 7 | #define CHAR_NULL 4 8 | 9 | inline 10 | int judge_char_type(char c) 11 | { 12 | if(c==' '||c=='\t'||c=='\n') return CHAR_NULL; 13 | else if( (c>='A'&&c<='Z') || (c>='a'&&c<='z') ) return CHAR_CHARACTER; 14 | else if( c>='0'&&c<='9' ) return CHAR_NUMBER; 15 | else return CHAR_OTHER; 16 | } 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /CompilePrinciple 1/getsym.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"InputReader.class.h" 4 | #include"func_lib.h" 5 | 6 | std::string getKeyword(std::string); 7 | std::string get_operator_name(const std::string&); 8 | 9 | namespace LexicalAnalyzer 10 | { 11 | int getsym(std::string &word,std::string &word_type,InputReader& inputreader,int &num_line,int& num_char) 12 | { 13 | char c; 14 | int c_type,value=0; 15 | const int WORD_MAX_LENGTH=10; 16 | const int NUM_MAX_LENGTH=14; 17 | word=""; 18 | 19 | do 20 | { 21 | num_line=inputreader.get_curline(); 22 | num_char=inputreader.get_curchar(); 23 | if((c=inputreader.getchar())<=0) return -1; 24 | c_type=judge_char_type(c); 25 | } 26 | while(c_type==CHAR_NULL); 27 | 28 | if(c_type==CHAR_CHARACTER) 29 | { 30 | word+=c; 31 | while(word.size()': 67 | case '<': 68 | if(inputreader.peekchar()=='=') 69 | { 70 | word+=inputreader.getchar(); 71 | } 72 | break; 73 | } 74 | 75 | word_type=get_operator_name(word); 76 | //if(word_type.size()==0) error 77 | } 78 | return value; 79 | } 80 | }; 81 | -------------------------------------------------------------------------------- /CompilePrinciple 1/keyword.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #define KEYWORD_LENGTH 13 5 | 6 | const std::pair KEYWORDS_ARRAY[]={ std::make_pair("if","ifsym"), 7 | std::make_pair("then","thensym"), 8 | std::make_pair("while","whilesym"), 9 | std::make_pair("do","dosym"), 10 | std::make_pair("read","readsym"), 11 | std::make_pair("write","writesym"), 12 | std::make_pair("call","callsym"), 13 | std::make_pair("begin","beginsym"), 14 | std::make_pair("end","endsym"), 15 | std::make_pair("const","constsym"), 16 | std::make_pair("var","varsym"), 17 | std::make_pair("procedure","procsym"), 18 | std::make_pair("odd","oddsym")}; 19 | 20 | const std::map KEYWORDS(KEYWORDS_ARRAY,KEYWORDS_ARRAY+KEYWORD_LENGTH); 21 | 22 | std::string getKeyword(std::string str) 23 | { 24 | for(int i=0;i::const_iterator iter=KEYWORDS.find(str); 26 | if(iter!=KEYWORDS.end()) return iter->second; 27 | else return ""; 28 | } 29 | 30 | -------------------------------------------------------------------------------- /CompilePrinciple 1/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"InputReader.class.h" 5 | 6 | namespace LexicalAnalyzer{int getsym(std::string&,std::string&,InputReader&,int&,int&);}; 7 | 8 | int main(int num_args,char* args[]) 9 | { 10 | std::string word,type; 11 | int value,i,num_char,num_line; 12 | 13 | ConsoleInputReader consoleinputreader; 14 | FileReader filereader; 15 | 16 | if(num_args>1) 17 | { 18 | filereader.open(args[1]); 19 | } 20 | 21 | while(true) 22 | { 23 | if(num_args>1) value=LexicalAnalyzer::getsym(word,type,filereader,num_line,num_char); 24 | else value=LexicalAnalyzer::getsym(word,type,consoleinputreader,num_line,num_char); 25 | if(value<0) break; 26 | std::cout << '(' << type << ','; 27 | if(word.size()>0) std::cout << word; 28 | else std::cout << value; 29 | std::cout << ')' << std::endl; 30 | } 31 | 32 | return 0; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /CompilePrinciple 1/operator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define OPERATOR_LENGTH 16 4 | 5 | const std::pair OPERATORS_ARRAY[]={ std::make_pair(":=","becomes"), 6 | std::make_pair(">=","geq"), 7 | std::make_pair(">","gtr"), 8 | std::make_pair("<=","leq"), 9 | std::make_pair("<","lss"), 10 | std::make_pair("+","plus"), 11 | std::make_pair("-","minus"), 12 | std::make_pair("*","times"), 13 | std::make_pair("/","slash"), 14 | std::make_pair("=","eql"), 15 | std::make_pair("#","neq"), 16 | std::make_pair(",","comma"), 17 | std::make_pair(".","period"), 18 | std::make_pair(";","semicolon"), 19 | std::make_pair("(","lparen"), 20 | std::make_pair(")","rparen")}; 21 | 22 | const std::map OPERATORS(OPERATORS_ARRAY,OPERATORS_ARRAY+OPERATOR_LENGTH); 23 | 24 | std::string get_operator_name(const std::string& str) 25 | { 26 | std::map::const_iterator iter=OPERATORS.find(str); 27 | if(iter!=OPERATORS.end()) return iter->second; 28 | else return ""; 29 | } 30 | 31 | -------------------------------------------------------------------------------- /CompilePrinciple 2/LexicalAnalyzer.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __INPUTREADER_CLASS_H 2 | #define __INPUTREADER_CLASS_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class LexicalAnalyzer 9 | { 10 | private: 11 | int num_line,prev_num_line; 12 | std::string prev_symtype,prev_symword; 13 | std::deque deq_buffer; 14 | public: 15 | bool open(const std::string &path) 16 | { 17 | std::string buffer; 18 | std::ifstream file(path.c_str(),std::ios::in); 19 | if(file.fail()) return false; 20 | this->deq_buffer.clear(); 21 | while(std::getline(file,buffer)) 22 | { 23 | this->deq_buffer.push_back(buffer); 24 | } 25 | this->deq_buffer.push_back(buffer); 26 | file.close(); 27 | this->num_line=this->prev_num_line=1; 28 | return true; 29 | } 30 | 31 | std::string peeksymtype() const 32 | { 33 | std::string row; 34 | int index; 35 | if(eof()) return ""; 36 | row=this->deq_buffer[this->num_line-1]; 37 | index=row.find_first_of('(')+1; 38 | return row.substr(index,row.find_first_of(',')-index); 39 | } 40 | 41 | std::string getsymtype() 42 | { 43 | std::string word=this->prev_symtype=this->peeksymtype(); 44 | this->prev_symword=this->peeksymword(); 45 | this->prev_num_line=this->num_line; 46 | ++this->num_line; 47 | 48 | return word; 49 | } 50 | 51 | std::string peeksymword() const 52 | { 53 | std::string row; 54 | int index; 55 | if(eof()) return ""; 56 | row=this->deq_buffer[this->num_line-1]; 57 | index=row.find_first_of(',')+1; 58 | return row.substr(index,row.find_last_of(')')-index); 59 | } 60 | 61 | std::string getsymword() 62 | { 63 | std::string word=this->prev_symword=this->peeksymword(); 64 | this->prev_symtype=this->peeksymtype(); 65 | this->prev_num_line=this->num_line; 66 | ++this->num_line; 67 | return word; 68 | } 69 | 70 | std::string getprevsymtype() const 71 | { 72 | return this->prev_symtype; 73 | } 74 | 75 | std::string getprevsymword() const 76 | { 77 | return this->prev_symword; 78 | } 79 | 80 | bool eof() const 81 | { 82 | return this->num_line>=this->deq_buffer.size(); 83 | } 84 | 85 | int get_curline() const 86 | { 87 | return this->num_line; 88 | } 89 | 90 | int get_prevline() const 91 | { 92 | return this->prev_num_line; 93 | } 94 | }; 95 | 96 | #endif 97 | 98 | -------------------------------------------------------------------------------- /CompilePrinciple 2/declare.h: -------------------------------------------------------------------------------- 1 | #ifndef __DECLARE_H 2 | #define __DECLARE_H 3 | #include 4 | 5 | class LexicalAnalyzer; 6 | std::string program(LexicalAnalyzer&); 7 | std::string subprogram(LexicalAnalyzer&); 8 | std::string constsym(LexicalAnalyzer&); 9 | std::string varsym(LexicalAnalyzer&); 10 | std::string procsym(LexicalAnalyzer&); 11 | std::string statement(LexicalAnalyzer&); 12 | std::string ident(LexicalAnalyzer&); 13 | std::string callsym(LexicalAnalyzer&); 14 | std::string beginsym(LexicalAnalyzer&); 15 | std::string ifsym(LexicalAnalyzer&); 16 | std::string whilesym(LexicalAnalyzer&); 17 | std::string readwritesym(LexicalAnalyzer&); 18 | std::string condition(LexicalAnalyzer&); 19 | std::string ident(LexicalAnalyzer&); 20 | std::string condition(LexicalAnalyzer&); 21 | std::string expression(LexicalAnalyzer&); 22 | std::string item(LexicalAnalyzer&); 23 | std::string factor(LexicalAnalyzer&); 24 | 25 | #endif 26 | 27 | -------------------------------------------------------------------------------- /CompilePrinciple 2/details.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"declare.h" 4 | 5 | std::string condition(LexicalAnalyzer& lexical_analyzer) 6 | { 7 | std::string word=lexical_analyzer.peeksymtype(); 8 | if(word=="oddsym") return lexical_analyzer.getsymtype().size(),expression(lexical_analyzer); 9 | else 10 | { 11 | if((word=expression(lexical_analyzer))!="") return word; 12 | if(word=lexical_analyzer.getsymtype(), 13 | word!="eql" && word!="neq" && word!="lss" && word!="leq" && word!="gtr" && word!="geq") return "这里应该有一个比较运算符,例如等于 = ,不等于 # ,小于 < ,小于等于 <= ,大于 > ,大于等于 >= "; 14 | return expression(lexical_analyzer); 15 | } 16 | } 17 | 18 | std::string expression(LexicalAnalyzer& lexical_analyzer) 19 | { 20 | std::string word=lexical_analyzer.peeksymtype(); 21 | if(word=="plus" || word=="minus") lexical_analyzer.getsymtype(); 22 | if((word=item(lexical_analyzer))!="") return word; 23 | while(word=lexical_analyzer.peeksymtype(),word=="plus" || word=="minus") 24 | { 25 | if(lexical_analyzer.getsymtype(),(word=item(lexical_analyzer))!="") return word; 26 | } 27 | 28 | return ""; 29 | } 30 | 31 | std::string item(LexicalAnalyzer& lexical_analyzer) 32 | { 33 | std::string word; 34 | if((word=factor(lexical_analyzer))!="") return word; 35 | while(word=lexical_analyzer.peeksymtype(),word=="times" || word=="slash") 36 | { 37 | if(lexical_analyzer.getsymtype(),(word=item(lexical_analyzer))!="") return word; 38 | } 39 | return ""; 40 | } 41 | 42 | std::string factor(LexicalAnalyzer& lexical_analyzer) 43 | { 44 | std::string word=lexical_analyzer.getsymtype(); 45 | if(word!="ident" && word!="number" && word!="lparen") return "这里应该是一个标识符或是一个数字或是一个表达式"; 46 | 47 | if(word=="lparen") 48 | { 49 | if((word=expression(lexical_analyzer))!="") return word; 50 | if(lexical_analyzer.getsymtype()!="rparen") return "这里应该有一个右括号,表达式必须用一对括号扩起来"; 51 | } 52 | return ""; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /CompilePrinciple 2/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"declare.h" 4 | 5 | int main(int num_args,char* args[]) 6 | { 7 | std::string word; 8 | LexicalAnalyzer lexical_analyzer; 9 | 10 | if(num_args<=1) 11 | { 12 | std::cout << "没有输入需要分析的文件" << std::endl; 13 | return 0; 14 | } 15 | 16 | if(!lexical_analyzer.open(args[1])) 17 | { 18 | std::cout << "文件打开时出错" << std::endl; 19 | return 0; 20 | } 21 | 22 | if((word=program(lexical_analyzer))=="") 23 | { 24 | std::cout << "语法正确" << std::endl; 25 | } 26 | else 27 | { 28 | std::cout << "语法错误\n" 29 | << "错误行数: " << lexical_analyzer.get_prevline() << '\n' 30 | << "错误内容: " << lexical_analyzer.getprevsymword() << '\n' 31 | << "错误原因:" << word << std::endl; 32 | } 33 | 34 | return 0; 35 | } 36 | 37 | -------------------------------------------------------------------------------- /CompilePrinciple 2/program.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"declare.h" 4 | 5 | std::string program(LexicalAnalyzer& lexical_analyzer) 6 | { 7 | std::string word; 8 | if((word=subprogram(lexical_analyzer))!="") return word; 9 | if(lexical_analyzer.peeksymtype()!="period") return "必须在程序结尾加一个句号,不要问我为神马,这就是语法!"; 10 | return ""; 11 | } 12 | 13 | std::string subprogram(LexicalAnalyzer& lexical_analyzer) 14 | { 15 | std::string word=lexical_analyzer.peeksymtype(); 16 | if(word=="constsym") 17 | { 18 | if((word=constsym(lexical_analyzer))!="") return word; 19 | word=lexical_analyzer.peeksymtype(); 20 | } 21 | if(word=="varsym") 22 | { 23 | if((word=varsym(lexical_analyzer))!="") return word; 24 | word=lexical_analyzer.peeksymtype(); 25 | } 26 | if(word=="procsym") 27 | { 28 | do 29 | { 30 | if((word=procsym(lexical_analyzer))!="") return word; 31 | }while((word=lexical_analyzer.peeksymtype())=="procsym"); 32 | } 33 | return statement(lexical_analyzer); 34 | } 35 | 36 | std::string constsym(LexicalAnalyzer& lexical_analyzer) 37 | { 38 | std::string word; 39 | if(lexical_analyzer.getsymtype()!="constsym") return "这里应该是一个const语句"; 40 | do 41 | { 42 | if(lexical_analyzer.getsymtype()!="ident") return "这里应该是一个标识符,例如:CONST X=6,Y=4;"; 43 | if(lexical_analyzer.getsymtype()!="eql") return "这里应该是一个等于符号,例如:CONST X=6,Y=4;"; 44 | if(lexical_analyzer.getsymtype()!="number") return "这里应该是一个数字,例如:CONST X=6,Y=4;"; 45 | }while((word=lexical_analyzer.getsymtype())=="comma"); 46 | 47 | return (word=="semicolon"?"":"const语句必须以分号结尾,例如:CONST X=6,Y=4; 请留意末尾的分号"); 48 | } 49 | 50 | std::string varsym(LexicalAnalyzer& lexical_analyzer) 51 | { 52 | std::string word; 53 | if(lexical_analyzer.getsymtype()!="varsym") return "这里应该是一个var语句"; 54 | do 55 | { 56 | if(lexical_analyzer.getsymtype()!="ident") return "这里应该是一个标识符,例如:VAR X,Y,Z;"; 57 | }while((word=lexical_analyzer.getsymtype())=="comma"); 58 | 59 | return (word=="semicolon"?"":"var语句必须以分号结尾,例如:VAR X,Y,Z; 请留意末尾的分号"); 60 | } 61 | 62 | std::string procsym(LexicalAnalyzer& lexical_analyzer) 63 | { 64 | std::string word=""; 65 | if(lexical_analyzer.getsymtype()!="procsym") return "这里应该是一个procedure语句"; 66 | if(lexical_analyzer.getsymtype()!="ident") return "这里应该有一个标识符,作为procedure的名字,例如:PROCEDURE PROC;"; 67 | if(lexical_analyzer.getsymtype()!="semicolon") return "这里应该有一个分号,作为procedure声明和内容的分隔符,例如:PROCEDURE PROC; 请留意末尾的分号"; 68 | if((word=subprogram(lexical_analyzer))!="") return word; 69 | if(lexical_analyzer.getsymtype()!="semicolon") return "这里应该有一个分号,作为一个procedure结束,我知道加一个分号很无聊也不能促进减肥,但是这是语法,是规定,只要你爸不是李刚,就必需遵守这个规定"; 70 | return ""; 71 | } 72 | -------------------------------------------------------------------------------- /CompilePrinciple 2/statement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"declare.h" 4 | 5 | std::string statement(LexicalAnalyzer& lexical_analyzer) 6 | { 7 | std::string word=lexical_analyzer.peeksymtype(); 8 | if(word=="ident") return ident(lexical_analyzer); 9 | if(word=="callsym") return callsym(lexical_analyzer); 10 | if(word=="beginsym") return beginsym(lexical_analyzer); 11 | if(word=="ifsym") return ifsym(lexical_analyzer); 12 | if(word=="whilesym") return whilesym(lexical_analyzer); 13 | if(word=="readsym" || word=="writesym") return readwritesym(lexical_analyzer); 14 | 15 | return ""; 16 | } 17 | 18 | std::string ident(LexicalAnalyzer& lexical_analyzer) 19 | { 20 | if(lexical_analyzer.getsymtype()!="ident") return "这里应该有一个标识符,参考赋值语句的语法:X:=2;"; 21 | if(lexical_analyzer.getsymtype()!="becomes") return "这里应该是一个赋值符号 := ,参考赋值语句的语法:X:=2;"; 22 | return expression(lexical_analyzer); 23 | } 24 | 25 | std::string callsym(LexicalAnalyzer& lexical_analyzer) 26 | { 27 | if(lexical_analyzer.getsymtype()!="callsym") return "这里应该是一个call语句,call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 28 | if(lexical_analyzer.getsymtype()!="ident") return "这个应该是一个标识符,否则我怎么知道你要call谁?call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 29 | return ""; 30 | } 31 | 32 | std::string beginsym(LexicalAnalyzer& lexical_analyzer) 33 | { 34 | std::string word; 35 | if(lexical_analyzer.getsymtype()!="beginsym") return "这里应该有一个begin语句的吧"; 36 | if((word=statement(lexical_analyzer))!="") return word; 37 | while(lexical_analyzer.peeksymtype()!="endsym") 38 | { 39 | if(lexical_analyzer.getsymtype()!="semicolon") return "这里必须有一个分号的啊,如果BEGIN..END语句中有多于一句语句的话,每句语句都必须用分号分隔"; 40 | if((word=statement(lexical_analyzer))!="") return word; 41 | } 42 | lexical_analyzer.getsymtype(); 43 | return ""; 44 | } 45 | 46 | std::string ifsym(LexicalAnalyzer& lexical_analyzer) 47 | { 48 | std::string word; 49 | if(lexical_analyzer.getsymtype()!="ifsym") return "这里应该是一个if语句"; 50 | if((word=condition(lexical_analyzer))!="") return word; 51 | if(lexical_analyzer.getsymtype()!="thensym") return "喂喂..if语句没有跟then,你这个if语句是干啥的?if语句参考语法:IF X=0 THEN X:=1;"; 52 | return statement(lexical_analyzer); 53 | } 54 | 55 | std::string whilesym(LexicalAnalyzer& lexical_analyzer) 56 | { 57 | std::string word; 58 | if(lexical_analyzer.getsymtype()!="whilesym") return "这里应该是一个while语句"; 59 | if((word=condition(lexical_analyzer))!="") return word; 60 | if(lexical_analyzer.getsymtype()!="dosym") return "这里应该有一个do的,没有do,单单一个while有神马意义呢?"; 61 | return statement(lexical_analyzer); 62 | } 63 | 64 | std::string readwritesym(LexicalAnalyzer& lexical_analyzer) 65 | { 66 | std::string word=lexical_analyzer.getsymtype(); 67 | if(word!="readsym" && word!="writesym") return "这里应该是一个函数"; 68 | if(lexical_analyzer.getsymtype()!="lparen") return "这是函数诶!他的语法应该是 READ(X); 或者 WRITE(Y); 吧,你貌似漏了左括号"; 69 | do{ 70 | if(lexical_analyzer.getsymtype()!="ident") return "函数里面要有标识符的啊,他的语法应该是 READ(X); 或是 WRITE(A,B,C);"; 71 | }while((word=lexical_analyzer.getsymtype())=="comma"); 72 | return (word=="rparen"?"":"函数参数要用右括号扩起来的啊,你加右括号了吗"); 73 | } 74 | 75 | -------------------------------------------------------------------------------- /CompilePrinciple 3/LexicalAnalyzer.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __LEXICALANALYZER_CLASS_H 2 | #define __LEXICALANALYZER_CLASS_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class LexicalAnalyzer 9 | { 10 | public: 11 | class InputReader 12 | { 13 | protected: 14 | int curline,curchar,curindex,prevline,prevchar; 15 | public: 16 | InputReader():curline(1),curchar(0),curindex(0) 17 | { 18 | } 19 | virtual char peekchar() const=0; 20 | virtual char getchar()=0; 21 | virtual int get_curline() const 22 | { 23 | return this->curline; 24 | } 25 | virtual int get_curchar() const 26 | { 27 | return this->curchar; 28 | } 29 | virtual int get_prevline() const 30 | { 31 | return this->prevline; 32 | } 33 | virtual int get_prevchar() const 34 | { 35 | return this->prevchar; 36 | } 37 | virtual bool eof() const=0; 38 | }; 39 | 40 | class ConsoleInputReader:public InputReader 41 | { 42 | public: 43 | char peekchar() const 44 | { 45 | if(eof()) return -1; 46 | return std::cin.peek(); 47 | } 48 | char getchar() 49 | { 50 | if(eof()) return -1; 51 | char c=std::cin.get(); 52 | this->prevline=this->curline; 53 | this->prevchar=this->curchar; 54 | ++this->curindex; 55 | if(c=='\n') 56 | { 57 | ++this->curline; 58 | this->curchar=0; 59 | } 60 | else ++this->curchar; 61 | return c; 62 | } 63 | bool eof() const 64 | { 65 | return std::cin.eof(); 66 | } 67 | }; 68 | 69 | class FileReader:public InputReader 70 | { 71 | private: 72 | std::string buffer; 73 | public: 74 | bool open(const std::string& path) 75 | { 76 | std::ifstream file(path.c_str(),std::ios::in); 77 | if(file.fail()) return false; 78 | std::getline(file,this->buffer,(char)-1); 79 | file.close(); 80 | curline=1; 81 | curchar=curindex=0; 82 | return true; 83 | } 84 | char peekchar() const 85 | { 86 | if(eof()) return -1; 87 | return this->buffer[this->curindex]; 88 | } 89 | char getchar() 90 | { 91 | char c=peekchar(); 92 | this->prevline=this->curline; 93 | this->prevchar=this->curchar; 94 | ++this->curindex; 95 | if(c=='\n') 96 | { 97 | ++this->curline; 98 | this->curchar=0; 99 | } 100 | else ++this->curchar; 101 | return c; 102 | } 103 | bool eof() const 104 | { 105 | return this->curindex >= this->buffer.size(); 106 | } 107 | }; 108 | private: 109 | ConsoleInputReader consoleinputreader; 110 | FileReader filereader; 111 | InputReader *inputreader; 112 | std::deque symtypes; 113 | std::deque symwords; 114 | std::deque symnumlines; 115 | std::deque symnumchars; 116 | int curdequeindex; 117 | bool resetmode; 118 | public: 119 | bool open(const std::string &path=""); 120 | void next(); 121 | std::string peeksymtype() const; 122 | std::string getsymtype(); 123 | std::string peeksymword() const; 124 | std::string getsymword(); 125 | std::string getprevsymtype() const; 126 | std::string getprevsymword() const; 127 | bool eof() const; 128 | int get_curline() const; 129 | int get_curchar() const; 130 | int get_prevline() const; 131 | int get_prevchar() const; 132 | void reset(); 133 | private: 134 | std::string getKeyword(std::string) const; 135 | std::string get_operator_name(const std::string&) const; 136 | bool getsym(std::string&,std::string&); 137 | }; 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /CompilePrinciple 3/LexicalAnalyzer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | 6 | bool LexicalAnalyzer::open(const std::string &path) 7 | { 8 | std::string word,type; 9 | this->symwords.clear(); 10 | this->symtypes.clear(); 11 | this->symnumchars.clear(); 12 | this->symnumlines.clear(); 13 | 14 | if(path.size()>0)//文件操作 15 | { 16 | this->inputreader=&this->filereader; 17 | if(!this->filereader.open(path)) return false; 18 | } 19 | else//控制台输入操作 20 | { 21 | this->inputreader=&this->consoleinputreader; 22 | } 23 | 24 | if(!this->getsym(word,type)) return false; 25 | this->symwords.push_back(word); 26 | this->symtypes.push_back(type); 27 | this->curdequeindex=0; 28 | this->resetmode=0; 29 | return true; 30 | } 31 | 32 | void LexicalAnalyzer::next() 33 | { 34 | std::string type,word; 35 | if(!this->resetmode) 36 | { 37 | this->getsym(word,type); 38 | this->symwords.push_back(word); 39 | this->symtypes.push_back(type); 40 | } 41 | ++this->curdequeindex; 42 | } 43 | 44 | std::string LexicalAnalyzer::peeksymtype() const 45 | { 46 | return this->symtypes[this->curdequeindex]; 47 | } 48 | 49 | std::string LexicalAnalyzer::getsymtype() 50 | { 51 | this->next(); 52 | return this->getprevsymtype(); 53 | } 54 | 55 | std::string LexicalAnalyzer::peeksymword() const 56 | { 57 | return this->symwords[this->curdequeindex]; 58 | } 59 | 60 | std::string LexicalAnalyzer::getsymword() 61 | { 62 | this->next(); 63 | return this->getprevsymword(); 64 | } 65 | 66 | std::string LexicalAnalyzer::getprevsymtype() const 67 | { 68 | return this->symtypes[this->curdequeindex-1]; 69 | } 70 | 71 | std::string LexicalAnalyzer::getprevsymword() const 72 | { 73 | return this->symwords[this->curdequeindex-1]; 74 | } 75 | 76 | bool LexicalAnalyzer::eof() const 77 | { 78 | if(!this->resetmode) return this->inputreader->eof(); 79 | else return this->curdequeindex==this->symtypes.size(); 80 | } 81 | 82 | int LexicalAnalyzer::get_curline() const 83 | { 84 | return this->symnumlines[this->curdequeindex]; 85 | } 86 | 87 | int LexicalAnalyzer::get_curchar() const 88 | { 89 | return this->symnumchars[this->curdequeindex]; 90 | } 91 | 92 | int LexicalAnalyzer::get_prevline() const 93 | { 94 | return this->symnumlines[this->curdequeindex-1]; 95 | } 96 | 97 | int LexicalAnalyzer::get_prevchar() const 98 | { 99 | return this->symnumchars[this->curdequeindex-1]; 100 | } 101 | 102 | void LexicalAnalyzer::reset() 103 | { 104 | this->resetmode=1; 105 | this->curdequeindex=0; 106 | } 107 | -------------------------------------------------------------------------------- /CompilePrinciple 3/SyntacticAnalyzer.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYNTACTICANALYZER_CLASS_H 2 | #define __SYNTACTICANALYZER_CLASS_H 3 | #include"LexicalAnalyzer.class.h" 4 | 5 | class SyntacticAnalyzer 6 | { 7 | public: 8 | static std::string analyze(LexicalAnalyzer&); 9 | private: 10 | static std::string subprogram(LexicalAnalyzer&); 11 | static std::string constsym(LexicalAnalyzer&); 12 | static std::string varsym(LexicalAnalyzer&); 13 | static std::string procsym(LexicalAnalyzer&); 14 | static std::string statement(LexicalAnalyzer&); 15 | static std::string callsym(LexicalAnalyzer&); 16 | static std::string beginsym(LexicalAnalyzer&); 17 | static std::string ifsym(LexicalAnalyzer&); 18 | static std::string whilesym(LexicalAnalyzer&); 19 | static std::string readwritesym(LexicalAnalyzer&); 20 | static std::string ident(LexicalAnalyzer&); 21 | static std::string condition(LexicalAnalyzer&); 22 | static std::string expression(LexicalAnalyzer&); 23 | static std::string item(LexicalAnalyzer&); 24 | static std::string factor(LexicalAnalyzer&); 25 | }; 26 | 27 | #endif 28 | 29 | -------------------------------------------------------------------------------- /CompilePrinciple 3/details.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"operatorlist.h" 5 | #include"keywordlist.h" 6 | #include"wordlist.h" 7 | 8 | std::string SyntacticAnalyzer::condition(LexicalAnalyzer& lexical_analyzer) 9 | { 10 | std::string word=lexical_analyzer.peeksymtype(); 11 | if(word==ODDSYM) return lexical_analyzer.getsymtype().size(),expression(lexical_analyzer); 12 | else 13 | { 14 | if((word=expression(lexical_analyzer))!="") return word; 15 | if(word=lexical_analyzer.getsymtype(), 16 | word!=EQL && word!=NEQ && word!=LSS && word!=LEQ && word!=GTR && word!=GEQ) return "这里应该有一个比较运算符,例如等于 = ,不等于 # ,小于 < ,小于等于 <= ,大于 > ,大于等于 >= "; 17 | return expression(lexical_analyzer); 18 | } 19 | } 20 | 21 | std::string SyntacticAnalyzer::expression(LexicalAnalyzer& lexical_analyzer) 22 | { 23 | std::string word=lexical_analyzer.peeksymtype(); 24 | if(word==PLUS || word==MINUS) lexical_analyzer.getsymtype(); 25 | if((word=item(lexical_analyzer))!="") return word; 26 | while(word=lexical_analyzer.peeksymtype(),word==PLUS || word==MINUS) 27 | { 28 | if(lexical_analyzer.getsymtype(),(word=item(lexical_analyzer))!="") return word; 29 | } 30 | 31 | return ""; 32 | } 33 | 34 | std::string SyntacticAnalyzer::item(LexicalAnalyzer& lexical_analyzer) 35 | { 36 | std::string word; 37 | if((word=factor(lexical_analyzer))!="") return word; 38 | while(word=lexical_analyzer.peeksymtype(),word==TIMES || word==SLASH) 39 | { 40 | if(lexical_analyzer.getsymtype(),(word=item(lexical_analyzer))!="") return word; 41 | } 42 | return ""; 43 | } 44 | 45 | std::string SyntacticAnalyzer::factor(LexicalAnalyzer& lexical_analyzer) 46 | { 47 | std::string word=lexical_analyzer.getsymtype(); 48 | if(word!=IDENT && word!=NUMBER && word!=LPAREN) return "这里应该是一个标识符或是一个数字或是一个表达式"; 49 | 50 | if(word==LPAREN) 51 | { 52 | if((word=expression(lexical_analyzer))!="") return word; 53 | if(lexical_analyzer.getsymtype()!=RPAREN) return "这里应该有一个右括号,表达式必须用一对括号扩起来"; 54 | } 55 | return ""; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /CompilePrinciple 3/func_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUNC_LIB_H 2 | #define __FUNC_LIB_H 3 | 4 | #define CHAR_CHARACTER 1 5 | #define CHAR_NUMBER 2 6 | #define CHAR_OTHER 3 7 | #define CHAR_NULL 4 8 | 9 | inline 10 | int judge_char_type(char c) 11 | { 12 | if(c==' '||c=='\t'||c=='\n') return CHAR_NULL; 13 | else if( (c>='A'&&c<='Z') || (c>='a'&&c<='z') ) return CHAR_CHARACTER; 14 | else if( c>='0'&&c<='9' ) return CHAR_NUMBER; 15 | else return CHAR_OTHER; 16 | } 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /CompilePrinciple 3/getsym.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"func_lib.h" 4 | #include"LexicalAnalyzer.class.h" 5 | #include"wordlist.h" 6 | 7 | bool LexicalAnalyzer::getsym(std::string &word,std::string &word_type) 8 | { 9 | char c; 10 | int c_type; 11 | const int WORD_MAX_LENGTH=10; 12 | const int NUM_MAX_LENGTH=14; 13 | word=word_type=""; 14 | 15 | do 16 | { 17 | if((c=this->inputreader->getchar())<=0) return false; 18 | c_type=judge_char_type(c); 19 | } 20 | while(c_type==CHAR_NULL); 21 | 22 | this->symnumchars.push_back(this->inputreader->get_curchar()); 23 | this->symnumlines.push_back(this->inputreader->get_curline()); 24 | 25 | if(c_type==CHAR_CHARACTER) 26 | { 27 | word+=c; 28 | while(word.size()inputreader->peekchar(); 31 | c_type=judge_char_type(c); 32 | if(c_type!=CHAR_CHARACTER && c_type!=CHAR_NUMBER) break; 33 | c=this->inputreader->getchar(); 34 | word+=c; 35 | } 36 | 37 | word_type=getKeyword(word); 38 | if(word_type.size()==0) 39 | { 40 | word_type=IDENT; 41 | } 42 | } 43 | else if(c_type==CHAR_NUMBER) 44 | { 45 | word+=c; 46 | while(word.size()inputreader->peekchar(); 49 | c_type=judge_char_type(c); 50 | if(c_type!=CHAR_NUMBER) break; 51 | c=this->inputreader->getchar(); 52 | word+=c; 53 | } 54 | word_type=NUMBER; 55 | } 56 | else/*if(c_type==CHAR_OTHER)*/ 57 | { 58 | word=c; 59 | switch(c) 60 | { 61 | case ':': 62 | case '>': 63 | case '<': 64 | if(this->inputreader->peekchar()=='=') 65 | { 66 | word+=this->inputreader->getchar(); 67 | } 68 | break; 69 | } 70 | 71 | word_type=get_operator_name(word); 72 | //if(word_type.size()==0) error 73 | } 74 | return true; 75 | } 76 | -------------------------------------------------------------------------------- /CompilePrinciple 3/keyword.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | #include"keywordlist.h" 6 | #define KEYWORD_LENGTH 13 7 | 8 | std::string LexicalAnalyzer::getKeyword(std::string str) const 9 | { 10 | static const std::pair KEYWORDS_ARRAY[]={ std::make_pair("if",IFSYM), 11 | std::make_pair("then",THENSYM), 12 | std::make_pair("while",WHILESYM), 13 | std::make_pair("do",DOSYM), 14 | std::make_pair("read",READSYM), 15 | std::make_pair("write",WRITESYM), 16 | std::make_pair("call",CALLSYM), 17 | std::make_pair("begin",BEGINSYM), 18 | std::make_pair("end",ENDSYM), 19 | std::make_pair("const",CONSTSYM), 20 | std::make_pair("var",VARSYM), 21 | std::make_pair("procedure",PROCSYM), 22 | std::make_pair("odd",ODDSYM)}; 23 | 24 | static const std::map KEYWORDS(KEYWORDS_ARRAY,KEYWORDS_ARRAY+KEYWORD_LENGTH); 25 | 26 | for(int i=0;i::const_iterator iter=KEYWORDS.find(str); 28 | if(iter!=KEYWORDS.end()) return iter->second; 29 | else return ""; 30 | } 31 | -------------------------------------------------------------------------------- /CompilePrinciple 3/keywordlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYWORD_H 2 | #define __KEYWORD_H 3 | 4 | #define IFSYM "ifsym" 5 | #define THENSYM "thensym" 6 | #define WHILESYM "whilesym" 7 | #define DOSYM "dosym" 8 | #define READSYM "readsym" 9 | #define WRITESYM "writesym" 10 | #define CALLSYM "callsym" 11 | #define BEGINSYM "beginsym" 12 | #define ENDSYM "endsym" 13 | #define CONSTSYM "constsym" 14 | #define VARSYM "varsym" 15 | #define PROCSYM "procsym" 16 | #define ODDSYM "oddsym" 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /CompilePrinciple 3/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | 5 | int main(int num_args,char* args[]) 6 | { 7 | std::string word; 8 | LexicalAnalyzer lexical_analyzer; 9 | 10 | if(num_args<=1) 11 | { 12 | lexical_analyzer.open(); 13 | } 14 | 15 | else if(!lexical_analyzer.open(args[1])) 16 | { 17 | std::cout << "文件打开时出错" << std::endl; 18 | return 0; 19 | } 20 | 21 | if((word=SyntacticAnalyzer::analyze(lexical_analyzer))=="") 22 | { 23 | std::cout << "语法正确" << std::endl; 24 | } 25 | else 26 | { 27 | std::cout << "语法错误\n" 28 | << "错误行数: " << lexical_analyzer.get_prevline() << '\n' 29 | << "错误列数: " << lexical_analyzer.get_prevchar() << '\n' 30 | << "错误内容: " << lexical_analyzer.getprevsymword() << '\n' 31 | << "错误原因:" << word << std::endl; 32 | } 33 | 34 | lexical_analyzer.reset(); 35 | while(!lexical_analyzer.eof()) 36 | { 37 | std::cout << lexical_analyzer.peeksymtype() << " , "; 38 | std::cout << lexical_analyzer.peeksymword() << " , "; 39 | std::cout << lexical_analyzer.get_curline() << " , "; 40 | std::cout << lexical_analyzer.get_curchar() << std::endl; 41 | lexical_analyzer.next(); 42 | } 43 | return 0; 44 | } 45 | 46 | -------------------------------------------------------------------------------- /CompilePrinciple 3/operator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"LexicalAnalyzer.class.h" 4 | #include"operatorlist.h" 5 | #define OPERATOR_LENGTH 16 6 | 7 | std::string LexicalAnalyzer::get_operator_name(const std::string& str) const 8 | { 9 | static const std::pair OPERATORS_ARRAY[]={ std::make_pair(":=",BECOMES), 10 | std::make_pair(">=",GEQ), 11 | std::make_pair(">",GTR), 12 | std::make_pair("<=",LEQ), 13 | std::make_pair("<",LSS), 14 | std::make_pair("+",PLUS), 15 | std::make_pair("-",MINUS), 16 | std::make_pair("*",TIMES), 17 | std::make_pair("/",SLASH), 18 | std::make_pair("=",EQL), 19 | std::make_pair("#",NEQ), 20 | std::make_pair(",",COMMA), 21 | std::make_pair(".",PERIOD), 22 | std::make_pair(";",SEMICOLON), 23 | std::make_pair("(",LPAREN), 24 | std::make_pair(")",RPAREN)}; 25 | 26 | static const std::map OPERATORS(OPERATORS_ARRAY,OPERATORS_ARRAY+OPERATOR_LENGTH); 27 | 28 | std::map::const_iterator iter=OPERATORS.find(str); 29 | if(iter!=OPERATORS.end()) return iter->second; 30 | else return ""; 31 | } 32 | -------------------------------------------------------------------------------- /CompilePrinciple 3/operatorlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __OPERATORLIST_H 2 | #define __OPERATORLIST_H 3 | 4 | #define BECOMES "becomes" 5 | #define GEQ "geq" 6 | #define GTR "gtr" 7 | #define LEQ "leq" 8 | #define LSS "lss" 9 | #define PLUS "plus" 10 | #define MINUS "minus" 11 | #define TIMES "times" 12 | #define SLASH "slash" 13 | #define EQL "eql" 14 | #define NEQ "neq" 15 | #define COMMA "comma" 16 | #define PERIOD "period" 17 | #define SEMICOLON "semicolon" 18 | #define LPAREN "lparen" 19 | #define RPAREN "rparen" 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /CompilePrinciple 3/program.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"keywordlist.h" 5 | #include"operatorlist.h" 6 | #include"wordlist.h" 7 | 8 | std::string SyntacticAnalyzer::analyze(LexicalAnalyzer& lexical_analyzer) 9 | { 10 | std::string word; 11 | if((word=subprogram(lexical_analyzer))!="") return word; 12 | if(lexical_analyzer.peeksymtype()!=PERIOD) 13 | { 14 | if(lexical_analyzer.peeksymtype()!="") return "程序有错,这个程序到这里看上去应该已经结束了,但其实不是。是不是少了运算符或漏了左括号?"; 15 | else return "必须在程序结尾加一个句号,不要问我为神马,这就是语法!"; 16 | } 17 | return ""; 18 | } 19 | 20 | std::string SyntacticAnalyzer::subprogram(LexicalAnalyzer& lexical_analyzer) 21 | { 22 | std::string word=lexical_analyzer.peeksymtype(); 23 | if(word==CONSTSYM) 24 | { 25 | if((word=constsym(lexical_analyzer))!="") return word; 26 | word=lexical_analyzer.peeksymtype(); 27 | } 28 | if(word==VARSYM) 29 | { 30 | if((word=varsym(lexical_analyzer))!="") return word; 31 | word=lexical_analyzer.peeksymtype(); 32 | } 33 | if(word==PROCSYM) 34 | { 35 | do 36 | { 37 | if((word=procsym(lexical_analyzer))!="") return word; 38 | }while((word=lexical_analyzer.peeksymtype())==PROCSYM); 39 | } 40 | return statement(lexical_analyzer); 41 | } 42 | 43 | std::string SyntacticAnalyzer::constsym(LexicalAnalyzer& lexical_analyzer) 44 | { 45 | std::string word; 46 | if(lexical_analyzer.getsymtype()!=CONSTSYM) return "这里应该是一个const语句"; 47 | do 48 | { 49 | if(lexical_analyzer.getsymtype()!=IDENT) return "这里应该是一个标识符,例如:CONST X=6,Y=4;"; 50 | if(lexical_analyzer.getsymtype()!=EQL) return "这里应该是一个等于符号,例如:CONST X=6,Y=4;"; 51 | if(lexical_analyzer.getsymtype()!=NUMBER) return "这里应该是一个数字,例如:CONST X=6,Y=4;"; 52 | }while((word=lexical_analyzer.getsymtype())==COMMA); 53 | 54 | return (word==SEMICOLON?"":"const语句必须以分号结尾,例如:CONST X=6,Y=4; 请留意末尾的分号"); 55 | } 56 | 57 | std::string SyntacticAnalyzer::varsym(LexicalAnalyzer& lexical_analyzer) 58 | { 59 | std::string word; 60 | if(lexical_analyzer.getsymtype()!=VARSYM) return "这里应该是一个var语句"; 61 | do 62 | { 63 | if(lexical_analyzer.getsymtype()!=IDENT) return "这里应该是一个标识符,例如:VAR X,Y,Z;"; 64 | }while((word=lexical_analyzer.getsymtype())==COMMA); 65 | 66 | return (word==SEMICOLON?"":"var语句必须以分号结尾,例如:VAR X,Y,Z; 请留意末尾的分号"); 67 | } 68 | 69 | std::string SyntacticAnalyzer::procsym(LexicalAnalyzer& lexical_analyzer) 70 | { 71 | std::string word=""; 72 | if(lexical_analyzer.getsymtype()!=PROCSYM) return "这里应该是一个procedure语句"; 73 | if(lexical_analyzer.getsymtype()!=IDENT) return "这里应该有一个标识符,作为procedure的名字,例如:PROCEDURE PROC;"; 74 | if(lexical_analyzer.getsymtype()!=SEMICOLON) return "这里应该有一个分号,作为procedure声明和内容的分隔符,例如:PROCEDURE PROC; 请留意末尾的分号"; 75 | if((word=subprogram(lexical_analyzer))!="") return word; 76 | if(lexical_analyzer.getsymtype()!=SEMICOLON) return "这里应该有一个分号,作为一个procedure结束,我知道加一个分号很无聊也不能促进减肥,但是这是语法,是规定,只要你爸不是李刚,就必需遵守这个规定"; 77 | return ""; 78 | } 79 | -------------------------------------------------------------------------------- /CompilePrinciple 3/statement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"keywordlist.h" 5 | #include"operatorlist.h" 6 | #include"wordlist.h" 7 | 8 | std::string SyntacticAnalyzer::statement(LexicalAnalyzer& lexical_analyzer) 9 | { 10 | std::string word=lexical_analyzer.peeksymtype(); 11 | if(word==IDENT) return ident(lexical_analyzer); 12 | if(word==CALLSYM) return callsym(lexical_analyzer); 13 | if(word==BEGINSYM) return beginsym(lexical_analyzer); 14 | if(word==IFSYM) return ifsym(lexical_analyzer); 15 | if(word==WHILESYM) return whilesym(lexical_analyzer); 16 | if(word==READSYM || word==WRITESYM) return readwritesym(lexical_analyzer); 17 | 18 | return ""; 19 | } 20 | 21 | std::string SyntacticAnalyzer::ident(LexicalAnalyzer& lexical_analyzer) 22 | { 23 | if(lexical_analyzer.getsymtype()!=IDENT) return "这里应该有一个标识符,参考赋值语句的语法:X:=2;"; 24 | if(lexical_analyzer.getsymtype()!=BECOMES) return "这里应该是一个赋值符号 := ,参考赋值语句的语法:X:=2;"; 25 | return expression(lexical_analyzer); 26 | } 27 | 28 | std::string SyntacticAnalyzer::callsym(LexicalAnalyzer& lexical_analyzer) 29 | { 30 | if(lexical_analyzer.getsymtype()!=CALLSYM) return "这里应该是一个call语句,call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 31 | if(lexical_analyzer.getsymtype()!=IDENT) return "这个应该是一个标识符,否则我怎么知道你要call谁?call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 32 | return ""; 33 | } 34 | 35 | std::string SyntacticAnalyzer::beginsym(LexicalAnalyzer& lexical_analyzer) 36 | { 37 | std::string word; 38 | if(lexical_analyzer.getsymtype()!=BEGINSYM) return "这里应该有一个begin语句的吧"; 39 | if((word=statement(lexical_analyzer))!="") return word; 40 | while(lexical_analyzer.peeksymtype()!=ENDSYM) 41 | { 42 | if(lexical_analyzer.getsymtype()!=SEMICOLON) return "这里必须有一个分号的啊,如果BEGIN..END语句中有多于一句语句的话,每句语句都必须用分号分隔"; 43 | if((word=statement(lexical_analyzer))!="") return word; 44 | } 45 | lexical_analyzer.getsymtype(); 46 | return ""; 47 | } 48 | 49 | std::string SyntacticAnalyzer::ifsym(LexicalAnalyzer& lexical_analyzer) 50 | { 51 | std::string word; 52 | if(lexical_analyzer.getsymtype()!=IFSYM) return "这里应该是一个if语句"; 53 | if((word=condition(lexical_analyzer))!="") return word; 54 | if(lexical_analyzer.getsymtype()!=THENSYM) return "喂喂..if语句没有跟then,你这个if语句是干啥的?if语句参考语法:IF X=0 THEN X:=1;"; 55 | return statement(lexical_analyzer); 56 | } 57 | 58 | std::string SyntacticAnalyzer::whilesym(LexicalAnalyzer& lexical_analyzer) 59 | { 60 | std::string word; 61 | if(lexical_analyzer.getsymtype()!=WHILESYM) return "这里应该是一个while语句"; 62 | if((word=condition(lexical_analyzer))!="") return word; 63 | if(lexical_analyzer.getsymtype()!=DOSYM) return "这里应该有一个do的,没有do,单单一个while有神马意义呢?"; 64 | return statement(lexical_analyzer); 65 | } 66 | 67 | std::string SyntacticAnalyzer::readwritesym(LexicalAnalyzer& lexical_analyzer) 68 | { 69 | std::string word=lexical_analyzer.getsymtype(); 70 | if(word!=READSYM && word!=WRITESYM) return "这里应该是一个函数"; 71 | if(lexical_analyzer.getsymtype()!=LPAREN) return "这是函数诶!他的语法应该是 READ(X); 或者 WRITE(Y); 吧,你貌似漏了左括号"; 72 | do{ 73 | if(lexical_analyzer.getsymtype()!=IDENT) return "函数里面要有标识符的啊,他的语法应该是 READ(X); 或是 WRITE(A,B,C);"; 74 | }while((word=lexical_analyzer.getsymtype())==COMMA); 75 | return (word==RPAREN?"":"函数参数要用右括号扩起来的啊,你加右括号了吗"); 76 | } 77 | 78 | -------------------------------------------------------------------------------- /CompilePrinciple 3/wordlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __WORDLIST_H 2 | #define __WORDLIST_H 3 | 4 | #define IDENT "ident" 5 | #define NUMBER "number" 6 | 7 | #endif 8 | 9 | -------------------------------------------------------------------------------- /CompilePrinciple 4/LexicalAnalyzer.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __LEXICALANALYZER_CLASS_H 2 | #define __LEXICALANALYZER_CLASS_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class LexicalAnalyzer 9 | { 10 | public: 11 | class InputReader 12 | { 13 | protected: 14 | int curline,curchar,curindex,prevline,prevchar; 15 | public: 16 | InputReader():curline(1),curchar(0),curindex(0) 17 | { 18 | } 19 | virtual char peekchar() const=0; 20 | virtual char getchar()=0; 21 | virtual int get_curline() const 22 | { 23 | return this->curline; 24 | } 25 | virtual int get_curchar() const 26 | { 27 | return this->curchar; 28 | } 29 | virtual int get_prevline() const 30 | { 31 | return this->prevline; 32 | } 33 | virtual int get_prevchar() const 34 | { 35 | return this->prevchar; 36 | } 37 | virtual bool eof() const=0; 38 | }; 39 | 40 | class ConsoleInputReader:public InputReader 41 | { 42 | public: 43 | char peekchar() const 44 | { 45 | if(eof()) return -1; 46 | return std::cin.peek(); 47 | } 48 | char getchar() 49 | { 50 | if(eof()) return -1; 51 | char c=std::cin.get(); 52 | this->prevline=this->curline; 53 | this->prevchar=this->curchar; 54 | ++this->curindex; 55 | if(c=='\n') 56 | { 57 | ++this->curline; 58 | this->curchar=0; 59 | } 60 | else ++this->curchar; 61 | return c; 62 | } 63 | bool eof() const 64 | { 65 | return std::cin.eof(); 66 | } 67 | }; 68 | 69 | class FileReader:public InputReader 70 | { 71 | private: 72 | std::string buffer; 73 | public: 74 | bool open(const std::string& path) 75 | { 76 | std::ifstream file(path.c_str(),std::ios::in); 77 | if(file.fail()) return false; 78 | std::getline(file,this->buffer,(char)-1); 79 | file.close(); 80 | curline=1; 81 | curchar=curindex=0; 82 | return true; 83 | } 84 | char peekchar() const 85 | { 86 | if(eof()) return -1; 87 | return this->buffer[this->curindex]; 88 | } 89 | char getchar() 90 | { 91 | char c=peekchar(); 92 | this->prevline=this->curline; 93 | this->prevchar=this->curchar; 94 | ++this->curindex; 95 | if(c=='\n') 96 | { 97 | ++this->curline; 98 | this->curchar=0; 99 | } 100 | else ++this->curchar; 101 | return c; 102 | } 103 | bool eof() const 104 | { 105 | return this->curindex >= this->buffer.size(); 106 | } 107 | }; 108 | private: 109 | ConsoleInputReader consoleinputreader; 110 | FileReader filereader; 111 | InputReader *inputreader; 112 | std::deque symtypes; 113 | std::deque symwords; 114 | std::deque symnumlines; 115 | std::deque symnumchars; 116 | int curdequeindex; 117 | bool resetmode; 118 | public: 119 | bool open(const std::string &path=""); 120 | void next(); 121 | std::string peeksymtype() const; 122 | std::string getsymtype(); 123 | std::string peeksymword() const; 124 | std::string getsymword(); 125 | std::string getprevsymtype() const; 126 | std::string getprevsymword() const; 127 | bool eof() const; 128 | int get_curline() const; 129 | int get_curchar() const; 130 | int get_prevline() const; 131 | int get_prevchar() const; 132 | void reset(); 133 | private: 134 | std::string getKeyword(std::string) const; 135 | std::string get_operator_name(const std::string&) const; 136 | bool getsym(std::string&,std::string&); 137 | }; 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /CompilePrinciple 4/LexicalAnalyzer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | 6 | bool LexicalAnalyzer::open(const std::string &path) 7 | { 8 | std::string word,type; 9 | this->symwords.clear(); 10 | this->symtypes.clear(); 11 | this->symnumchars.clear(); 12 | this->symnumlines.clear(); 13 | 14 | if(path.size()>0)//文件操作 15 | { 16 | this->inputreader=&this->filereader; 17 | if(!this->filereader.open(path)) return false; 18 | } 19 | else//控制台输入操作 20 | { 21 | this->inputreader=&this->consoleinputreader; 22 | } 23 | 24 | if(!this->getsym(word,type)) return false; 25 | this->symwords.push_back(word); 26 | this->symtypes.push_back(type); 27 | this->curdequeindex=0; 28 | this->resetmode=0; 29 | return true; 30 | } 31 | 32 | void LexicalAnalyzer::next() 33 | { 34 | std::string type,word; 35 | if(!this->resetmode) 36 | { 37 | this->getsym(word,type); 38 | this->symwords.push_back(word); 39 | this->symtypes.push_back(type); 40 | } 41 | ++this->curdequeindex; 42 | } 43 | 44 | std::string LexicalAnalyzer::peeksymtype() const 45 | { 46 | return this->symtypes[this->curdequeindex]; 47 | } 48 | 49 | std::string LexicalAnalyzer::getsymtype() 50 | { 51 | if(!this->eof()) 52 | { 53 | this->next(); 54 | return this->getprevsymtype(); 55 | } 56 | else return this->peeksymtype(); 57 | } 58 | 59 | std::string LexicalAnalyzer::peeksymword() const 60 | { 61 | return this->symwords[this->curdequeindex]; 62 | } 63 | 64 | std::string LexicalAnalyzer::getsymword() 65 | { 66 | if(!this->eof()) 67 | { 68 | this->next(); 69 | return this->getprevsymword(); 70 | } 71 | else return this->peeksymword(); 72 | } 73 | 74 | std::string LexicalAnalyzer::getprevsymtype() const 75 | { 76 | return this->symtypes[this->curdequeindex-1]; 77 | } 78 | 79 | std::string LexicalAnalyzer::getprevsymword() const 80 | { 81 | return this->symwords[this->curdequeindex-1]; 82 | } 83 | 84 | bool LexicalAnalyzer::eof() const 85 | { 86 | if(!this->resetmode) return this->inputreader->eof(); 87 | else return this->curdequeindex==this->symtypes.size(); 88 | } 89 | 90 | int LexicalAnalyzer::get_curline() const 91 | { 92 | return this->symnumlines[this->curdequeindex]; 93 | } 94 | 95 | int LexicalAnalyzer::get_curchar() const 96 | { 97 | return this->symnumchars[this->curdequeindex]; 98 | } 99 | 100 | int LexicalAnalyzer::get_prevline() const 101 | { 102 | return this->symnumlines[this->curdequeindex-1]; 103 | } 104 | 105 | int LexicalAnalyzer::get_prevchar() const 106 | { 107 | return this->symnumchars[this->curdequeindex-1]; 108 | } 109 | 110 | void LexicalAnalyzer::reset() 111 | { 112 | this->resetmode=1; 113 | this->curdequeindex=0; 114 | } 115 | -------------------------------------------------------------------------------- /CompilePrinciple 4/SyntacticAnalyzer.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYNTACTICANALYZER_CLASS_H 2 | #define __SYNTACTICANALYZER_CLASS_H 3 | #include"LexicalAnalyzer.class.h" 4 | 5 | class SyntacticAnalyzer 6 | { 7 | public: 8 | std::string get_error_info() 9 | { 10 | return this->errorinfo; 11 | } 12 | //仅仅给第4题用 13 | /* 14 | bool analyze(LexicalAnalyzer&); 15 | private: 16 | bool subprogram(LexicalAnalyzer&); 17 | bool constsym(LexicalAnalyzer&); 18 | bool varsym(LexicalAnalyzer&); 19 | bool procsym(LexicalAnalyzer&); 20 | bool statement(LexicalAnalyzer&); 21 | bool callsym(LexicalAnalyzer&); 22 | bool beginsym(LexicalAnalyzer&); 23 | bool ifsym(LexicalAnalyzer&); 24 | bool whilesym(LexicalAnalyzer&); 25 | bool readwritesym(LexicalAnalyzer&); 26 | bool ident(LexicalAnalyzer&);*/ 27 | int condition(LexicalAnalyzer&,bool&); 28 | int expression(LexicalAnalyzer&,int&); 29 | //仅仅给第4题用 30 | private: 31 | int item(LexicalAnalyzer&,int&); 32 | int factor(LexicalAnalyzer&,int&); 33 | private: 34 | std::string errorinfo; 35 | }; 36 | 37 | #endif 38 | 39 | -------------------------------------------------------------------------------- /CompilePrinciple 4/details.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"operatorlist.h" 5 | #include"keywordlist.h" 6 | #include"wordlist.h" 7 | 8 | int SyntacticAnalyzer::condition(LexicalAnalyzer& lexical_analyzer,bool& value) 9 | { 10 | int res=1,tmp_value,tmp_value2,tmp_res=1,tmp_res2=1; 11 | std::string word=lexical_analyzer.peeksymtype(); 12 | if(word==ODDSYM) 13 | { 14 | lexical_analyzer.getsymtype(); 15 | if(!(res=expression(lexical_analyzer,tmp_value))) return false; 16 | else if(res==2) value=tmp_value%2==1; 17 | 18 | return res; 19 | } 20 | else 21 | { 22 | if(!(tmp_res=expression(lexical_analyzer,tmp_value))) return false; 23 | if(word=lexical_analyzer.getsymtype(), 24 | word!=EQL && word!=NEQ && word!=LSS && word!=LEQ && word!=GTR && word!=GEQ) 25 | { 26 | this->errorinfo="这里应该有一个比较运算符,例如等于 = ,不等于 # ,小于 < ,小于等于 <= ,大于 > ,大于等于 >= "; 27 | return false; 28 | } 29 | else 30 | { 31 | if(!(tmp_res2=expression(lexical_analyzer,tmp_value2))) return false; 32 | else if(tmp_res==2 && tmp_res2==2) 33 | { 34 | if(word==EQL) value=tmp_value==tmp_value2; 35 | else if(word==NEQ) value=tmp_value!=tmp_value2; 36 | else if(word==LSS) value=tmp_valuetmp_value2; 39 | else if(word==GEQ) value=tmp_value>=tmp_value2; 40 | return 2; 41 | } 42 | return 1; 43 | } 44 | } 45 | } 46 | 47 | int SyntacticAnalyzer::expression(LexicalAnalyzer& lexical_analyzer,int& value) 48 | { 49 | int fac=1,res=1,tmp_res=1,tmp_value; 50 | std::string type=lexical_analyzer.peeksymtype(); 51 | if(type==PLUS || type==MINUS) 52 | { 53 | if(type==MINUS) fac=-1; 54 | lexical_analyzer.getsymtype(); 55 | } 56 | if(!(res=item(lexical_analyzer,value))) return false; 57 | else if(res==2) value*=fac;//之前是符号,让它乘以符号因子1或-1 58 | 59 | while(type=lexical_analyzer.peeksymtype(),type==PLUS || type==MINUS) 60 | { 61 | if(lexical_analyzer.getsymtype(),!(tmp_res=item(lexical_analyzer,tmp_value))) return false; 62 | if(res==2 && tmp_res==2) 63 | { 64 | if(type==PLUS) value+=tmp_value; 65 | else /*if(type==MINUS)*/ value-=tmp_value; 66 | } 67 | else res=1; 68 | } 69 | 70 | return res; 71 | } 72 | 73 | int SyntacticAnalyzer::item(LexicalAnalyzer& lexical_analyzer,int& value) 74 | { 75 | int res=1,tmp_res=1,tmp_value; 76 | std::string type; 77 | if(!(res=factor(lexical_analyzer,value))) return false; 78 | //如果能走到这一步,res只会是1或2 79 | while(type=lexical_analyzer.peeksymtype(),type==TIMES || type==SLASH) 80 | { 81 | if(lexical_analyzer.getsymtype(),!(tmp_res=factor(lexical_analyzer,tmp_value))) return false; 82 | //如果能走到这一步,tmp_res只会是1或2 83 | else if(res==2 && tmp_res==2) 84 | { 85 | if(type==TIMES) value*=tmp_value; 86 | else/* if(type==SLASH)*/ value/=tmp_value; 87 | } 88 | else res=1;//只要有一次tmp_res不是2,那么对value的计算毫无意义,使res=1来避免此计算 89 | } 90 | return res; 91 | } 92 | 93 | int SyntacticAnalyzer::factor(LexicalAnalyzer& lexical_analyzer,int& value) 94 | { 95 | int res=1;//0: 语法错 1: 语法对 不会返回语义值 2: 语法对 会返回语义值 96 | std::string type=lexical_analyzer.getsymtype(); 97 | std::string word=lexical_analyzer.getprevsymword(); 98 | if(type!=IDENT && type!=NUMBER && type!=LPAREN) 99 | { 100 | this->errorinfo="这里应该是一个标识符或是一个数字或是一个表达式"; 101 | return false; 102 | } 103 | if(type==NUMBER) 104 | { 105 | sscanf(word.c_str(),"%d",&value); 106 | return 2; 107 | } 108 | if(type==LPAREN) 109 | { 110 | if(!(res=expression(lexical_analyzer,value))) return false; 111 | if(lexical_analyzer.getsymtype()!=RPAREN) 112 | { 113 | this->errorinfo="这里应该有一个右括号,表达式必须用一对括号扩起来"; 114 | return false; 115 | } 116 | } 117 | return res; 118 | } 119 | 120 | -------------------------------------------------------------------------------- /CompilePrinciple 4/func_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUNC_LIB_H 2 | #define __FUNC_LIB_H 3 | 4 | #define CHAR_CHARACTER 1 5 | #define CHAR_NUMBER 2 6 | #define CHAR_OTHER 3 7 | #define CHAR_NULL 4 8 | 9 | inline 10 | int judge_char_type(char c) 11 | { 12 | if(c==' '||c=='\t'||c=='\n') return CHAR_NULL; 13 | else if( (c>='A'&&c<='Z') || (c>='a'&&c<='z') ) return CHAR_CHARACTER; 14 | else if( c>='0'&&c<='9' ) return CHAR_NUMBER; 15 | else return CHAR_OTHER; 16 | } 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /CompilePrinciple 4/getsym.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"func_lib.h" 4 | #include"LexicalAnalyzer.class.h" 5 | #include"wordlist.h" 6 | 7 | bool LexicalAnalyzer::getsym(std::string &word,std::string &word_type) 8 | { 9 | char c; 10 | int c_type; 11 | const int WORD_MAX_LENGTH=10; 12 | const int NUM_MAX_LENGTH=14; 13 | word=word_type=""; 14 | 15 | do 16 | { 17 | if((c=this->inputreader->getchar())<=0) return false; 18 | c_type=judge_char_type(c); 19 | } 20 | while(c_type==CHAR_NULL); 21 | 22 | this->symnumchars.push_back(this->inputreader->get_curchar()); 23 | this->symnumlines.push_back(this->inputreader->get_curline()); 24 | 25 | if(c_type==CHAR_CHARACTER) 26 | { 27 | word+=c; 28 | while(word.size()inputreader->peekchar(); 31 | c_type=judge_char_type(c); 32 | if(c_type!=CHAR_CHARACTER && c_type!=CHAR_NUMBER) break; 33 | c=this->inputreader->getchar(); 34 | word+=c; 35 | } 36 | 37 | word_type=getKeyword(word); 38 | if(word_type.size()==0) 39 | { 40 | word_type=IDENT; 41 | } 42 | } 43 | else if(c_type==CHAR_NUMBER) 44 | { 45 | word+=c; 46 | while(word.size()inputreader->peekchar(); 49 | c_type=judge_char_type(c); 50 | if(c_type!=CHAR_NUMBER) break; 51 | c=this->inputreader->getchar(); 52 | word+=c; 53 | } 54 | word_type=NUMBER; 55 | } 56 | else/*if(c_type==CHAR_OTHER)*/ 57 | { 58 | word=c; 59 | switch(c) 60 | { 61 | case ':': 62 | case '>': 63 | case '<': 64 | if(this->inputreader->peekchar()=='=') 65 | { 66 | word+=this->inputreader->getchar(); 67 | } 68 | break; 69 | } 70 | 71 | word_type=get_operator_name(word); 72 | //if(word_type.size()==0) error 73 | } 74 | return true; 75 | } 76 | -------------------------------------------------------------------------------- /CompilePrinciple 4/keyword.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | #include"keywordlist.h" 6 | #define KEYWORD_LENGTH 13 7 | 8 | std::string LexicalAnalyzer::getKeyword(std::string str) const 9 | { 10 | static const std::pair KEYWORDS_ARRAY[]={ std::make_pair("if",IFSYM), 11 | std::make_pair("then",THENSYM), 12 | std::make_pair("while",WHILESYM), 13 | std::make_pair("do",DOSYM), 14 | std::make_pair("read",READSYM), 15 | std::make_pair("write",WRITESYM), 16 | std::make_pair("call",CALLSYM), 17 | std::make_pair("begin",BEGINSYM), 18 | std::make_pair("end",ENDSYM), 19 | std::make_pair("const",CONSTSYM), 20 | std::make_pair("var",VARSYM), 21 | std::make_pair("procedure",PROCSYM), 22 | std::make_pair("odd",ODDSYM)}; 23 | 24 | static const std::map KEYWORDS(KEYWORDS_ARRAY,KEYWORDS_ARRAY+KEYWORD_LENGTH); 25 | 26 | for(int i=0;i::const_iterator iter=KEYWORDS.find(str); 28 | if(iter!=KEYWORDS.end()) return iter->second; 29 | else return ""; 30 | } 31 | -------------------------------------------------------------------------------- /CompilePrinciple 4/keywordlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYWORD_H 2 | #define __KEYWORD_H 3 | 4 | #define IFSYM "ifsym" 5 | #define THENSYM "thensym" 6 | #define WHILESYM "whilesym" 7 | #define DOSYM "dosym" 8 | #define READSYM "readsym" 9 | #define WRITESYM "writesym" 10 | #define CALLSYM "callsym" 11 | #define BEGINSYM "beginsym" 12 | #define ENDSYM "endsym" 13 | #define CONSTSYM "constsym" 14 | #define VARSYM "varsym" 15 | #define PROCSYM "procsym" 16 | #define ODDSYM "oddsym" 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /CompilePrinciple 4/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | 5 | int main(int num_args,char* args[]) 6 | { 7 | int res,value; 8 | std::string word; 9 | LexicalAnalyzer lexical_analyzer; 10 | SyntacticAnalyzer syntactic_analyzer; 11 | 12 | if(num_args<=1) 13 | { 14 | lexical_analyzer.open(); 15 | } 16 | 17 | else if(!lexical_analyzer.open(args[1])) 18 | { 19 | std::cout << "文件打开时出错" << std::endl; 20 | return 0; 21 | } 22 | 23 | ///仅仅给第4题用 24 | if(res=syntactic_analyzer.expression(lexical_analyzer,value)) 25 | { 26 | std::cout << "语法正确" << std::endl; 27 | if(res==2) std::cout << "他的值为 " << value << std::endl; 28 | } 29 | /* 30 | if(syntactic_analyzer.analyze(lexical_analyzer)) 31 | { 32 | std::cout << "语法正确" << std::endl; 33 | }*/ 34 | else 35 | { 36 | std::cout << "语法错误\n" 37 | << "错误行数: " << lexical_analyzer.get_prevline() << '\n' 38 | << "错误列数: " << lexical_analyzer.get_prevchar() << '\n' 39 | << "错误内容: " << lexical_analyzer.getprevsymword() << '\n' 40 | << "错误原因:" << syntactic_analyzer.get_error_info() << std::endl; 41 | } 42 | /* 43 | lexical_analyzer.reset(); 44 | while(!lexical_analyzer.eof()) 45 | { 46 | std::cout << lexical_analyzer.peeksymtype() << " , "; 47 | std::cout << lexical_analyzer.peeksymword() << " , "; 48 | std::cout << lexical_analyzer.get_curline() << " , "; 49 | std::cout << lexical_analyzer.get_curchar() << std::endl; 50 | lexical_analyzer.next(); 51 | }*/ 52 | return 0; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /CompilePrinciple 4/operator.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"LexicalAnalyzer.class.h" 4 | #include"operatorlist.h" 5 | #define OPERATOR_LENGTH 16 6 | 7 | std::string LexicalAnalyzer::get_operator_name(const std::string& str) const 8 | { 9 | static const std::pair OPERATORS_ARRAY[]={ std::make_pair(":=",BECOMES), 10 | std::make_pair(">=",GEQ), 11 | std::make_pair(">",GTR), 12 | std::make_pair("<=",LEQ), 13 | std::make_pair("<",LSS), 14 | std::make_pair("+",PLUS), 15 | std::make_pair("-",MINUS), 16 | std::make_pair("*",TIMES), 17 | std::make_pair("/",SLASH), 18 | std::make_pair("=",EQL), 19 | std::make_pair("#",NEQ), 20 | std::make_pair(",",COMMA), 21 | std::make_pair(".",PERIOD), 22 | std::make_pair(";",SEMICOLON), 23 | std::make_pair("(",LPAREN), 24 | std::make_pair(")",RPAREN)}; 25 | 26 | static const std::map OPERATORS(OPERATORS_ARRAY,OPERATORS_ARRAY+OPERATOR_LENGTH); 27 | 28 | std::map::const_iterator iter=OPERATORS.find(str); 29 | if(iter!=OPERATORS.end()) return iter->second; 30 | else return ""; 31 | } 32 | -------------------------------------------------------------------------------- /CompilePrinciple 4/operatorlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __OPERATORLIST_H 2 | #define __OPERATORLIST_H 3 | 4 | #define BECOMES "becomes" 5 | #define GEQ "geq" 6 | #define GTR "gtr" 7 | #define LEQ "leq" 8 | #define LSS "lss" 9 | #define PLUS "plus" 10 | #define MINUS "minus" 11 | #define TIMES "times" 12 | #define SLASH "slash" 13 | #define EQL "eql" 14 | #define NEQ "neq" 15 | #define COMMA "comma" 16 | #define PERIOD "period" 17 | #define SEMICOLON "semicolon" 18 | #define LPAREN "lparen" 19 | #define RPAREN "rparen" 20 | 21 | #endif 22 | 23 | -------------------------------------------------------------------------------- /CompilePrinciple 4/program.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | #include 3 | #include"LexicalAnalyzer.class.h" 4 | #include"SyntacticAnalyzer.class.h" 5 | #include"keywordlist.h" 6 | #include"operatorlist.h" 7 | #include"wordlist.h" 8 | 9 | bool SyntacticAnalyzer::analyze(LexicalAnalyzer& lexical_analyzer) 10 | { 11 | if(!subprogram(lexical_analyzer)) return false; 12 | if(lexical_analyzer.peeksymtype()!=PERIOD) 13 | { 14 | if(lexical_analyzer.peeksymtype()!="") this->errorinfo="程序有错,这个程序到这里看上去应该已经结束了,但其实不是。是不是少了运算符或漏了左括号?"; 15 | else this->errorinfo="必须在程序结尾加一个句号,不要问我为神马,这就是语法!"; 16 | return false; 17 | } 18 | return true; 19 | } 20 | 21 | bool SyntacticAnalyzer::subprogram(LexicalAnalyzer& lexical_analyzer) 22 | { 23 | std::string word=lexical_analyzer.peeksymtype(); 24 | if(word==CONSTSYM) 25 | { 26 | if(!constsym(lexical_analyzer)) return false; 27 | word=lexical_analyzer.peeksymtype(); 28 | } 29 | if(word==VARSYM) 30 | { 31 | if(!varsym(lexical_analyzer)) return false; 32 | word=lexical_analyzer.peeksymtype(); 33 | } 34 | if(word==PROCSYM) 35 | { 36 | do 37 | { 38 | if(!procsym(lexical_analyzer)) return false; 39 | }while((word=lexical_analyzer.peeksymtype())==PROCSYM); 40 | } 41 | return statement(lexical_analyzer); 42 | } 43 | 44 | bool SyntacticAnalyzer::constsym(LexicalAnalyzer& lexical_analyzer) 45 | { 46 | std::string word; 47 | if(lexical_analyzer.getsymtype()!=CONSTSYM) 48 | { 49 | this->errorinfo="这里应该是一个const语句"; 50 | return false; 51 | } 52 | do 53 | { 54 | if(lexical_analyzer.getsymtype()!=IDENT) 55 | { 56 | this->errorinfo="这里应该是一个标识符,例如:CONST X=6,Y=4;"; 57 | return false; 58 | } 59 | if(lexical_analyzer.getsymtype()!=EQL) 60 | { 61 | this->errorinfo="这里应该是一个等于符号,例如:CONST X=6,Y=4;"; 62 | return false; 63 | } 64 | if(lexical_analyzer.getsymtype()!=NUMBER) 65 | { 66 | this->errorinfo="这里应该是一个数字,例如:CONST X=6,Y=4;"; 67 | return false; 68 | } 69 | }while((word=lexical_analyzer.getsymtype())==COMMA); 70 | 71 | if(word==SEMICOLON) return true; 72 | else 73 | { 74 | this->errorinfo="const语句必须以分号结尾,例如:CONST X=6,Y=4; 请留意末尾的分号"; 75 | return false; 76 | } 77 | } 78 | 79 | bool SyntacticAnalyzer::varsym(LexicalAnalyzer& lexical_analyzer) 80 | { 81 | std::string word; 82 | if(lexical_analyzer.getsymtype()!=VARSYM) 83 | { 84 | this->errorinfo="这里应该是一个var语句"; 85 | return false; 86 | } 87 | do 88 | { 89 | if(lexical_analyzer.getsymtype()!=IDENT) 90 | { 91 | this->errorinfo="这里应该是一个标识符,例如:VAR X,Y,Z;"; 92 | return false; 93 | } 94 | }while((word=lexical_analyzer.getsymtype())==COMMA); 95 | if(word==SEMICOLON) return true; 96 | else 97 | { 98 | this->errorinfo="var语句必须以分号结尾,例如:VAR X,Y,Z; 请留意末尾的分号"; 99 | return false; 100 | } 101 | } 102 | 103 | bool SyntacticAnalyzer::procsym(LexicalAnalyzer& lexical_analyzer) 104 | { 105 | if(lexical_analyzer.getsymtype()!=PROCSYM) 106 | { 107 | this->errorinfo="这里应该是一个procedure语句"; 108 | return false; 109 | } 110 | if(lexical_analyzer.getsymtype()!=IDENT) 111 | { 112 | this->errorinfo="这里应该有一个标识符,作为procedure的名字,例如:PROCEDURE PROC;"; 113 | return false; 114 | } 115 | if(lexical_analyzer.getsymtype()!=SEMICOLON) 116 | { 117 | this->errorinfo="这里应该有一个分号,作为procedure声明和内容的分隔符,例如:PROCEDURE PROC; 请留意末尾的分号"; 118 | return false; 119 | } 120 | if(!subprogram(lexical_analyzer)) return false; 121 | if(lexical_analyzer.getsymtype()!=SEMICOLON) 122 | { 123 | this->errorinfo="这里应该有一个分号,作为一个procedure结束,我知道加一个分号很无聊也不能促进减肥,但是这是语法,是规定,只要你爸不是李刚,就必需遵守这个规定"; 124 | return false; 125 | } 126 | return true; 127 | } 128 | */ -------------------------------------------------------------------------------- /CompilePrinciple 4/statement.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | #include 3 | #include"LexicalAnalyzer.class.h" 4 | #include"SyntacticAnalyzer.class.h" 5 | #include"keywordlist.h" 6 | #include"operatorlist.h" 7 | #include"wordlist.h" 8 | 9 | bool SyntacticAnalyzer::statement(LexicalAnalyzer& lexical_analyzer) 10 | { 11 | std::string word=lexical_analyzer.peeksymtype(); 12 | if(word==IDENT) return ident(lexical_analyzer); 13 | if(word==CALLSYM) return callsym(lexical_analyzer); 14 | if(word==BEGINSYM) return beginsym(lexical_analyzer); 15 | if(word==IFSYM) return ifsym(lexical_analyzer); 16 | if(word==WHILESYM) return whilesym(lexical_analyzer); 17 | if(word==READSYM || word==WRITESYM) return readwritesym(lexical_analyzer); 18 | 19 | return true; 20 | } 21 | 22 | bool SyntacticAnalyzer::ident(LexicalAnalyzer& lexical_analyzer) 23 | { 24 | if(lexical_analyzer.getsymtype()!=IDENT) 25 | { 26 | this->errorinfo="这里应该有一个标识符,参考赋值语句的语法:X:=2;"; 27 | return false; 28 | } 29 | if(lexical_analyzer.getsymtype()!=BECOMES) 30 | { 31 | this->errorinfo="这里应该是一个赋值符号 := ,参考赋值语句的语法:X:=2;"; 32 | return false; 33 | } 34 | return expression(lexical_analyzer); 35 | } 36 | 37 | bool SyntacticAnalyzer::callsym(LexicalAnalyzer& lexical_analyzer) 38 | { 39 | if(lexical_analyzer.getsymtype()!=CALLSYM) 40 | { 41 | this->errorinfo="这里应该是一个call语句,call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 42 | return false; 43 | } 44 | if(lexical_analyzer.getsymtype()!=IDENT) 45 | { 46 | this->errorinfo="这个应该是一个标识符,否则我怎么知道你要call谁?call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 47 | return false; 48 | } 49 | return true; 50 | } 51 | 52 | bool SyntacticAnalyzer::beginsym(LexicalAnalyzer& lexical_analyzer) 53 | { 54 | std::string word; 55 | if(lexical_analyzer.getsymtype()!=BEGINSYM) 56 | { 57 | this->errorinfo="这里应该有一个begin语句的吧"; 58 | return false; 59 | } 60 | if(!statement(lexical_analyzer)) return false; 61 | while(lexical_analyzer.peeksymtype()!=ENDSYM) 62 | { 63 | if(lexical_analyzer.getsymtype()!=SEMICOLON) 64 | { 65 | this->errorinfo="这里必须有一个分号的啊,如果BEGIN..END语句中有多于一句语句的话,每句语句都必须用分号分隔"; 66 | return false; 67 | } 68 | if(!statement(lexical_analyzer)) return false; 69 | } 70 | lexical_analyzer.getsymtype(); 71 | return true; 72 | } 73 | 74 | bool SyntacticAnalyzer::ifsym(LexicalAnalyzer& lexical_analyzer) 75 | { 76 | std::string word; 77 | if(lexical_analyzer.getsymtype()!=IFSYM) 78 | { 79 | this->errorinfo="这里应该是一个if语句"; 80 | return false; 81 | } 82 | if(!condition(lexical_analyzer)) return false; 83 | if(lexical_analyzer.getsymtype()!=THENSYM) 84 | { 85 | this->errorinfo="喂喂..if语句没有跟then,你这个if语句是干啥的?if语句参考语法:IF X=0 THEN X:=1;"; 86 | return false; 87 | } 88 | return statement(lexical_analyzer); 89 | } 90 | 91 | bool SyntacticAnalyzer::whilesym(LexicalAnalyzer& lexical_analyzer) 92 | { 93 | std::string word; 94 | if(lexical_analyzer.getsymtype()!=WHILESYM) 95 | { 96 | this->errorinfo="这里应该是一个while语句"; 97 | return false; 98 | } 99 | if(!condition(lexical_analyzer)) return false; 100 | if(lexical_analyzer.getsymtype()!=DOSYM) 101 | { 102 | this->errorinfo="这里应该有一个do的,没有do,单单一个while有神马意义呢?"; 103 | return false; 104 | } 105 | return statement(lexical_analyzer); 106 | } 107 | 108 | bool SyntacticAnalyzer::readwritesym(LexicalAnalyzer& lexical_analyzer) 109 | { 110 | std::string word=lexical_analyzer.getsymtype(); 111 | if(word!=READSYM && word!=WRITESYM) 112 | { 113 | this->errorinfo="这里应该是一个函数"; 114 | return false; 115 | } 116 | if(lexical_analyzer.getsymtype()!=LPAREN) 117 | { 118 | this->errorinfo="这是函数诶!他的语法应该是 READ(X); 或者 WRITE(Y); 吧,你貌似漏了左括号"; 119 | return false; 120 | } 121 | do{ 122 | if(lexical_analyzer.getsymtype()!=IDENT) 123 | { 124 | this->errorinfo="函数里面要有标识符的啊,他的语法应该是 READ(X); 或是 WRITE(A,B,C);"; 125 | return false; 126 | } 127 | }while((word=lexical_analyzer.getsymtype())==COMMA); 128 | if(word==RPAREN) return true; 129 | else 130 | { 131 | this->errorinfo="函数参数要用右括号扩起来的啊,你加右括号了吗"; 132 | return false; 133 | } 134 | } 135 | 136 | */ -------------------------------------------------------------------------------- /CompilePrinciple 4/wordlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __WORDLIST_H 2 | #define __WORDLIST_H 3 | 4 | #define IDENT "ident" 5 | #define NUMBER "number" 6 | 7 | #endif 8 | 9 | -------------------------------------------------------------------------------- /CompilePrinciple 5/LexicalAnalyzer.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __LEXICALANALYZER_CLASS_H 2 | #define __LEXICALANALYZER_CLASS_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class LexicalAnalyzer 9 | { 10 | public: 11 | class InputReader 12 | { 13 | protected: 14 | int curline,curchar,curindex,prevline,prevchar; 15 | public: 16 | InputReader():curline(1),curchar(0),curindex(0) 17 | { 18 | } 19 | virtual char peekchar() const=0; 20 | virtual char getchar()=0; 21 | virtual int get_curline() const 22 | { 23 | return this->curline; 24 | } 25 | virtual int get_curchar() const 26 | { 27 | return this->curchar; 28 | } 29 | virtual int get_prevline() const 30 | { 31 | return this->prevline; 32 | } 33 | virtual int get_prevchar() const 34 | { 35 | return this->prevchar; 36 | } 37 | virtual bool eof() const=0; 38 | }; 39 | 40 | class ConsoleInputReader:public InputReader 41 | { 42 | public: 43 | char peekchar() const 44 | { 45 | if(eof()) return -1; 46 | return std::cin.peek(); 47 | } 48 | char getchar() 49 | { 50 | if(eof()) return -1; 51 | char c=std::cin.get(); 52 | this->prevline=this->curline; 53 | this->prevchar=this->curchar; 54 | ++this->curindex; 55 | if(c=='\n') 56 | { 57 | ++this->curline; 58 | this->curchar=0; 59 | } 60 | else ++this->curchar; 61 | return c; 62 | } 63 | bool eof() const 64 | { 65 | return std::cin.eof(); 66 | } 67 | }; 68 | 69 | class FileReader:public InputReader 70 | { 71 | private: 72 | std::string buffer; 73 | public: 74 | bool open(const std::string& path) 75 | { 76 | std::ifstream file(path.c_str(),std::ios::in); 77 | if(file.fail()) return false; 78 | std::getline(file,this->buffer,(char)-1); 79 | file.close(); 80 | curline=1; 81 | curchar=curindex=0; 82 | return true; 83 | } 84 | char peekchar() const 85 | { 86 | if(eof()) return -1; 87 | return this->buffer[this->curindex]; 88 | } 89 | char getchar() 90 | { 91 | char c=peekchar(); 92 | this->prevline=this->curline; 93 | this->prevchar=this->curchar; 94 | ++this->curindex; 95 | if(c=='\n') 96 | { 97 | ++this->curline; 98 | this->curchar=0; 99 | } 100 | else ++this->curchar; 101 | return c; 102 | } 103 | bool eof() const 104 | { 105 | return this->curindex >= this->buffer.size(); 106 | } 107 | }; 108 | private: 109 | ConsoleInputReader consoleinputreader; 110 | FileReader filereader; 111 | InputReader *inputreader; 112 | std::deque symtypes; 113 | std::deque symwords; 114 | std::deque symnumlines; 115 | std::deque symnumchars; 116 | int curdequeindex; 117 | bool resetmode; 118 | public: 119 | bool open(const std::string &path=""); 120 | void next(); 121 | std::string peeksymtype() const; 122 | std::string getsymtype(); 123 | std::string peeksymword() const; 124 | std::string getsymword(); 125 | std::string getprevsymtype() const; 126 | std::string getprevsymword() const; 127 | bool eof() const; 128 | int get_curline() const; 129 | int get_curchar() const; 130 | int get_prevline() const; 131 | int get_prevchar() const; 132 | void reset(); 133 | private: 134 | std::string getKeyword(std::string) const; 135 | std::string get_operator_name(const std::string&) const; 136 | bool getsym(std::string&,std::string&); 137 | }; 138 | 139 | #endif 140 | -------------------------------------------------------------------------------- /CompilePrinciple 5/LexicalAnalyzer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | 6 | bool LexicalAnalyzer::open(const std::string &path) 7 | { 8 | std::string word,type; 9 | this->symwords.clear(); 10 | this->symtypes.clear(); 11 | this->symnumchars.clear(); 12 | this->symnumlines.clear(); 13 | 14 | if(path.size()>0)//文件操作 15 | { 16 | this->inputreader=&this->filereader; 17 | if(!this->filereader.open(path)) return false; 18 | } 19 | else//控制台输入操作 20 | { 21 | this->inputreader=&this->consoleinputreader; 22 | } 23 | 24 | if(!this->getsym(word,type)) return false; 25 | this->symwords.push_back(word); 26 | this->symtypes.push_back(type); 27 | this->curdequeindex=0; 28 | this->resetmode=0; 29 | return true; 30 | } 31 | 32 | void LexicalAnalyzer::next() 33 | { 34 | std::string type,word; 35 | if(!this->resetmode) 36 | { 37 | this->getsym(word,type); 38 | this->symwords.push_back(word); 39 | this->symtypes.push_back(type); 40 | } 41 | ++this->curdequeindex; 42 | } 43 | 44 | std::string LexicalAnalyzer::peeksymtype() const 45 | { 46 | return this->symtypes[this->curdequeindex]; 47 | } 48 | 49 | std::string LexicalAnalyzer::getsymtype() 50 | { 51 | if(!this->eof()) 52 | { 53 | this->next(); 54 | return this->getprevsymtype(); 55 | } 56 | else return this->peeksymtype(); 57 | } 58 | 59 | std::string LexicalAnalyzer::peeksymword() const 60 | { 61 | return this->symwords[this->curdequeindex]; 62 | } 63 | 64 | std::string LexicalAnalyzer::getsymword() 65 | { 66 | if(!this->eof()) 67 | { 68 | this->next(); 69 | return this->getprevsymword(); 70 | } 71 | else return this->peeksymword(); 72 | } 73 | 74 | std::string LexicalAnalyzer::getprevsymtype() const 75 | { 76 | return this->symtypes[this->curdequeindex-1]; 77 | } 78 | 79 | std::string LexicalAnalyzer::getprevsymword() const 80 | { 81 | return this->symwords[this->curdequeindex-1]; 82 | } 83 | 84 | bool LexicalAnalyzer::eof() const 85 | { 86 | if(!this->resetmode) return this->inputreader->eof(); 87 | else return this->curdequeindex==this->symtypes.size(); 88 | } 89 | 90 | int LexicalAnalyzer::get_curline() const 91 | { 92 | return this->symnumlines[this->curdequeindex]; 93 | } 94 | 95 | int LexicalAnalyzer::get_curchar() const 96 | { 97 | return this->symnumchars[this->curdequeindex]; 98 | } 99 | 100 | int LexicalAnalyzer::get_prevline() const 101 | { 102 | return this->symnumlines[this->curdequeindex-1]; 103 | } 104 | 105 | int LexicalAnalyzer::get_prevchar() const 106 | { 107 | return this->symnumchars[this->curdequeindex-1]; 108 | } 109 | 110 | void LexicalAnalyzer::reset() 111 | { 112 | this->resetmode=1; 113 | this->curdequeindex=0; 114 | } 115 | -------------------------------------------------------------------------------- /CompilePrinciple 5/SyntacticAnalyzer.class.cpp: -------------------------------------------------------------------------------- 1 | #include"SyntacticAnalyzer.class.h" 2 | #include 3 | #include 4 | 5 | std::deque::const_iterator SyntacticAnalyzer::ident_stack_find(const std::string _ident) 6 | { 7 | for(std::deque::iterator iter=this->ident_stack.begin();iter!=this->ident_stack.end();++iter) 8 | { 9 | if(iter->ident==_ident) 10 | { 11 | return iter; 12 | } 13 | } 14 | return this->ident_stack.end(); 15 | } 16 | 17 | void SyntacticAnalyzer::ident_stack_clear() 18 | { 19 | while(this->ident_stack.back().flag!=BOUND) 20 | { 21 | this->ident_stack.pop_back(); 22 | } 23 | this->ident_stack.pop_back(); 24 | } 25 | 26 | std::string SyntacticAnalyzer::TempVar::next() 27 | { 28 | char buffer[10]; 29 | sprintf(buffer,"%d",this->seqnum++); 30 | return std::string(TEMP_VARNAME_PREFIX)+buffer; 31 | } 32 | 33 | bool SyntacticAnalyzer::TempVar::isTempVar(const std::string varname) 34 | { 35 | const std::string temp_varname_prefix=TEMP_VARNAME_PREFIX; 36 | return temp_varname_prefix==varname.substr(0,temp_varname_prefix.size()); 37 | } -------------------------------------------------------------------------------- /CompilePrinciple 5/SyntacticAnalyzer.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYNTACTICANALYZER_CLASS_H 2 | #define __SYNTACTICANALYZER_CLASS_H 3 | #include"LexicalAnalyzer.class.h" 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #define TEMP_VARNAME_PREFIX "tempvar_" 10 | 11 | class SyntacticAnalyzer 12 | { 13 | private: 14 | enum IdentStackFlag{CONST,VAR,BOUND}; 15 | enum SyntacticAnalyzerResult {ERROR=false,RIGHT=true,VALUE=2}; 16 | class IdentStackNode 17 | { 18 | public: 19 | IdentStackFlag flag; 20 | std::string ident; 21 | int value; 22 | public: 23 | IdentStackNode(const IdentStackFlag _flag,const std::string _ident="",const int _value=0):flag(_flag),ident(_ident),value(_value){} 24 | }; 25 | class TempVar 26 | { 27 | public: 28 | std::string prev_temp_varname; 29 | private: 30 | int seqnum; 31 | public: 32 | TempVar():seqnum(1){} 33 | std::string next(); 34 | static bool isTempVar(const std::string varname); 35 | }; 36 | class IntermediateCodeNode 37 | { 38 | public: 39 | std::string command; 40 | std::string oper1,oper2,oper3; 41 | }; 42 | private: 43 | std::string errorinfo; 44 | std::deque ident_stack; 45 | std::set procedure_set; 46 | std::deque intermediate_code_deque; 47 | TempVar tempvar; 48 | public: 49 | SyntacticAnalyzerResult analyze(LexicalAnalyzer&); 50 | private: 51 | SyntacticAnalyzerResult subprogram(LexicalAnalyzer&); 52 | SyntacticAnalyzerResult constsym(LexicalAnalyzer&); 53 | SyntacticAnalyzerResult varsym(LexicalAnalyzer&); 54 | SyntacticAnalyzerResult procsym(LexicalAnalyzer&); 55 | SyntacticAnalyzerResult statement(LexicalAnalyzer&); 56 | SyntacticAnalyzerResult callsym(LexicalAnalyzer&); 57 | SyntacticAnalyzerResult beginsym(LexicalAnalyzer&); 58 | SyntacticAnalyzerResult ifsym(LexicalAnalyzer&); 59 | SyntacticAnalyzerResult whilesym(LexicalAnalyzer&); 60 | SyntacticAnalyzerResult readwritesym(LexicalAnalyzer&); 61 | SyntacticAnalyzerResult ident(LexicalAnalyzer&); 62 | SyntacticAnalyzerResult condition(LexicalAnalyzer&,bool&); 63 | SyntacticAnalyzerResult expression(LexicalAnalyzer&,int&); 64 | SyntacticAnalyzerResult item(LexicalAnalyzer&,int&); 65 | SyntacticAnalyzerResult factor(LexicalAnalyzer&,int&); 66 | private: 67 | std::deque::const_iterator ident_stack_find(const std::string _ident); 68 | void ident_stack_clear(); 69 | public: 70 | std::string get_error_info() const 71 | { 72 | return this->errorinfo; 73 | } 74 | void print_intermediate_code(std::ostream& out) const 75 | { 76 | for(std::deque::const_iterator iter=this->intermediate_code_deque.begin(); 77 | iter!=this->intermediate_code_deque.end();++iter) 78 | { 79 | out << '(' << iter->command << ' ' << iter->oper1 << ' ' << iter->oper2 << ' ' << iter->oper3 << ')' << std::endl; 80 | } 81 | } 82 | }; 83 | 84 | #endif 85 | 86 | -------------------------------------------------------------------------------- /CompilePrinciple 5/details.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"operatorlist.h" 5 | #include"keywordlist.h" 6 | #include"wordlist.h" 7 | 8 | #define VALUEBUFFERLENGTH 10 9 | 10 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::condition(LexicalAnalyzer& lexical_analyzer,bool& value) 11 | { 12 | SyntacticAnalyzer::SyntacticAnalyzerResult res=RIGHT,tmp_res=RIGHT,tmp_res2=RIGHT; 13 | int tmp_value,tmp_value2; 14 | std::string type=lexical_analyzer.peeksymtype(); 15 | if(type==ODDSYM) 16 | { 17 | lexical_analyzer.getsymtype(); 18 | if(!(res=expression(lexical_analyzer,tmp_value))) return ERROR; 19 | else if(res==VALUE) value=tmp_value%2==1; 20 | 21 | return res; 22 | } 23 | else 24 | { 25 | if(!(tmp_res=expression(lexical_analyzer,tmp_value))) return ERROR; 26 | if(type=lexical_analyzer.getsymtype(), 27 | type!=EQL && type!=NEQ && type!=LSS && type!=LEQ && type!=GTR && type!=GEQ) 28 | { 29 | this->errorinfo="这里应该有一个比较运算符,例如等于 = ,不等于 # ,小于 < ,小于等于 <= ,大于 > ,大于等于 >= "; 30 | return ERROR; 31 | } 32 | else 33 | { 34 | if(!(tmp_res2=expression(lexical_analyzer,tmp_value2))) return ERROR; 35 | else if(tmp_res==VALUE && tmp_res2==VALUE) 36 | { 37 | if(type==EQL) value=tmp_value==tmp_value2; 38 | else if(type==NEQ) value=tmp_value!=tmp_value2; 39 | else if(type==LSS) value=tmp_valuetmp_value2; 42 | else if(type==GEQ) value=tmp_value>=tmp_value2; 43 | return VALUE; 44 | } 45 | return RIGHT; 46 | } 47 | } 48 | } 49 | 50 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::expression(LexicalAnalyzer& lexical_analyzer,int& value) 51 | { 52 | SyntacticAnalyzer::SyntacticAnalyzerResult res=RIGHT,tmp_res=RIGHT; 53 | SyntacticAnalyzer::IntermediateCodeNode newcodenode; 54 | int fac=1,tmp_value,some_value_to_optimize=0/*加减法这里是0,乘除法是1*/; 55 | char buffer[VALUEBUFFERLENGTH]; 56 | std::string type=lexical_analyzer.peeksymtype(),oper1; 57 | 58 | for(;;) 59 | { 60 | type=lexical_analyzer.peeksymtype(); 61 | if(type==PLUS || type==MINUS) 62 | { 63 | if(type==MINUS) fac=-1; 64 | lexical_analyzer.getsymtype(); 65 | } 66 | if(!(res=item(lexical_analyzer,value))) return ERROR; 67 | else if(res==VALUE && value==0 && (lexical_analyzer.peeksymtype()==PLUS || lexical_analyzer.peeksymtype()==MINUS)) continue; 68 | else if(res==VALUE)//既然是值,我们保留值的样子,不生成中间代码,以期待接下来的操作数都以值的形式出现,这样就可以实现优化 69 | { 70 | value*=fac;//之前是符号,让它乘以符号因子1或-1 71 | sprintf(buffer,"%d",value); 72 | this->tempvar.prev_temp_varname=buffer;//这里如果item返回值,替换掉最后一个临时变量 73 | } 74 | else if(fac==-1 && res==RIGHT)//如果这是个变量且在前面加过负号,在这里将出现(times -1 var tempvar)的中间代码 75 | { 76 | newcodenode.command=TIMESOPER; 77 | sprintf(buffer,"%d",-1); 78 | newcodenode.oper1=buffer; 79 | newcodenode.oper2=this->tempvar.prev_temp_varname;//prev_temp_varname里存储item函数中的最后结果 80 | newcodenode.oper3=this->tempvar.next(); 81 | this->intermediate_code_deque.push_back(newcodenode); 82 | this->tempvar.prev_temp_varname=newcodenode.oper3; 83 | } 84 | //如果fac==1 && res==RIGHT,那么前一个结果的最后变量还在this->tempvar.prev_temp_varname不动 85 | //这样一来,this->tempvar.prev_temp_varname就始终代表前一个变量或是值了 86 | //然后,我们把this->tempvar.prev_temp_varname保存在oper1里,因为等会还要调用item函数,this->tempvar.prev_temp_varname将会被替换 87 | oper1=this->tempvar.prev_temp_varname; 88 | break; 89 | } 90 | 91 | while(type=lexical_analyzer.peeksymtype(),type==PLUS || type==MINUS) 92 | { 93 | if(lexical_analyzer.getsymtype(),!(tmp_res=item(lexical_analyzer,tmp_value))) return ERROR; 94 | 95 | else if(tmp_res==VALUE && tmp_value==0) 96 | { 97 | this->tempvar.prev_temp_varname=oper1;//抛弃0这个结果 98 | continue;//对于加减法,如果 加/减 数为0,不再继续做下去,直接下一轮迭代。 99 | } 100 | 101 | else if(res==VALUE && tmp_res==VALUE) 102 | { 103 | if(type==PLUS) value+=tmp_value; 104 | else /*if(type==MINUS)*/ value-=tmp_value; 105 | //我们必须继续保持oper1为前一个操作数不变,必须继续保持,希望不要在哪里忘记掉 106 | sprintf(buffer,"%d",value); 107 | this->tempvar.prev_temp_varname=oper1=buffer;//我们还要让this->tempvar.prev_temp_varname也为最新的value, 108 | //万一在这里结束,this->tempvar.prev_temp_varname里能够保存本函数最后的结果值 109 | } 110 | else 111 | { 112 | //对于一旦出现res还是VALUE而tmp_res已不是VALUE的情况,将会保存res为一临时变量,然后让这个临时变量参与接下来一切计算 113 | if(res==VALUE /* && tmp_res==RIGHT*/) 114 | { 115 | res=RIGHT; 116 | 117 | newcodenode.command=(type==PLUS?PLUSOPER:MINUSOPER);//PLUS OR MINUS 118 | newcodenode.oper1=oper1; 119 | newcodenode.oper2=this->tempvar.prev_temp_varname; 120 | if(SyntacticAnalyzer::TempVar::isTempVar(this->tempvar.prev_temp_varname)) newcodenode.oper3=this->tempvar.prev_temp_varname; 121 | else newcodenode.oper3=this->tempvar.next(); 122 | 123 | this->intermediate_code_deque.push_back(newcodenode); 124 | this->tempvar.prev_temp_varname=oper1=newcodenode.oper3; 125 | } 126 | else if(tmp_res==VALUE /*&& res==RIGHT*/) 127 | { 128 | if(type==PLUS) 129 | { 130 | some_value_to_optimize+=tmp_value; 131 | } 132 | else /*if(type==MINUS)*/ 133 | { 134 | some_value_to_optimize-=tmp_value; 135 | } 136 | } 137 | else 138 | { 139 | newcodenode.command=(type==PLUS?PLUSOPER:MINUSOPER);//不是PLUS就是MINUS 140 | newcodenode.oper1=oper1; 141 | newcodenode.oper2=this->tempvar.prev_temp_varname; //item的结果,可能是值。注意,即使是返回值,this->tempvar.prev_temp_varname内也必须是结果值的字符串 142 | //调用他的函数不应为此负责,简化下代码 143 | //由于非常复杂,可能出现的情况太多,这里仅仅依靠前缀来判断是否是临时变量,如果是临时变量就是可以修改的。这里关键是不能修改掉用户定义的变量常量或是值 144 | if(SyntacticAnalyzer::TempVar::isTempVar(newcodenode.oper1)) newcodenode.oper3=newcodenode.oper1; 145 | else if(SyntacticAnalyzer::TempVar::isTempVar(newcodenode.oper2)) newcodenode.oper3=newcodenode.oper2; 146 | else newcodenode.oper3=this->tempvar.next(); 147 | 148 | this->intermediate_code_deque.push_back(newcodenode); 149 | this->tempvar.prev_temp_varname=oper1=newcodenode.oper3; //oper1和this->tempvar.prev_temp_varname同时保存前一个结果,一个给函数返回以后使用,一个给下一个循环使用 150 | } 151 | } 152 | } 153 | 154 | if(some_value_to_optimize!=0) 155 | { 156 | newcodenode.command=PLUSOPER; 157 | newcodenode.oper1=oper1; 158 | sprintf(buffer,"%d",some_value_to_optimize); 159 | newcodenode.oper2=buffer; 160 | if(SyntacticAnalyzer::TempVar::isTempVar(oper1)) newcodenode.oper3=oper1; 161 | else newcodenode.oper3=this->tempvar.next(); 162 | 163 | this->intermediate_code_deque.push_back(newcodenode); 164 | this->tempvar.prev_temp_varname=newcodenode.oper3; 165 | } 166 | 167 | 168 | return res; 169 | } 170 | 171 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::item(LexicalAnalyzer& lexical_analyzer,int& value) 172 | { 173 | SyntacticAnalyzer::SyntacticAnalyzerResult res=RIGHT,tmp_res=RIGHT; 174 | SyntacticAnalyzer::IntermediateCodeNode newcodenode; 175 | int tmp_value,some_value_to_optimize=1/*乘除法这里是1,加减法是0*/; 176 | bool stop_optimizing=false;//当出现第一个除法时,立即停止优化。 177 | std::string type,oper1; 178 | char buffer[VALUEBUFFERLENGTH]; 179 | 180 | for(;;) 181 | { 182 | if(!(res=factor(lexical_analyzer,value))) return ERROR; 183 | else if(res==VALUE && value==1 && lexical_analyzer.peeksymtype()==TIMES) 184 | { 185 | lexical_analyzer.getsymtype(); 186 | continue; 187 | } 188 | else/*if(res==VALUE || res==RIGHT)*/ 189 | {//和前面一样,我们把factor的结果放在oper1里,小心翼翼的维护他。 190 | //但这里还比前面简单,完全不需要对res的处理,好爽好爽~~ 191 | oper1=this->tempvar.prev_temp_varname; 192 | } 193 | //如果能走到这一步,res只会是RIGHT或VALUE 194 | //和前面一样,oper1和this->tempvar.prev_temp_varname同时保持最新结果,一个给返回后使用,一个给接下来的迭代使用 195 | break; 196 | } 197 | 198 | while(type=lexical_analyzer.peeksymtype(),type==TIMES || type==SLASH) 199 | { 200 | if(lexical_analyzer.getsymtype(),!(tmp_res=factor(lexical_analyzer,tmp_value))) return ERROR; 201 | //如果能走到这一步,tmp_res只会是RIGHT或VALUE 202 | else if(tmp_res==VALUE && tmp_value==1) 203 | { 204 | this->tempvar.prev_temp_varname=oper1;//抛弃1这个结果 205 | continue;//对于乘除法,如果 乘/除 数为1,不再继续做下去,直接下一轮迭代。 206 | } 207 | 208 | else if(res==VALUE && tmp_res==VALUE) 209 | { 210 | if(type==TIMES) value*=tmp_value; 211 | else/* if(type==SLASH)*/ value/=tmp_value; 212 | sprintf(buffer,"%d",value); 213 | this->tempvar.prev_temp_varname=oper1=buffer;//继续保持 偶也~~ 214 | } 215 | else 216 | { 217 | if(type==SLASH) 218 | { 219 | stop_optimizing=true; 220 | if(some_value_to_optimize!=1) 221 | { 222 | newcodenode.command=TIMESOPER; 223 | newcodenode.oper1=oper1; 224 | sprintf(buffer,"%d",some_value_to_optimize); 225 | newcodenode.oper2=buffer; 226 | if(SyntacticAnalyzer::TempVar::isTempVar(oper1)) newcodenode.oper3=oper1; 227 | else newcodenode.oper3=this->tempvar.next(); 228 | 229 | this->intermediate_code_deque.push_back(newcodenode); 230 | some_value_to_optimize=1; 231 | } 232 | } 233 | //破处~~ 234 | if(res==VALUE /*&& tmp_res==RIGHT*/) 235 | { 236 | res=RIGHT;//只要有一次tmp_res不是VALUE,那么对value的计算毫无意义,使res=RIGHT来避免此计算 237 | 238 | newcodenode.command=(type==TIMES?TIMESOPER:SLASHOPER);//TIMES OR SLASH 239 | newcodenode.oper1=oper1; 240 | newcodenode.oper2=this->tempvar.prev_temp_varname; 241 | if(SyntacticAnalyzer::TempVar::isTempVar(this->tempvar.prev_temp_varname)) newcodenode.oper3=this->tempvar.prev_temp_varname; 242 | else newcodenode.oper3=this->tempvar.next(); 243 | 244 | this->intermediate_code_deque.push_back(newcodenode); 245 | this->tempvar.prev_temp_varname=oper1=newcodenode.oper3;//保持保持~~ 246 | } 247 | else if(tmp_res==VALUE && stop_optimizing==false /* && res=RIGHT*/) 248 | {//既然tmp_res是个值,证明还有优化的潜能,我们把值放进some_value_to_optimize里,并在最后把它作为一条指令放进结果中 249 | some_value_to_optimize*=tmp_value; 250 | } 251 | else 252 | { 253 | newcodenode.command=(type==TIMES?TIMESOPER:SLASHOPER);//TIMES or SLASH 254 | newcodenode.oper1=oper1; 255 | newcodenode.oper2=this->tempvar.prev_temp_varname; 256 | 257 | if(SyntacticAnalyzer::TempVar::isTempVar(newcodenode.oper1)) newcodenode.oper3=newcodenode.oper1; 258 | else if(SyntacticAnalyzer::TempVar::isTempVar(newcodenode.oper2)) newcodenode.oper3=newcodenode.oper2; 259 | else newcodenode.oper3=this->tempvar.next(); 260 | 261 | this->intermediate_code_deque.push_back(newcodenode); 262 | this->tempvar.prev_temp_varname=oper1=newcodenode.oper3;//保持保持~~ 263 | } 264 | } 265 | } 266 | 267 | if(some_value_to_optimize!=1) 268 | { 269 | newcodenode.command=TIMESOPER; 270 | newcodenode.oper1=oper1; 271 | sprintf(buffer,"%d",some_value_to_optimize); 272 | newcodenode.oper2=buffer; 273 | if(SyntacticAnalyzer::TempVar::isTempVar(oper1)) newcodenode.oper3=oper1; 274 | else newcodenode.oper3=this->tempvar.next(); 275 | 276 | this->intermediate_code_deque.push_back(newcodenode); 277 | this->tempvar.prev_temp_varname=newcodenode.oper3; 278 | } 279 | 280 | return res; 281 | } 282 | 283 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::factor(LexicalAnalyzer& lexical_analyzer,int& value) 284 | { 285 | SyntacticAnalyzer::SyntacticAnalyzerResult res=RIGHT; 286 | std::string type=lexical_analyzer.getsymtype(); 287 | std::string word=lexical_analyzer.getprevsymword(); 288 | std::deque::const_iterator iter; 289 | char buffer[VALUEBUFFERLENGTH]; 290 | 291 | if(type!=IDENT && type!=NUMBER && type!=LPAREN) 292 | { 293 | this->errorinfo="这里应该是一个标识符或是一个数字或是一个表达式"; 294 | return ERROR; 295 | } 296 | 297 | else if(type==NUMBER) 298 | { 299 | this->tempvar.prev_temp_varname=word;//this->tempvar.prev_temp_varname必须保持最新结果,无论接下来是不是返回值 300 | sscanf(word.c_str(),"%d",&value); 301 | return VALUE; 302 | } 303 | 304 | else if(type==IDENT) 305 | { 306 | if((iter=this->ident_stack_find(word.c_str()))==this->ident_stack.end()) 307 | { 308 | this->errorinfo="找不到这个标识符哦,它确实已经定义了吗?"; 309 | return ERROR; 310 | } 311 | else if(iter->flag==CONST) 312 | { 313 | value=iter->value; 314 | sprintf(buffer,"%d",value); 315 | this->tempvar.prev_temp_varname=buffer; 316 | return VALUE; 317 | } 318 | else this->tempvar.prev_temp_varname=word; 319 | } 320 | 321 | else /*if(type==LPAREN)*/ 322 | { 323 | if(!(res=expression(lexical_analyzer,value))) return ERROR; 324 | if(lexical_analyzer.getsymtype()!=RPAREN) 325 | { 326 | this->errorinfo="这里应该有一个右括号,表达式必须用一对括号扩起来"; 327 | return ERROR; 328 | } 329 | } 330 | return res; 331 | } 332 | 333 | -------------------------------------------------------------------------------- /CompilePrinciple 5/func_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUNC_LIB_H 2 | #define __FUNC_LIB_H 3 | 4 | #define CHAR_CHARACTER 1 5 | #define CHAR_NUMBER 2 6 | #define CHAR_OTHER 3 7 | #define CHAR_NULL 4 8 | 9 | inline 10 | int judge_char_type(char c) 11 | { 12 | if(c==' '||c=='\t'||c=='\n') return CHAR_NULL; 13 | else if( (c>='A'&&c<='Z') || (c>='a'&&c<='z') ) return CHAR_CHARACTER; 14 | else if( c>='0'&&c<='9' ) return CHAR_NUMBER; 15 | else return CHAR_OTHER; 16 | } 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /CompilePrinciple 5/getsym.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"func_lib.h" 4 | #include"LexicalAnalyzer.class.h" 5 | #include"wordlist.h" 6 | 7 | bool LexicalAnalyzer::getsym(std::string &word,std::string &word_type) 8 | { 9 | char c; 10 | int c_type; 11 | const int WORD_MAX_LENGTH=10; 12 | const int NUM_MAX_LENGTH=14; 13 | word=word_type=""; 14 | 15 | do 16 | { 17 | if((c=this->inputreader->getchar())<=0) return false; 18 | c_type=judge_char_type(c); 19 | } 20 | while(c_type==CHAR_NULL); 21 | 22 | this->symnumchars.push_back(this->inputreader->get_curchar()); 23 | this->symnumlines.push_back(this->inputreader->get_curline()); 24 | 25 | if(c_type==CHAR_CHARACTER) 26 | { 27 | word+=c; 28 | while(word.size()inputreader->peekchar(); 31 | c_type=judge_char_type(c); 32 | if(c_type!=CHAR_CHARACTER && c_type!=CHAR_NUMBER) break; 33 | c=this->inputreader->getchar(); 34 | word+=c; 35 | } 36 | 37 | word_type=getKeyword(word); 38 | if(word_type.size()==0) 39 | { 40 | word_type=IDENT; 41 | } 42 | } 43 | else if(c_type==CHAR_NUMBER) 44 | { 45 | word+=c; 46 | while(word.size()inputreader->peekchar(); 49 | c_type=judge_char_type(c); 50 | if(c_type!=CHAR_NUMBER) break; 51 | c=this->inputreader->getchar(); 52 | word+=c; 53 | } 54 | word_type=NUMBER; 55 | } 56 | else/*if(c_type==CHAR_OTHER)*/ 57 | { 58 | word=c; 59 | switch(c) 60 | { 61 | case ':': 62 | case '>': 63 | case '<': 64 | if(this->inputreader->peekchar()=='=') 65 | { 66 | word+=this->inputreader->getchar(); 67 | } 68 | break; 69 | } 70 | 71 | word_type=get_operator_name(word); 72 | //if(word_type.size()==0) error 73 | } 74 | return true; 75 | } 76 | -------------------------------------------------------------------------------- /CompilePrinciple 5/keyword.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | #include"keywordlist.h" 6 | #define KEYWORD_LENGTH 13 7 | 8 | std::string LexicalAnalyzer::getKeyword(std::string str) const 9 | { 10 | static const std::pair KEYWORDS_ARRAY[]={ std::make_pair("if",IFSYM), 11 | std::make_pair("then",THENSYM), 12 | std::make_pair("while",WHILESYM), 13 | std::make_pair("do",DOSYM), 14 | std::make_pair("read",READSYM), 15 | std::make_pair("write",WRITESYM), 16 | std::make_pair("call",CALLSYM), 17 | std::make_pair("begin",BEGINSYM), 18 | std::make_pair("end",ENDSYM), 19 | std::make_pair("const",CONSTSYM), 20 | std::make_pair("var",VARSYM), 21 | std::make_pair("procedure",PROCSYM), 22 | std::make_pair("odd",ODDSYM)}; 23 | 24 | static const std::map KEYWORDS(KEYWORDS_ARRAY,KEYWORDS_ARRAY+KEYWORD_LENGTH); 25 | 26 | for(int i=0;i::const_iterator iter=KEYWORDS.find(str); 28 | if(iter!=KEYWORDS.end()) return iter->second; 29 | else return ""; 30 | } 31 | -------------------------------------------------------------------------------- /CompilePrinciple 5/keywordlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYWORD_H 2 | #define __KEYWORD_H 3 | 4 | #define IFSYM "if" 5 | #define THENSYM "then" 6 | #define WHILESYM "while" 7 | #define DOSYM "do" 8 | #define READSYM "read" 9 | #define WRITESYM "write" 10 | #define CALLSYM "call" 11 | #define BEGINSYM "begin" 12 | #define ENDSYM "end" 13 | #define CONSTSYM "const" 14 | #define VARSYM "var" 15 | #define PROCSYM "proc" 16 | #define ODDSYM "odd" 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /CompilePrinciple 5/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | #include"SyntacticAnalyzer.class.h" 6 | 7 | int main(int argc,char* argv[]) 8 | { 9 | LexicalAnalyzer lexical_analyzer; 10 | SyntacticAnalyzer syntactic_analyzer; 11 | std::string outputfilename="",inputfilename=""; 12 | int i; 13 | 14 | for(i=1;i 2 | #include 3 | #include"LexicalAnalyzer.class.h" 4 | #include"operatorlist.h" 5 | #define OPERATOR_LENGTH 16 6 | 7 | std::string LexicalAnalyzer::get_operator_name(const std::string& str) const 8 | { 9 | static const std::pair OPERATORS_ARRAY[]={ std::make_pair(BECOMESOPER,BECOMES), 10 | std::make_pair(GEQOPER,GEQ), 11 | std::make_pair(GTROPER,GTR), 12 | std::make_pair(LEQOPER,LEQ), 13 | std::make_pair(LSSOPER,LSS), 14 | std::make_pair(PLUSOPER,PLUS), 15 | std::make_pair(MINUSOPER,MINUS), 16 | std::make_pair(TIMESOPER,TIMES), 17 | std::make_pair(SLASHOPER,SLASH), 18 | std::make_pair(EQLOPER,EQL), 19 | std::make_pair(NEQOPER,NEQ), 20 | std::make_pair(COMMAOPER,COMMA), 21 | std::make_pair(PERIODOPER,PERIOD), 22 | std::make_pair(SEMICOLONOPER,SEMICOLON), 23 | std::make_pair(LPARANOPER,LPAREN), 24 | std::make_pair(RPARANOPER,RPAREN)}; 25 | 26 | static const std::map OPERATORS(OPERATORS_ARRAY,OPERATORS_ARRAY+OPERATOR_LENGTH); 27 | 28 | std::map::const_iterator iter=OPERATORS.find(str); 29 | if(iter!=OPERATORS.end()) return iter->second; 30 | else return ""; 31 | } 32 | -------------------------------------------------------------------------------- /CompilePrinciple 5/operatorlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __OPERATORLIST_H 2 | #define __OPERATORLIST_H 3 | 4 | #define BECOMES "becomes" 5 | #define GEQ "geq" 6 | #define GTR "gtr" 7 | #define LEQ "leq" 8 | #define LSS "lss" 9 | #define PLUS "plus" 10 | #define MINUS "minus" 11 | #define TIMES "times" 12 | #define SLASH "slash" 13 | #define EQL "eql" 14 | #define NEQ "neq" 15 | #define COMMA "comma" 16 | #define PERIOD "period" 17 | #define SEMICOLON "semicolon" 18 | #define LPAREN "lparen" 19 | #define RPAREN "rparen" 20 | 21 | #define BECOMESOPER ":=" 22 | #define GEQOPER ">=" 23 | #define GTROPER ">" 24 | #define LEQOPER "<=" 25 | #define LSSOPER "<" 26 | #define PLUSOPER "+" 27 | #define MINUSOPER "-" 28 | #define TIMESOPER "*" 29 | #define SLASHOPER "/" 30 | #define EQLOPER "=" 31 | #define NEQOPER "#" 32 | #define COMMAOPER "," 33 | #define PERIODOPER "." 34 | #define SEMICOLONOPER ";" 35 | #define LPARANOPER "(" 36 | #define RPARANOPER ")" 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /CompilePrinciple 5/program.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"keywordlist.h" 5 | #include"operatorlist.h" 6 | #include"wordlist.h" 7 | 8 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::analyze(LexicalAnalyzer& lexical_analyzer) 9 | { 10 | if(!subprogram(lexical_analyzer)) return ERROR; 11 | if(lexical_analyzer.peeksymtype()!=PERIOD) 12 | { 13 | if(lexical_analyzer.peeksymtype()!="") this->errorinfo="程序有错,这个程序到这里看上去应该已经结束了,但其实不是。是不是少了运算符或漏了左括号?"; 14 | else this->errorinfo="必须在程序结尾加一个句号,不要问我为神马,这就是语法!"; 15 | return ERROR; 16 | } 17 | return RIGHT; 18 | } 19 | 20 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::subprogram(LexicalAnalyzer& lexical_analyzer) 21 | { 22 | SyntacticAnalyzer::SyntacticAnalyzerResult res; 23 | std::string type=lexical_analyzer.peeksymtype(); 24 | this->ident_stack.push_back(SyntacticAnalyzer::IdentStackNode(BOUND)); 25 | if(type==CONSTSYM) 26 | { 27 | if(!constsym(lexical_analyzer)) return ERROR; 28 | type=lexical_analyzer.peeksymtype(); 29 | } 30 | if(type==VARSYM) 31 | { 32 | if(!varsym(lexical_analyzer)) return ERROR; 33 | type=lexical_analyzer.peeksymtype(); 34 | } 35 | if(type==PROCSYM) 36 | { 37 | do 38 | { 39 | if(!procsym(lexical_analyzer)) return ERROR; 40 | }while((type=lexical_analyzer.peeksymtype())==PROCSYM); 41 | } 42 | if((res=statement(lexical_analyzer))!=ERROR) 43 | { 44 | this->ident_stack_clear(); 45 | } 46 | return res; 47 | } 48 | 49 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::constsym(LexicalAnalyzer& lexical_analyzer) 50 | { 51 | std::string word; 52 | SyntacticAnalyzer::IdentStackNode newnode(CONST); 53 | if(lexical_analyzer.getsymtype()!=CONSTSYM) 54 | { 55 | this->errorinfo="这里应该是一个const语句"; 56 | return ERROR; 57 | } 58 | do 59 | { 60 | if(lexical_analyzer.getsymtype()!=IDENT) 61 | { 62 | this->errorinfo="这里应该是一个标识符,例如:CONST X=6,Y=4;"; 63 | return ERROR; 64 | } 65 | else if(this->ident_stack_find(lexical_analyzer.getprevsymword().c_str())!=this->ident_stack.end()) 66 | { 67 | this->errorinfo="我说,常量名好像有重复啊,你检查下,看看本级的,上一级的常量或者变量有没有叫这名儿的"; 68 | return ERROR; 69 | } 70 | else newnode.ident=lexical_analyzer.getprevsymword(); 71 | 72 | if(lexical_analyzer.getsymtype()!=EQL) 73 | { 74 | this->errorinfo="这里应该是一个等于符号,例如:CONST X=6,Y=4;"; 75 | return ERROR; 76 | } 77 | if(lexical_analyzer.getsymtype()!=NUMBER) 78 | { 79 | this->errorinfo="这里应该是一个数字,例如:CONST X=6,Y=4;"; 80 | return ERROR; 81 | } 82 | else 83 | { 84 | sscanf(lexical_analyzer.getprevsymword().c_str(),"%d",&newnode.value); 85 | this->ident_stack.push_back(newnode); 86 | } 87 | }while((word=lexical_analyzer.getsymtype())==COMMA); 88 | 89 | if(word==SEMICOLON) return RIGHT; 90 | else 91 | { 92 | this->errorinfo="const语句必须以分号结尾,例如:CONST X=6,Y=4; 请留意末尾的分号"; 93 | return ERROR; 94 | } 95 | } 96 | 97 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::varsym(LexicalAnalyzer& lexical_analyzer) 98 | { 99 | std::string word; 100 | SyntacticAnalyzer::IdentStackNode newnode(VAR); 101 | if(lexical_analyzer.getsymtype()!=VARSYM) 102 | { 103 | this->errorinfo="这里应该是一个var语句"; 104 | return ERROR; 105 | } 106 | do 107 | { 108 | if(lexical_analyzer.getsymtype()!=IDENT) 109 | { 110 | this->errorinfo="这里应该是一个标识符,例如:VAR X,Y,Z;"; 111 | return ERROR; 112 | } 113 | else if(this->ident_stack_find(lexical_analyzer.getprevsymword().c_str())!=this->ident_stack.end()) 114 | { 115 | this->errorinfo="我说,变量名好像有重复啊,你检查下,看看本级的,上一级的变量或者常量有没有叫这名儿的"; 116 | return ERROR; 117 | } 118 | else 119 | { 120 | 121 | newnode.ident=lexical_analyzer.getprevsymword(); 122 | this->ident_stack.push_back(newnode); 123 | } 124 | }while((word=lexical_analyzer.getsymtype())==COMMA); 125 | if(word==SEMICOLON) return RIGHT; 126 | else 127 | { 128 | this->errorinfo="var语句必须以分号结尾,例如:VAR X,Y,Z; 请留意末尾的分号"; 129 | return ERROR; 130 | } 131 | } 132 | 133 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::procsym(LexicalAnalyzer& lexical_analyzer) 134 | { 135 | std::string word; 136 | if(lexical_analyzer.getsymtype()!=PROCSYM) 137 | { 138 | this->errorinfo="这里应该是一个procedure语句"; 139 | return ERROR; 140 | } 141 | 142 | if(lexical_analyzer.getsymtype()!=IDENT) 143 | { 144 | this->errorinfo="这里应该有一个标识符,作为procedure的名字,例如:PROCEDURE PROC;"; 145 | return ERROR; 146 | } 147 | else if((this->procedure_set.find(word=lexical_analyzer.getprevsymword()))!=this->procedure_set.end()) 148 | { 149 | this->errorinfo="过程名好像重复了耶!要记住哦,PL/0不能出现重复的过程名哦!一定不能重复哦!乖!"; 150 | return ERROR; 151 | } 152 | else this->procedure_set.insert(word);//0 is temp value... 153 | 154 | if(lexical_analyzer.getsymtype()!=SEMICOLON) 155 | { 156 | this->errorinfo="这里应该有一个分号,作为procedure声明和内容的分隔符,例如:PROCEDURE PROC; 请留意末尾的分号"; 157 | return ERROR; 158 | } 159 | if(!subprogram(lexical_analyzer)) return ERROR; 160 | if(lexical_analyzer.getsymtype()!=SEMICOLON) 161 | { 162 | this->errorinfo="这里应该有一个分号,作为一个procedure结束,我知道加一个分号很无聊也不能促进减肥,但是这是语法,是规定,只要你爸不是李刚,就必需遵守这个规定"; 163 | return ERROR; 164 | } 165 | return RIGHT; 166 | } 167 | -------------------------------------------------------------------------------- /CompilePrinciple 5/statement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"keywordlist.h" 5 | #include"operatorlist.h" 6 | #include"wordlist.h" 7 | 8 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::statement(LexicalAnalyzer& lexical_analyzer) 9 | { 10 | std::string type=lexical_analyzer.peeksymtype(); 11 | if(type==IDENT) return ident(lexical_analyzer); 12 | if(type==CALLSYM) return callsym(lexical_analyzer); 13 | if(type==BEGINSYM) return beginsym(lexical_analyzer); 14 | if(type==IFSYM) return ifsym(lexical_analyzer); 15 | if(type==WHILESYM) return whilesym(lexical_analyzer); 16 | if(type==READSYM || type==WRITESYM) return readwritesym(lexical_analyzer); 17 | 18 | return RIGHT; 19 | } 20 | 21 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::ident(LexicalAnalyzer& lexical_analyzer) 22 | { 23 | int value; 24 | std::deque::const_iterator iter; 25 | if(lexical_analyzer.getsymtype()!=IDENT) 26 | { 27 | this->errorinfo="这里应该有一个标识符,参考赋值语句的语法:X:=2;"; 28 | return ERROR; 29 | } 30 | else if((iter=this->ident_stack_find(lexical_analyzer.getprevsymword().c_str()))==this->ident_stack.end()) 31 | { 32 | this->errorinfo="找不到这个标识符哦,它确实已经定义了吗?"; 33 | return ERROR; 34 | } 35 | else if(iter->flag!=VAR) 36 | { 37 | this->errorinfo="喂喂喂!这不是变量,是常量吧!你怎么能对常量赋值呢??"; 38 | return ERROR; 39 | } 40 | 41 | if(lexical_analyzer.getsymtype()!=BECOMES) 42 | { 43 | this->errorinfo="这里应该是一个赋值符号 := ,参考赋值语句的语法:X:=2;"; 44 | return ERROR; 45 | } 46 | return expression(lexical_analyzer,value); 47 | } 48 | 49 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::callsym(LexicalAnalyzer& lexical_analyzer) 50 | { 51 | if(lexical_analyzer.getsymtype()!=CALLSYM) 52 | { 53 | this->errorinfo="这里应该是一个call语句,call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 54 | return ERROR; 55 | } 56 | 57 | if(lexical_analyzer.getsymtype()!=IDENT) 58 | { 59 | this->errorinfo="这个应该是一个标识符,否则我怎么知道你要call谁?call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 60 | return ERROR; 61 | } 62 | else if(this->procedure_set.find(lexical_analyzer.getprevsymword())==this->procedure_set.end()) 63 | { 64 | this->errorinfo="这神马过程啊,我真的不认识这货!"; 65 | return ERROR; 66 | } 67 | 68 | return RIGHT; 69 | } 70 | 71 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::beginsym(LexicalAnalyzer& lexical_analyzer) 72 | { 73 | if(lexical_analyzer.getsymtype()!=BEGINSYM) 74 | { 75 | this->errorinfo="这里应该有一个begin语句的吧"; 76 | return ERROR; 77 | } 78 | if(!statement(lexical_analyzer)) return ERROR; 79 | while(lexical_analyzer.peeksymtype()!=ENDSYM) 80 | { 81 | if(lexical_analyzer.getsymtype()!=SEMICOLON) 82 | { 83 | this->errorinfo="这里必须有一个分号的啊,如果BEGIN..END语句中有多于一句语句的话,每句语句都必须用分号分隔"; 84 | return ERROR; 85 | } 86 | if(!statement(lexical_analyzer)) return ERROR; 87 | } 88 | lexical_analyzer.getsymtype(); 89 | return RIGHT; 90 | } 91 | 92 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::ifsym(LexicalAnalyzer& lexical_analyzer) 93 | { 94 | bool value; 95 | if(lexical_analyzer.getsymtype()!=IFSYM) 96 | { 97 | this->errorinfo="这里应该是一个if语句"; 98 | return ERROR; 99 | } 100 | if(!condition(lexical_analyzer,value)) return ERROR; 101 | if(lexical_analyzer.getsymtype()!=THENSYM) 102 | { 103 | this->errorinfo="喂喂..if语句没有跟then,你这个if语句是干啥的?if语句参考语法:IF X=0 THEN X:=1;"; 104 | return ERROR; 105 | } 106 | return statement(lexical_analyzer); 107 | } 108 | 109 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::whilesym(LexicalAnalyzer& lexical_analyzer) 110 | { 111 | bool value; 112 | if(lexical_analyzer.getsymtype()!=WHILESYM) 113 | { 114 | this->errorinfo="这里应该是一个while语句"; 115 | return ERROR; 116 | } 117 | if(!condition(lexical_analyzer,value)) return ERROR; 118 | if(lexical_analyzer.getsymtype()!=DOSYM) 119 | { 120 | this->errorinfo="这里应该有一个do的,没有do,单单一个while有神马意义呢?"; 121 | return ERROR; 122 | } 123 | return statement(lexical_analyzer); 124 | } 125 | 126 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::readwritesym(LexicalAnalyzer& lexical_analyzer) 127 | { 128 | std::string type1=lexical_analyzer.getsymtype(),type2; 129 | std::deque::const_iterator iter; 130 | if(type1!=READSYM && type1!=WRITESYM) 131 | { 132 | this->errorinfo="这里应该是一个函数"; 133 | return ERROR; 134 | } 135 | if(lexical_analyzer.getsymtype()!=LPAREN) 136 | { 137 | this->errorinfo="这是函数诶!他的语法应该是 READ(X); 或者 WRITE(Y); 吧,你貌似漏了左括号"; 138 | return ERROR; 139 | } 140 | do{ 141 | if(lexical_analyzer.getsymtype()!=IDENT) 142 | { 143 | this->errorinfo="函数里面要有标识符的啊,他的语法应该是 READ(X); 或是 WRITE(A,B,C);"; 144 | return ERROR; 145 | } 146 | else if((iter=this->ident_stack_find(lexical_analyzer.getprevsymword().c_str()))==this->ident_stack.end()) 147 | { 148 | this->errorinfo="找不到这个标识符哦,它确实已经定义了吗?"; 149 | return ERROR; 150 | } 151 | else if(type1==READSYM && iter->flag!=VAR) 152 | { 153 | this->errorinfo="喂喂喂!这不是变量,是常量吧!你怎么能对常量赋值呢??"; 154 | return ERROR; 155 | } 156 | }while((type2=lexical_analyzer.getsymtype())==COMMA); 157 | if(type2==RPAREN) return RIGHT; 158 | else 159 | { 160 | this->errorinfo="函数参数要用右括号扩起来的啊,你加右括号了吗"; 161 | return ERROR; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /CompilePrinciple 5/wordlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __WORDLIST_H 2 | #define __WORDLIST_H 3 | 4 | #define IDENT "ident" 5 | #define NUMBER "number" 6 | 7 | #endif 8 | 9 | -------------------------------------------------------------------------------- /CompilePrincipleInterpreter/CompilePrincipleInterpreter.class.cpp: -------------------------------------------------------------------------------- 1 | #include"CompilePrincipleInterpreter.class.h" 2 | #include"../keywordlist.h" 3 | #include"../operatorlist.h" 4 | #include"../intermediatecodelist.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #define COUNT_OPER 4 12 | 13 | #define ISNUM(VARNAME) ((VARNAME[0]>='0' && VARNAME[0]<='9')||(VARNAME[0]=='-' && VARNAME[1]>='0' && VARNAME[1]<='9')) 14 | 15 | #define SETOPERVAL int oper1_val,oper2_val;\ 16 | {\ 17 | if(ISNUM(oper1)) sscanf(oper1.c_str(),"%d",&oper1_val);\ 18 | else oper1_val=this->get_var(oper1);\ 19 | \ 20 | if(ISNUM(oper2)) sscanf(oper2.c_str(),"%d",&oper2_val);\ 21 | else oper2_val=this->get_var(oper2);\ 22 | } 23 | 24 | #define ARITHMETICS(OPER)\ 25 | {\ 26 | SETOPERVAL\ 27 | this->set_var(oper3,oper1_val OPER oper2_val);\ 28 | ++this->ip;\ 29 | } 30 | 31 | #define CONDITION(OPER)\ 32 | {\ 33 | SETOPERVAL\ 34 | if(oper1_val OPER oper2_val)\ 35 | {\ 36 | ++this->ip;\ 37 | }\ 38 | else\ 39 | {\ 40 | this->ip=this->point_map.find(point)->second;\ 41 | }\ 42 | }\ 43 | 44 | void CompilePrincipleInterpreter::interpreter(const std::string& filename) 45 | { 46 | std::ifstream file(filename.c_str(),std::ios::in); 47 | std::string file_row,oper[COUNT_OPER]; 48 | int start,end,found,i; 49 | 50 | if(file.fail()) 51 | { 52 | std::cerr << filename << ": 文件打开错误" << std::endl; 53 | return; 54 | } 55 | 56 | while(std::getline(file,file_row)) 57 | { 58 | start=file_row.find_first_of(LPARAN); 59 | if(start==std::string::npos) 60 | { 61 | if((end=file_row.find_last_of(COLON))!=std::string::npos) 62 | { 63 | this->collect_point(file_row.substr(0,end),this->code_stack.size()); 64 | } 65 | continue; 66 | } 67 | end=file_row.find_last_of(RPARAN); 68 | if(end==std::string::npos) continue; 69 | 70 | for(i=0;(found=file_row.find_first_of(DELIMITER,++start))!=std::string::npos && icode_stack.push_back(CompilePrincipleInterpreter::IntermediateCodeNode(oper[0],oper[1],oper[2],oper[3])); 78 | } 79 | file.close(); 80 | 81 | while(this->ipcode_stack.size()) 82 | { 83 | this->command(this->code_stack[this->ip].command, 84 | this->code_stack[this->ip].oper1, 85 | this->code_stack[this->ip].oper2, 86 | this->code_stack[this->ip].oper3); 87 | } 88 | } 89 | 90 | void CompilePrincipleInterpreter::collect_point(const std::string& row,const int ip) 91 | { 92 | this->point_map.insert(std::make_pair(row,ip)); 93 | } 94 | 95 | void CompilePrincipleInterpreter::command(const std::string& command, const std::string& oper1, const std::string& oper2, const std::string& oper3) 96 | { 97 | #ifdef DISPLAY 98 | std::cout << command << ' ' << oper1 << ' ' << oper2 << ' ' << oper3 << std::endl; 99 | #endif 100 | if(command==VARSYM) 101 | { 102 | var(oper1); 103 | } 104 | else if(command==BECOMESOPER) 105 | { 106 | becomes(oper1,oper2); 107 | } 108 | else if(command==READSYM) 109 | { 110 | read(oper1); 111 | } 112 | else if(command==WRITESYM) 113 | { 114 | write(oper1); 115 | } 116 | else if(command==PLUSOPER) 117 | { 118 | plus(oper1,oper2,oper3); 119 | } 120 | else if(command==MINUSOPER) 121 | { 122 | minus(oper1,oper2,oper3); 123 | } 124 | else if(command==TIMESOPER) 125 | { 126 | times(oper1,oper2,oper3); 127 | } 128 | else if(command==SLASHOPER) 129 | { 130 | slash(oper1,oper2,oper3); 131 | } 132 | else if(command==ODDSYM) 133 | { 134 | odd(oper1,oper2); 135 | } 136 | else if(command==JUMP) 137 | { 138 | jump(oper1); 139 | } 140 | else if(command==GEQOPER) 141 | { 142 | geq(oper1,oper2,oper3); 143 | } 144 | else if(command==GTROPER) 145 | { 146 | gtr(oper1,oper2,oper3); 147 | } 148 | else if(command==LEQOPER) 149 | { 150 | leq(oper1,oper2,oper3); 151 | } 152 | else if(command==LSSOPER) 153 | { 154 | lss(oper1,oper2,oper3); 155 | } 156 | else if(command==EQLOPER) 157 | { 158 | eql(oper1,oper2,oper3); 159 | } 160 | else if(command==NEQOPER) 161 | { 162 | neq(oper1,oper2,oper3); 163 | } 164 | else if(command==CALLSYM) 165 | { 166 | call(oper1); 167 | } 168 | else if(command==RETURN) 169 | { 170 | ret(); 171 | } 172 | else if(command==HALT) 173 | { 174 | this->ip=this->code_stack.size(); 175 | } 176 | } 177 | 178 | void CompilePrincipleInterpreter::var(const std::string& varname) 179 | { 180 | this->create_var(varname); 181 | ++this->ip; 182 | } 183 | 184 | void CompilePrincipleInterpreter::becomes(const std::string& valuename,const std::string& varname) 185 | { 186 | int val; 187 | if(ISNUM(valuename)) //这里不进行任何验证性判断,如果中间代码非法,将会段错误 188 | { 189 | sscanf(valuename.c_str(),"%d",&val); 190 | this->set_var(varname,val); 191 | } 192 | else 193 | { 194 | this->set_var(varname,this->get_var(valuename)); 195 | } 196 | ++this->ip; 197 | } 198 | 199 | void CompilePrincipleInterpreter::read(const std::string& varname) 200 | { 201 | int buf; 202 | std::cin >> buf; 203 | this->set_var(varname,buf); 204 | ++this->ip; 205 | } 206 | 207 | void CompilePrincipleInterpreter::write(const std::string& valuename) 208 | { 209 | int val; 210 | if(ISNUM(valuename)) //这里不进行任何验证性判断,如果中间代码非法,将会段错误 211 | { 212 | sscanf(valuename.c_str(),"%d",&val); 213 | std::cout << val << std::endl; 214 | } 215 | else 216 | { 217 | std::cout << this->get_var(valuename) << std::endl; 218 | } 219 | ++this->ip; 220 | } 221 | 222 | void CompilePrincipleInterpreter::plus(const std::string& oper1, const std::string& oper2, const std::string& oper3) 223 | { 224 | ARITHMETICS(+) 225 | } 226 | 227 | void CompilePrincipleInterpreter::minus(const std::string& oper1, const std::string& oper2, const std::string& oper3) 228 | { 229 | ARITHMETICS(-) 230 | } 231 | 232 | void CompilePrincipleInterpreter::times(const std::string& oper1, const std::string& oper2, const std::string& oper3) 233 | { 234 | ARITHMETICS(*) 235 | } 236 | 237 | void CompilePrincipleInterpreter::slash(const std::string& oper1, const std::string& oper2, const std::string& oper3) 238 | { 239 | ARITHMETICS(/) 240 | } 241 | 242 | void CompilePrincipleInterpreter::call(const std::string& point) 243 | { 244 | this->runtime_stack.push_back(CompilePrincipleInterpreter::RuntimeStackNode(this->ip+1)); 245 | this->ip=this->point_map.find(point)->second; 246 | } 247 | 248 | void CompilePrincipleInterpreter::ret() 249 | { 250 | this->ip=this->runtime_stack.back().ip; 251 | this->runtime_stack.pop_back(); 252 | } 253 | 254 | void CompilePrincipleInterpreter::odd(const std::string& oper1, const std::string& point) 255 | { 256 | if(this->get_var(oper1)%2==1)//奇数 257 | { 258 | ++this->ip; 259 | } 260 | else/*偶数*/ 261 | { 262 | this->ip=this->point_map.find(point)->second; 263 | } 264 | } 265 | 266 | void CompilePrincipleInterpreter::jump(const std::string& point) 267 | { 268 | this->ip=this->point_map.find(point)->second; 269 | } 270 | 271 | void CompilePrincipleInterpreter::geq(const std::string& oper1, const std::string& oper2, const std::string& point) 272 | { 273 | CONDITION(>=) 274 | } 275 | 276 | void CompilePrincipleInterpreter::gtr(const std::string& oper1, const std::string& oper2, const std::string& point) 277 | { 278 | CONDITION(>) 279 | } 280 | 281 | void CompilePrincipleInterpreter::leq(const std::string& oper1, const std::string& oper2, const std::string& point) 282 | { 283 | CONDITION(<=) 284 | } 285 | 286 | void CompilePrincipleInterpreter::lss(const std::string& oper1, const std::string& oper2, const std::string& point) 287 | { 288 | CONDITION(<) 289 | } 290 | 291 | void CompilePrincipleInterpreter::eql(const std::string& oper1, const std::string& oper2, const std::string& point) 292 | { 293 | CONDITION(==) 294 | } 295 | 296 | void CompilePrincipleInterpreter::neq(const std::string& oper1, const std::string& oper2, const std::string& point) 297 | { 298 | CONDITION(!=) 299 | } 300 | 301 | int CompilePrincipleInterpreter::get_var(const std::string& varname) const 302 | { 303 | std::map::const_iterator found_iter; 304 | for(std::deque::const_reverse_iterator iter=this->runtime_stack.rbegin(); 305 | iter!=this->runtime_stack.rend();++iter) 306 | { 307 | if((found_iter=iter->var_map.find(varname))!=iter->var_map.end()) 308 | { 309 | return found_iter->second; 310 | } 311 | }//if not found, error 312 | } 313 | 314 | void CompilePrincipleInterpreter::set_var(const std::string& varname,const int value) 315 | { 316 | std::map::iterator found_iter; 317 | for(std::deque::reverse_iterator iter=this->runtime_stack.rbegin(); 318 | iter!=this->runtime_stack.rend();++iter) 319 | { 320 | if((found_iter=iter->var_map.find(varname))!=iter->var_map.end()) 321 | { 322 | found_iter->second=value; 323 | return; 324 | } 325 | }//if not found, error 326 | } 327 | 328 | void CompilePrincipleInterpreter::create_var(const std::string& varname) 329 | { 330 | this->runtime_stack.back().var_map.insert(std::make_pair(varname,0)); 331 | } -------------------------------------------------------------------------------- /CompilePrincipleInterpreter/CompilePrincipleInterpreter.class.h: -------------------------------------------------------------------------------- 1 | #ifndef COMPILEPRINCIPLEINTERPRETER_CLASS_H 2 | #define COMPILEPRINCIPLEINTERPRETER_CLASS_H 3 | #include 4 | #include 5 | #include 6 | 7 | class CompilePrincipleInterpreter 8 | { 9 | private: 10 | class IntermediateCodeNode 11 | { 12 | public: 13 | std::string command; 14 | std::string oper1,oper2,oper3; 15 | public: 16 | IntermediateCodeNode(const std::string& _command,const std::string& _oper1,const std::string& _oper2,const std::string& _oper3) 17 | :command(_command),oper1(_oper1),oper2(_oper2),oper3(_oper3){} 18 | }; 19 | class RuntimeStackNode 20 | { 21 | public: 22 | int ip; 23 | std::map var_map; 24 | public: 25 | RuntimeStackNode(const int _ip):ip(_ip){} 26 | }; 27 | private: 28 | std::map point_map; 29 | std::deque code_stack; 30 | std::deque runtime_stack; 31 | int ip;//程序计数器 32 | public: 33 | void interpreter(const std::string&); 34 | private: 35 | void command(const std::string&,const std::string&,const std::string&,const std::string&); 36 | void collect_point(const std::string&,const int); 37 | void var(const std::string&); 38 | void becomes(const std::string&,const std::string&); 39 | void read(const std::string&); 40 | void write(const std::string&); 41 | void plus(const std::string&,const std::string&,const std::string&); 42 | void minus(const std::string&,const std::string&,const std::string&); 43 | void times(const std::string&,const std::string&,const std::string&); 44 | void slash(const std::string&,const std::string&,const std::string&); 45 | void odd(const std::string&,const std::string&); 46 | void jump(const std::string&); 47 | void geq(const std::string&,const std::string&,const std::string&); 48 | void gtr(const std::string&,const std::string&,const std::string&); 49 | void leq(const std::string&,const std::string&,const std::string&); 50 | void lss(const std::string&,const std::string&,const std::string&); 51 | void eql(const std::string&,const std::string&,const std::string&); 52 | void neq(const std::string&,const std::string&,const std::string&); 53 | void call(const std::string&); 54 | void ret(); 55 | public: 56 | CompilePrincipleInterpreter():ip(0) 57 | { 58 | this->runtime_stack.push_back(RuntimeStackNode(0)); 59 | } 60 | private: 61 | int get_var(const std::string&) const; 62 | void set_var(const std::string&,const int); 63 | void create_var(const std::string&); 64 | }; 65 | 66 | #endif /* COMPILEPRINCIPLEINTERPRETER_CLASS_H */ 67 | 68 | -------------------------------------------------------------------------------- /CompilePrincipleInterpreter/main.cpp: -------------------------------------------------------------------------------- 1 | #include"CompilePrincipleInterpreter.class.h" 2 | #include 3 | 4 | int main(int argc,char* argv[]) 5 | { 6 | CompilePrincipleInterpreter interpreter; 7 | if(argc<=1) 8 | { 9 | std::cerr << "必须指定输入文件" << std::endl; 10 | return 1; 11 | } 12 | interpreter.interpreter(argv[1]); 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /LexicalAnalyzer.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __LEXICALANALYZER_CLASS_H 2 | #define __LEXICALANALYZER_CLASS_H 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | class LexicalAnalyzer 9 | { 10 | public: 11 | class InputReader 12 | { 13 | protected: 14 | int curline,curchar,curindex,prevline,prevchar; 15 | public: 16 | InputReader():curline(1),curchar(0),curindex(0) 17 | { 18 | } 19 | virtual char peekchar() const=0; 20 | virtual char getchar()=0; 21 | virtual int get_curline() const 22 | { 23 | return this->curline; 24 | } 25 | virtual int get_curchar() const 26 | { 27 | return this->curchar; 28 | } 29 | virtual int get_prevline() const 30 | { 31 | return this->prevline; 32 | } 33 | virtual int get_prevchar() const 34 | { 35 | return this->prevchar; 36 | } 37 | virtual bool eof() const=0; 38 | }; 39 | 40 | class ConsoleInputReader:public InputReader 41 | { 42 | public: 43 | char peekchar() const 44 | { 45 | if(eof()) return -1; 46 | return std::cin.peek(); 47 | } 48 | char getchar() 49 | { 50 | if(eof()) return -1; 51 | char c=std::cin.get(); 52 | this->prevline=this->curline; 53 | this->prevchar=this->curchar; 54 | ++this->curindex; 55 | if(c=='\n') 56 | { 57 | ++this->curline; 58 | this->curchar=0; 59 | } 60 | else ++this->curchar; 61 | return c; 62 | } 63 | bool eof() const 64 | { 65 | return std::cin.eof(); 66 | } 67 | }; 68 | 69 | class FileReader:public InputReader 70 | { 71 | private: 72 | std::string buffer; 73 | public: 74 | bool open(const std::string& path) 75 | { 76 | std::ifstream file(path.c_str(),std::ios::in); 77 | if(file.fail()) return false; 78 | std::getline(file,this->buffer,(char)-1); 79 | file.close(); 80 | curline=1; 81 | curchar=curindex=0; 82 | return true; 83 | } 84 | char peekchar() const 85 | { 86 | if(eof()) return -1; 87 | return this->buffer[this->curindex]; 88 | } 89 | char getchar() 90 | { 91 | char c=peekchar(); 92 | this->prevline=this->curline; 93 | this->prevchar=this->curchar; 94 | ++this->curindex; 95 | if(c=='\n') 96 | { 97 | ++this->curline; 98 | this->curchar=0; 99 | } 100 | else ++this->curchar; 101 | return c; 102 | } 103 | bool eof() const 104 | { 105 | return this->curindex >= this->buffer.size(); 106 | } 107 | }; 108 | private: 109 | ConsoleInputReader consoleinputreader; 110 | FileReader filereader; 111 | InputReader *inputreader; 112 | std::string cursymword,prevsymword; 113 | int cursymtype,prevsymtype; 114 | int cursymline,cursymchar,prevsymline,prevsymchar; 115 | public: 116 | bool open(const std::string &path=""); 117 | void next(); 118 | int peeksymtype() const; 119 | int getsymtype(); 120 | std::string peeksymword() const; 121 | std::string getsymword(); 122 | int getprevsymtype() const; 123 | std::string getprevsymword() const; 124 | bool eof() const; 125 | int get_curline() const; 126 | int get_curchar() const; 127 | int get_prevline() const; 128 | int get_prevchar() const; 129 | private: 130 | int get_keyword(std::string) const; 131 | int get_operator(const std::string&) const; 132 | bool getsym(std::string&,int&); 133 | }; 134 | 135 | #endif 136 | -------------------------------------------------------------------------------- /LexicalAnalyzer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | 6 | bool LexicalAnalyzer::open(const std::string &path) 7 | { 8 | int type; 9 | std::string word; 10 | 11 | if(path.size()>0)//文件操作 12 | { 13 | this->inputreader=&this->filereader; 14 | if(!this->filereader.open(path)) return false; 15 | } 16 | else//控制台输入操作 17 | { 18 | this->inputreader=&this->consoleinputreader; 19 | } 20 | 21 | if(!this->getsym(word,type)) return false; 22 | this->cursymtype=type; 23 | this->cursymword=word; 24 | return true; 25 | } 26 | 27 | void LexicalAnalyzer::next() 28 | { 29 | int type; 30 | std::string word; 31 | this->prevsymtype=this->cursymtype; 32 | this->prevsymword=this->cursymword; 33 | this->getsym(word,type); 34 | this->cursymtype=type; 35 | this->cursymword=word; 36 | } 37 | 38 | int LexicalAnalyzer::peeksymtype() const 39 | { 40 | return this->cursymtype; 41 | } 42 | 43 | int LexicalAnalyzer::getsymtype() 44 | { 45 | if(!this->eof()) 46 | { 47 | this->next(); 48 | return this->getprevsymtype(); 49 | } 50 | else return this->peeksymtype(); 51 | } 52 | 53 | std::string LexicalAnalyzer::peeksymword() const 54 | { 55 | return this->cursymword; 56 | } 57 | 58 | std::string LexicalAnalyzer::getsymword() 59 | { 60 | if(!this->eof()) 61 | { 62 | this->next(); 63 | return this->getprevsymword(); 64 | } 65 | else return this->peeksymword(); 66 | } 67 | 68 | int LexicalAnalyzer::getprevsymtype() const 69 | { 70 | return this->prevsymtype; 71 | } 72 | 73 | std::string LexicalAnalyzer::getprevsymword() const 74 | { 75 | return this->prevsymword; 76 | } 77 | 78 | bool LexicalAnalyzer::eof() const 79 | { 80 | return this->inputreader->eof(); 81 | } 82 | 83 | int LexicalAnalyzer::get_curline() const 84 | { 85 | return this->cursymline; 86 | } 87 | 88 | int LexicalAnalyzer::get_curchar() const 89 | { 90 | return this->cursymchar; 91 | } 92 | 93 | int LexicalAnalyzer::get_prevline() const 94 | { 95 | return this->prevsymline; 96 | } 97 | 98 | int LexicalAnalyzer::get_prevchar() const 99 | { 100 | return this->prevsymchar; 101 | } 102 | -------------------------------------------------------------------------------- /SyntacticAnalyzer.class.cpp: -------------------------------------------------------------------------------- 1 | #include"SyntacticAnalyzer.class.h" 2 | #include"keywordlist.h" 3 | #include"intermediatecodelist.h" 4 | #include 5 | #include 6 | 7 | #define TEMP_VARNAME_PREFIX "tempvar_" 8 | #define TEMP_POINT_PREFIX "" 9 | 10 | std::deque::const_iterator SyntacticAnalyzer::ident_stack_find(const std::string& _ident,const QUERYWAY query_way) const 11 | { 12 | for(std::deque::const_reverse_iterator iter=this->ident_stack.rbegin();iter!=this->ident_stack.rend();++iter) 13 | { 14 | if(iter->ident==_ident) 15 | { 16 | return iter.base()-1; 17 | } 18 | else if(iter->flag==BOUND && query_way==QUERY_CUR_PROC) break; 19 | } 20 | return this->ident_stack.end(); 21 | } 22 | 23 | bool SyntacticAnalyzer::procedure_find(const std::string& _ident) const 24 | { 25 | for(std::vector::const_iterator iter=this->procedure_vector.begin(); 26 | iter!=this->procedure_vector.end();++iter) 27 | { 28 | if(*iter==_ident) 29 | { 30 | return true; 31 | } 32 | } 33 | return false; 34 | } 35 | 36 | void SyntacticAnalyzer::ident_stack_clear() 37 | { 38 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(SyntacticAnalyzer::IntermediateCodeNode(RETURN)); 39 | 40 | while(this->ident_stack.back().flag!=BOUND) 41 | { 42 | this->ident_stack.pop_back(); 43 | } 44 | this->cur_procedure_name=this->ident_stack.back().ident; 45 | this->cur_procedure_index=this->ident_stack.back().value; 46 | this->ident_stack.pop_back(); 47 | } 48 | 49 | std::string SyntacticAnalyzer::TempVar::next() 50 | { 51 | char buffer[10]; 52 | sprintf(buffer,"%d",this->seqnum++); 53 | return std::string(TEMP_VARNAME_PREFIX)+buffer; 54 | } 55 | 56 | std::string SyntacticAnalyzer::TempPoint::next() 57 | { 58 | char buffer[10]; 59 | sprintf(buffer,"%d",this->seqnum++); 60 | return std::string(TEMP_POINT_PREFIX)+buffer; 61 | } 62 | 63 | void SyntacticAnalyzer::declare_new_var(const std::string& varname) 64 | { 65 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(SyntacticAnalyzer::IntermediateCodeNode(VARSYM,varname)); 66 | } 67 | 68 | bool SyntacticAnalyzer::TempVar::isTempVar(const std::string& varname) 69 | { 70 | const std::string temp_varname_prefix=TEMP_VARNAME_PREFIX; 71 | return temp_varname_prefix==varname.substr(0,temp_varname_prefix.size()); 72 | } 73 | 74 | void SyntacticAnalyzer::print_intermediate_code(std::ostream& out) const 75 | { 76 | int i; 77 | std::deque::const_iterator iter; 78 | for(i=0;iintermediate_code_deque_vector.size();++i) 79 | { 80 | out << this->procedure_vector[i] << ':' << '\n'; 81 | for(iter=this->intermediate_code_deque_vector[i].begin(); 82 | iter!=this->intermediate_code_deque_vector[i].end();++iter) 83 | {//必须对DECLARE做特别判断,这仅仅是个妥协,不是合法指令 84 | if(iter->command==DECLARE) 85 | { 86 | out << iter->oper1 << COLON << std::endl; 87 | } 88 | else 89 | { 90 | out << LPARAN << iter->command; 91 | if(iter->oper1!="") out << DELIMITER << iter->oper1; 92 | if(iter->oper2!="") out << DELIMITER << iter->oper2; 93 | if(iter->oper3!="") out << DELIMITER << iter->oper3; 94 | out << RPARAN << std::endl; 95 | } 96 | } 97 | } 98 | } -------------------------------------------------------------------------------- /SyntacticAnalyzer.class.h: -------------------------------------------------------------------------------- 1 | #ifndef __SYNTACTICANALYZER_CLASS_H 2 | #define __SYNTACTICANALYZER_CLASS_H 3 | #include"LexicalAnalyzer.class.h" 4 | #include"keywordlist.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | class SyntacticAnalyzer 12 | { 13 | private: 14 | enum IdentStackFlag{CONST,VAR,BOUND}; 15 | enum SyntacticAnalyzerResult {ERROR=false,RIGHT=true,VALUE=2}; 16 | enum QUERYWAY{QUERY_ALL_PROC=true,QUERY_CUR_PROC=false}; 17 | class IdentStackNode 18 | { 19 | public: 20 | IdentStackFlag flag; 21 | std::string ident; 22 | int value; 23 | public: 24 | IdentStackNode(const IdentStackFlag _flag,const std::string& _ident="",const int _value=0):flag(_flag),ident(_ident),value(_value){} 25 | }; 26 | class TempVar 27 | { 28 | public: 29 | std::string prev_temp_varname; 30 | private: 31 | int seqnum; 32 | public: 33 | TempVar():seqnum(1){} 34 | std::string next(); 35 | static bool isTempVar(const std::string& varname); 36 | }; 37 | class TempPoint 38 | { 39 | private: 40 | int seqnum; 41 | public: 42 | TempPoint():seqnum(1){} 43 | std::string next(); 44 | }; 45 | class IntermediateCodeNode 46 | { 47 | public: 48 | std::string command; 49 | std::string oper1,oper2,oper3; 50 | public: 51 | IntermediateCodeNode(const std::string& _command="",const std::string& _oper1="",const std::string& _oper2="",const std::string& _oper3="") 52 | :command(_command),oper1(_oper1),oper2(_oper2),oper3(_oper3){} 53 | }; 54 | private: 55 | std::string errorinfo; 56 | std::deque ident_stack; 57 | std::vector procedure_vector; 58 | std::vector > intermediate_code_deque_vector; 59 | TempVar tempvar; 60 | TempPoint temppoint; 61 | std::string cur_procedure_name; 62 | int cur_procedure_index; 63 | public: 64 | SyntacticAnalyzerResult analyze(LexicalAnalyzer&); 65 | private: 66 | SyntacticAnalyzerResult subprogram(LexicalAnalyzer&); 67 | SyntacticAnalyzerResult constsym(LexicalAnalyzer&); 68 | SyntacticAnalyzerResult varsym(LexicalAnalyzer&); 69 | SyntacticAnalyzerResult procsym(LexicalAnalyzer&); 70 | SyntacticAnalyzerResult statement(LexicalAnalyzer&); 71 | SyntacticAnalyzerResult callsym(LexicalAnalyzer&); 72 | SyntacticAnalyzerResult beginsym(LexicalAnalyzer&); 73 | SyntacticAnalyzerResult ifsym(LexicalAnalyzer&); 74 | SyntacticAnalyzerResult whilesym(LexicalAnalyzer&); 75 | SyntacticAnalyzerResult readsym(LexicalAnalyzer&); 76 | SyntacticAnalyzerResult writesym(LexicalAnalyzer&); 77 | SyntacticAnalyzerResult ident(LexicalAnalyzer&); 78 | SyntacticAnalyzerResult condition(LexicalAnalyzer&,const std::string&,bool&); 79 | SyntacticAnalyzerResult expression(LexicalAnalyzer&,int&); 80 | SyntacticAnalyzerResult item(LexicalAnalyzer&,int&); 81 | SyntacticAnalyzerResult factor(LexicalAnalyzer&,int&); 82 | private: 83 | std::deque::const_iterator ident_stack_find(const std::string&,const QUERYWAY) const; 84 | bool procedure_find(const std::string&) const; 85 | void ident_stack_clear(); 86 | void declare_new_var(const std::string&); 87 | public: 88 | SyntacticAnalyzer():cur_procedure_name("[START]"),cur_procedure_index(0) 89 | { 90 | intermediate_code_deque_vector.push_back(std::deque()); 91 | procedure_vector.push_back("start"); 92 | } 93 | std::string get_error_info() const 94 | { 95 | return this->errorinfo; 96 | } 97 | void print_intermediate_code(std::ostream& out) const; 98 | }; 99 | 100 | #endif 101 | 102 | -------------------------------------------------------------------------------- /details.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"operatorlist.h" 5 | #include"keywordlist.h" 6 | #include"wordlist.h" 7 | 8 | #define VALUEBUFFERLENGTH 10 9 | #define DECLARE_NEW_TEMPVARNAME_TO_OPER3 \ 10 | {\ 11 | newcodenode.oper3=this->tempvar.next();\ 12 | this->declare_new_var(newcodenode.oper3);\ 13 | } 14 | 15 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::condition(LexicalAnalyzer& lexical_analyzer,const std::string& point,bool& value) 16 | { 17 | SyntacticAnalyzer::SyntacticAnalyzerResult res=RIGHT,tmp_res=RIGHT,tmp_res2=RIGHT; 18 | int tmp_value,tmp_value2,type=lexical_analyzer.peeksymtype(); 19 | std::string oper1,word; 20 | if(type==ODDTYPE) 21 | { 22 | lexical_analyzer.getsymtype(); 23 | if(!(res=expression(lexical_analyzer,tmp_value))) return ERROR; 24 | else if(res==VALUE) 25 | { 26 | value=tmp_value%2==1; 27 | if(value==false)//如果value为假,证明中间所有语句均不可能执行到,直接跳过 28 | { 29 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back( 30 | SyntacticAnalyzer::IntermediateCodeNode(JUMP,point)); 31 | } 32 | } 33 | else 34 | { 35 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back( 36 | SyntacticAnalyzer::IntermediateCodeNode(ODDSYM,this->tempvar.prev_temp_varname,point)); 37 | } 38 | return res; 39 | } 40 | else 41 | { 42 | if(!(tmp_res=expression(lexical_analyzer,tmp_value))) return ERROR; 43 | else oper1=this->tempvar.prev_temp_varname;//记录oper1的返回内容 44 | 45 | if(type=lexical_analyzer.getsymtype(),word=lexical_analyzer.getprevsymword(), 46 | type!=EQLTYPE && type!=NEQTYPE && type!=LSSTYPE && type!=LEQTYPE && type!=GTRTYPE && type!=GEQTYPE) 47 | { 48 | this->errorinfo="这里应该有一个比较运算符,例如等于 = ,不等于 # ,小于 < ,小于等于 <= ,大于 > ,大于等于 >= "; 49 | return ERROR; 50 | } 51 | else 52 | { 53 | if(!(tmp_res2=expression(lexical_analyzer,tmp_value2))) return ERROR; 54 | else if(tmp_res==VALUE && tmp_res2==VALUE) 55 | { 56 | switch(type) 57 | { 58 | case EQLTYPE: value=tmp_value==tmp_value2;break; 59 | case NEQTYPE: value=tmp_value!=tmp_value2;break; 60 | case LSSTYPE: value=tmp_valuetmp_value2;break; 63 | case GEQTYPE: value=tmp_value>=tmp_value2;break; 64 | } 65 | 66 | if(value==false)//如果value为假,证明中间所有语句均不可能执行到,直接跳过 67 | { 68 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back( 69 | SyntacticAnalyzer::IntermediateCodeNode(JUMP,point)); 70 | } 71 | 72 | return VALUE; 73 | } 74 | else 75 | { 76 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back( 77 | SyntacticAnalyzer::IntermediateCodeNode(word,oper1,this->tempvar.prev_temp_varname,point)); 78 | //这里直接依赖“this->tempvar.prev_temp_varname中存储返回值的字符串” 79 | } 80 | 81 | return RIGHT; 82 | } 83 | } 84 | } 85 | 86 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::expression(LexicalAnalyzer& lexical_analyzer,int& value) 87 | { 88 | SyntacticAnalyzer::SyntacticAnalyzerResult res=RIGHT,tmp_res=RIGHT; 89 | SyntacticAnalyzer::IntermediateCodeNode newcodenode; 90 | int fac=1,tmp_value,some_value_to_optimize=0/*加减法这里是0,乘除法是1*/; 91 | char buffer[VALUEBUFFERLENGTH]; 92 | std::string oper1; 93 | 94 | for(;;) 95 | { 96 | type=lexical_analyzer.peeksymtype(); 97 | if(type==PLUSTYPE || type==MINUSTYPE) 98 | { 99 | if(type==MINUSTYPE) fac=-1; 100 | lexical_analyzer.getsymtype(); 101 | } 102 | if(!(res=item(lexical_analyzer,value))) return ERROR; 103 | else if(res==VALUE && value==0 && (lexical_analyzer.peeksymtype()==PLUSTYPE || lexical_analyzer.peeksymtype()==MINUSTYPE)) continue; 104 | else if(res==VALUE)//既然是值,我们保留值的样子,不生成中间代码,以期待接下来的操作数都以值的形式出现,这样就可以实现优化 105 | { 106 | value*=fac;//之前是符号,让它乘以符号因子1或-1 107 | sprintf(buffer,"%d",value); 108 | this->tempvar.prev_temp_varname=buffer;//这里如果item返回值,替换掉最后一个临时变量 109 | } 110 | else if(fac==-1 && res==RIGHT)//如果这是个变量且在前面加过负号,在这里将出现(times -1 var tempvar)的中间代码 111 | { 112 | newcodenode.command=TIMESOPER; 113 | sprintf(buffer,"%d",-1); 114 | newcodenode.oper1=buffer; 115 | newcodenode.oper2=this->tempvar.prev_temp_varname;//prev_temp_varname里存储item函数中的最后结果 116 | DECLARE_NEW_TEMPVARNAME_TO_OPER3 117 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 118 | this->tempvar.prev_temp_varname=newcodenode.oper3; 119 | } 120 | //如果fac==1 && res==RIGHT,那么前一个结果的最后变量还在this->tempvar.prev_temp_varname不动 121 | //这样一来,this->tempvar.prev_temp_varname就始终代表前一个变量或是值了 122 | //然后,我们把this->tempvar.prev_temp_varname保存在oper1里,因为等会还要调用item函数,this->tempvar.prev_temp_varname将会被替换 123 | oper1=this->tempvar.prev_temp_varname; 124 | break; 125 | } 126 | 127 | while(type=lexical_analyzer.peeksymtype(),type==PLUSTYPE || type==MINUSTYPE) 128 | { 129 | if(lexical_analyzer.getsymtype(),!(tmp_res=item(lexical_analyzer,tmp_value))) return ERROR; 130 | 131 | else if(tmp_res==VALUE && tmp_value==0) 132 | { 133 | this->tempvar.prev_temp_varname=oper1;//抛弃0这个结果 134 | continue;//对于加减法,如果 加/减 数为0,不再继续做下去,直接下一轮迭代。 135 | } 136 | 137 | else if(res==VALUE && tmp_res==VALUE) 138 | { 139 | if(type==PLUSTYPE) value+=tmp_value; 140 | else /*if(type==MINUSTYPE)*/ value-=tmp_value; 141 | //我们必须继续保持oper1为前一个操作数不变,必须继续保持,希望不要在哪里忘记掉 142 | sprintf(buffer,"%d",value); 143 | this->tempvar.prev_temp_varname=oper1=buffer;//我们还要让this->tempvar.prev_temp_varname也为最新的value, 144 | //万一在这里结束,this->tempvar.prev_temp_varname里能够保存本函数最后的结果值 145 | } 146 | else 147 | { 148 | //对于一旦出现res还是VALUE而tmp_res已不是VALUE的情况,将会保存res为一临时变量,然后让这个临时变量参与接下来一切计算 149 | if(res==VALUE /* && tmp_res==RIGHT*/) 150 | { 151 | res=RIGHT; 152 | 153 | newcodenode.command=(type==PLUSTYPE?PLUSOPER:MINUSOPER);//PLUS OR MINUS 154 | newcodenode.oper1=oper1; 155 | newcodenode.oper2=this->tempvar.prev_temp_varname; 156 | if(SyntacticAnalyzer::TempVar::isTempVar(this->tempvar.prev_temp_varname)) newcodenode.oper3=this->tempvar.prev_temp_varname; 157 | else DECLARE_NEW_TEMPVARNAME_TO_OPER3 158 | 159 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 160 | this->tempvar.prev_temp_varname=oper1=newcodenode.oper3; 161 | } 162 | else if(tmp_res==VALUE /*&& res==RIGHT*/) 163 | { 164 | if(type==PLUSTYPE) 165 | { 166 | some_value_to_optimize+=tmp_value; 167 | } 168 | else /*if(type==MINUS)*/ 169 | { 170 | some_value_to_optimize-=tmp_value; 171 | } 172 | } 173 | else 174 | { 175 | newcodenode.command=(type==PLUSTYPE?PLUSOPER:MINUSOPER);//不是PLUS就是MINUS 176 | newcodenode.oper1=oper1; 177 | newcodenode.oper2=this->tempvar.prev_temp_varname; //item的结果,可能是值。注意,即使是返回值,this->tempvar.prev_temp_varname内也必须是结果值的字符串 178 | //调用他的函数不应为此负责,简化下代码 179 | //由于非常复杂,可能出现的情况太多,这里仅仅依靠前缀来判断是否是临时变量,如果是临时变量就是可以修改的。这里关键是不能修改掉用户定义的变量常量或是值 180 | if(SyntacticAnalyzer::TempVar::isTempVar(newcodenode.oper1)) newcodenode.oper3=newcodenode.oper1; 181 | else if(SyntacticAnalyzer::TempVar::isTempVar(newcodenode.oper2)) newcodenode.oper3=newcodenode.oper2; 182 | else DECLARE_NEW_TEMPVARNAME_TO_OPER3 183 | 184 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 185 | this->tempvar.prev_temp_varname=oper1=newcodenode.oper3; //oper1和this->tempvar.prev_temp_varname同时保存前一个结果,一个给函数返回以后使用,一个给下一个循环使用 186 | } 187 | } 188 | } 189 | 190 | if(some_value_to_optimize!=0) 191 | { 192 | newcodenode.command=PLUSOPER; 193 | newcodenode.oper1=oper1; 194 | sprintf(buffer,"%d",some_value_to_optimize); 195 | newcodenode.oper2=buffer; 196 | if(SyntacticAnalyzer::TempVar::isTempVar(oper1)) newcodenode.oper3=oper1; 197 | else DECLARE_NEW_TEMPVARNAME_TO_OPER3 198 | 199 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 200 | this->tempvar.prev_temp_varname=newcodenode.oper3; 201 | } 202 | 203 | 204 | return res; 205 | } 206 | 207 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::item(LexicalAnalyzer& lexical_analyzer,int& value) 208 | { 209 | SyntacticAnalyzer::SyntacticAnalyzerResult res=RIGHT,tmp_res=RIGHT; 210 | SyntacticAnalyzer::IntermediateCodeNode newcodenode; 211 | int tmp_value,some_value_to_optimize=1/*乘除法这里是1,加减法是0*/,type; 212 | bool stop_optimizing=false;//当出现第一个除法时,立即停止优化。 213 | std::string oper1; 214 | char buffer[VALUEBUFFERLENGTH]; 215 | 216 | for(;;) 217 | { 218 | if(!(res=factor(lexical_analyzer,value))) return ERROR; 219 | else if(res==VALUE && value==1 && lexical_analyzer.peeksymtype()==TIMESTYPE) 220 | { 221 | lexical_analyzer.getsymtype(); 222 | continue; 223 | } 224 | else/*if(res==VALUE || res==RIGHT)*/ 225 | {//和前面一样,我们把factor的结果放在oper1里,小心翼翼的维护他。 226 | //但这里还比前面简单,完全不需要对res的处理,好爽好爽~~ 227 | oper1=this->tempvar.prev_temp_varname; 228 | } 229 | //如果能走到这一步,res只会是RIGHT或VALUE 230 | //和前面一样,oper1和this->tempvar.prev_temp_varname同时保持最新结果,一个给返回后使用,一个给接下来的迭代使用 231 | break; 232 | } 233 | 234 | while(type=lexical_analyzer.peeksymtype(),type==TIMESTYPE || type==SLASHTYPE) 235 | { 236 | if(lexical_analyzer.getsymtype(),!(tmp_res=factor(lexical_analyzer,tmp_value))) return ERROR; 237 | //如果能走到这一步,tmp_res只会是RIGHT或VALUE 238 | else if(tmp_res==VALUE && tmp_value==1) 239 | { 240 | this->tempvar.prev_temp_varname=oper1;//抛弃1这个结果 241 | continue;//对于乘除法,如果 乘/除 数为1,不再继续做下去,直接下一轮迭代。 242 | } 243 | 244 | else if(res==VALUE && tmp_res==VALUE) 245 | { 246 | if(type==TIMESTYPE) value*=tmp_value; 247 | else/* if(type==SLASHTYPE)*/ value/=tmp_value; 248 | sprintf(buffer,"%d",value); 249 | this->tempvar.prev_temp_varname=oper1=buffer;//继续保持 偶也~~ 250 | } 251 | else 252 | { 253 | if(type==SLASHTYPE) 254 | { 255 | stop_optimizing=true; 256 | if(some_value_to_optimize!=1) 257 | { 258 | newcodenode.command=TIMESOPER; 259 | newcodenode.oper1=oper1; 260 | sprintf(buffer,"%d",some_value_to_optimize); 261 | newcodenode.oper2=buffer; 262 | if(SyntacticAnalyzer::TempVar::isTempVar(oper1)) newcodenode.oper3=oper1; 263 | else DECLARE_NEW_TEMPVARNAME_TO_OPER3 264 | 265 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 266 | some_value_to_optimize=1; 267 | } 268 | } 269 | //破处~~ 270 | if(res==VALUE /*&& tmp_res==RIGHT*/) 271 | { 272 | res=RIGHT;//只要有一次tmp_res不是VALUE,那么对value的计算毫无意义,使res=RIGHT来避免此计算 273 | 274 | newcodenode.command=(type==TIMESTYPE?TIMESOPER:SLASHOPER);//TIMES OR SLASH 275 | newcodenode.oper1=oper1; 276 | newcodenode.oper2=this->tempvar.prev_temp_varname; 277 | if(SyntacticAnalyzer::TempVar::isTempVar(this->tempvar.prev_temp_varname)) newcodenode.oper3=this->tempvar.prev_temp_varname; 278 | else DECLARE_NEW_TEMPVARNAME_TO_OPER3 279 | 280 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 281 | this->tempvar.prev_temp_varname=oper1=newcodenode.oper3;//保持保持~~ 282 | } 283 | else if(tmp_res==VALUE && stop_optimizing==false /* && res=RIGHT*/) 284 | {//既然tmp_res是个值,证明还有优化的潜能,我们把值放进some_value_to_optimize里,并在最后把它作为一条指令放进结果中 285 | some_value_to_optimize*=tmp_value; 286 | } 287 | else 288 | { 289 | newcodenode.command=(type==TIMESTYPE?TIMESOPER:SLASHOPER);//TIMES or SLASH 290 | newcodenode.oper1=oper1; 291 | newcodenode.oper2=this->tempvar.prev_temp_varname; 292 | 293 | if(SyntacticAnalyzer::TempVar::isTempVar(newcodenode.oper1)) newcodenode.oper3=newcodenode.oper1; 294 | else if(SyntacticAnalyzer::TempVar::isTempVar(newcodenode.oper2)) newcodenode.oper3=newcodenode.oper2; 295 | else DECLARE_NEW_TEMPVARNAME_TO_OPER3 296 | 297 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 298 | this->tempvar.prev_temp_varname=oper1=newcodenode.oper3;//保持保持~~ 299 | } 300 | } 301 | } 302 | 303 | if(some_value_to_optimize!=1) 304 | { 305 | newcodenode.command=TIMESOPER; 306 | newcodenode.oper1=oper1; 307 | sprintf(buffer,"%d",some_value_to_optimize); 308 | newcodenode.oper2=buffer; 309 | if(SyntacticAnalyzer::TempVar::isTempVar(oper1)) newcodenode.oper3=oper1; 310 | else DECLARE_NEW_TEMPVARNAME_TO_OPER3 311 | 312 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 313 | this->tempvar.prev_temp_varname=newcodenode.oper3; 314 | } 315 | 316 | return res; 317 | } 318 | 319 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::factor(LexicalAnalyzer& lexical_analyzer,int& value) 320 | { 321 | SyntacticAnalyzer::SyntacticAnalyzerResult res=RIGHT; 322 | int type=lexical_analyzer.getsymtype(); 323 | std::string word=lexical_analyzer.getprevsymword(); 324 | std::deque::const_iterator iter; 325 | char buffer[VALUEBUFFERLENGTH]; 326 | 327 | if(type!=IDENTTYPE && type!=NUMBERTYPE && type!=LPARENTYPE) 328 | { 329 | this->errorinfo="这里应该是一个标识符或是一个数字或是一个表达式"; 330 | return ERROR; 331 | } 332 | 333 | else if(type==NUMBERTYPE) 334 | { 335 | this->tempvar.prev_temp_varname=word;//this->tempvar.prev_temp_varname必须保持最新结果,无论接下来是不是返回值 336 | sscanf(word.c_str(),"%d",&value); 337 | return VALUE; 338 | } 339 | 340 | else if(type==IDENTTYPE) 341 | { 342 | if((iter=this->ident_stack_find(word.c_str(),QUERY_ALL_PROC))==this->ident_stack.end()) 343 | { 344 | this->errorinfo="找不到这个标识符哦,它确实已经定义了吗?"; 345 | return ERROR; 346 | } 347 | else if(iter->flag==CONST) 348 | { 349 | value=iter->value; 350 | sprintf(buffer,"%d",value); 351 | this->tempvar.prev_temp_varname=buffer; 352 | return VALUE; 353 | } 354 | else this->tempvar.prev_temp_varname=word; 355 | } 356 | 357 | else /*if(type==LPAREN)*/ 358 | { 359 | if(!(res=expression(lexical_analyzer,value))) return ERROR; 360 | if(lexical_analyzer.getsymtype()!=RPARENTYPE) 361 | { 362 | this->errorinfo="这里应该有一个右括号,表达式必须用一对括号扩起来"; 363 | return ERROR; 364 | } 365 | } 366 | return res; 367 | } 368 | 369 | -------------------------------------------------------------------------------- /func_lib.h: -------------------------------------------------------------------------------- 1 | #ifndef __FUNC_LIB_H 2 | #define __FUNC_LIB_H 3 | 4 | #define CHAR_CHARACTER 1 5 | #define CHAR_NUMBER 2 6 | #define CHAR_OTHER 3 7 | #define CHAR_NULL 4 8 | 9 | inline 10 | int judge_char_type(char c) 11 | { 12 | if(c==' '||c=='\t'||c=='\n') return CHAR_NULL; 13 | else if( (c>='A'&&c<='Z') || (c>='a'&&c<='z') ) return CHAR_CHARACTER; 14 | else if( c>='0'&&c<='9' ) return CHAR_NUMBER; 15 | else return CHAR_OTHER; 16 | } 17 | 18 | #endif 19 | 20 | -------------------------------------------------------------------------------- /getsym.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include"func_lib.h" 4 | #include"LexicalAnalyzer.class.h" 5 | #include"wordlist.h" 6 | 7 | bool LexicalAnalyzer::getsym(std::string &word,int& word_type) 8 | { 9 | char c; 10 | int c_type; 11 | const int WORD_MAX_LENGTH=10; 12 | const int NUM_MAX_LENGTH=14; 13 | word=""; 14 | word_type=0; 15 | 16 | do 17 | { 18 | if((c=this->inputreader->getchar())<=0) return false; 19 | c_type=judge_char_type(c); 20 | } 21 | while(c_type==CHAR_NULL); 22 | 23 | this->prevsymchar=this->cursymchar; 24 | this->prevsymline=this->cursymline; 25 | this->cursymchar=this->inputreader->get_curchar(); 26 | this->cursymline=this->inputreader->get_curline(); 27 | 28 | if(c_type==CHAR_CHARACTER) 29 | { 30 | word=c; 31 | while(word.size()inputreader->peekchar(); 34 | c_type=judge_char_type(c); 35 | if(c_type!=CHAR_CHARACTER && c_type!=CHAR_NUMBER) break; 36 | c=this->inputreader->getchar(); 37 | word+=c; 38 | } 39 | 40 | word_type=get_keyword(word); 41 | if(word_type==0) 42 | { 43 | word_type=IDENTTYPE; 44 | } 45 | } 46 | else if(c_type==CHAR_NUMBER) 47 | { 48 | word=c; 49 | while(word.size()inputreader->peekchar(); 52 | c_type=judge_char_type(c); 53 | if(c_type!=CHAR_NUMBER) break; 54 | c=this->inputreader->getchar(); 55 | word+=c; 56 | } 57 | word_type=NUMBERTYPE; 58 | } 59 | else/*if(c_type==CHAR_OTHER)*/ 60 | { 61 | word=c; 62 | switch(c) 63 | { 64 | case ':': 65 | case '>': 66 | case '<': 67 | if(this->inputreader->peekchar()=='=') 68 | { 69 | word+=this->inputreader->getchar(); 70 | } 71 | break; 72 | } 73 | 74 | word_type=get_operator(word); 75 | //if(word_type==0) error 76 | } 77 | return true; 78 | } 79 | -------------------------------------------------------------------------------- /intermediatecodelist.h: -------------------------------------------------------------------------------- 1 | #ifndef INTERMEDIATECODELIST_H 2 | #define INTERMEDIATECODELIST_H 3 | 4 | #define LPARAN '(' 5 | #define RPARAN ')' 6 | #define DELIMITER ' ' 7 | #define COLON ':' 8 | 9 | #endif /* INTERMEDIATECODELIST_H */ 10 | 11 | -------------------------------------------------------------------------------- /keyword.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | #include"keywordlist.h" 6 | #define KEYWORD_LENGTH 13 7 | 8 | int LexicalAnalyzer::get_keyword(std::string str) const 9 | { 10 | static const std::pair KEYWORDS_ARRAY[]={ std::make_pair(IFSYM,IFTYPE), 11 | std::make_pair(THENSYM,THENTYPE), 12 | std::make_pair(WHILESYM,WHILETYPE), 13 | std::make_pair(DOSYM,DOTYPE), 14 | std::make_pair(READSYM,READTYPE), 15 | std::make_pair(WRITESYM,WRITETYPE), 16 | std::make_pair(CALLSYM,CALLTYPE), 17 | std::make_pair(BEGINSYM,BEGINTYPE), 18 | std::make_pair(ENDSYM,ENDTYPE), 19 | std::make_pair(CONSTSYM,CONSTTYPE), 20 | std::make_pair(VARSYM,VARTYPE), 21 | std::make_pair(PROCSYM,PROCTYPE), 22 | std::make_pair(ODDSYM,ODDTYPE)}; 23 | 24 | static const std::map KEYWORDS(KEYWORDS_ARRAY,KEYWORDS_ARRAY+KEYWORD_LENGTH); 25 | 26 | for(int i=0;i::const_iterator iter=KEYWORDS.find(str); 28 | if(iter!=KEYWORDS.end()) return iter->second; 29 | else return 0; 30 | } 31 | -------------------------------------------------------------------------------- /keywordlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __KEYWORD_H 2 | #define __KEYWORD_H 3 | 4 | #define IFSYM "if" 5 | #define THENSYM "then" 6 | #define WHILESYM "while" 7 | #define DOSYM "do" 8 | #define READSYM "read" 9 | #define WRITESYM "write" 10 | #define CALLSYM "call" 11 | #define BEGINSYM "begin" 12 | #define ENDSYM "end" 13 | #define CONSTSYM "const" 14 | #define VARSYM "var" 15 | #define PROCSYM "procedure" 16 | #define ODDSYM "odd" 17 | 18 | #define IFTYPE 10 19 | #define THENTYPE 11 20 | #define WHILETYPE 12 21 | #define DOTYPE 13 22 | #define READTYPE 14 23 | #define WRITETYPE 15 24 | #define CALLTYPE 16 25 | #define BEGINTYPE 17 26 | #define ENDTYPE 18 27 | #define CONSTTYPE 19 28 | #define VARTYPE 20 29 | #define PROCTYPE 21 30 | #define ODDTYPE 22 31 | 32 | #define JUMP "jump" 33 | #define RETURN "return" 34 | #define HALT "halt" 35 | 36 | #define DECLARE "declare" 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include"LexicalAnalyzer.class.h" 5 | #include"SyntacticAnalyzer.class.h" 6 | 7 | int main(int argc,char* argv[]) 8 | { 9 | LexicalAnalyzer lexical_analyzer; 10 | SyntacticAnalyzer syntactic_analyzer; 11 | std::string outputfilename="",inputfilename=""; 12 | int i; 13 | 14 | for(i=1;i 2 | #include 3 | #include"LexicalAnalyzer.class.h" 4 | #include"operatorlist.h" 5 | #define OPERATOR_LENGTH 16 6 | 7 | int LexicalAnalyzer::get_operator(const std::string& str) const 8 | { 9 | static const std::pair OPERATORS_ARRAY[]={ std::make_pair(BECOMESOPER,BECOMESTYPE), 10 | std::make_pair(GEQOPER,GEQTYPE), 11 | std::make_pair(GTROPER,GTRTYPE), 12 | std::make_pair(LEQOPER,LEQTYPE), 13 | std::make_pair(LSSOPER,LSSTYPE), 14 | std::make_pair(PLUSOPER,PLUSTYPE), 15 | std::make_pair(MINUSOPER,MINUSTYPE), 16 | std::make_pair(TIMESOPER,TIMESTYPE), 17 | std::make_pair(SLASHOPER,SLASHTYPE), 18 | std::make_pair(EQLOPER,EQLTYPE), 19 | std::make_pair(NEQOPER,NEQTYPE), 20 | std::make_pair(COMMAOPER,COMMATYPE), 21 | std::make_pair(PERIODOPER,PERIODTYPE), 22 | std::make_pair(SEMICOLONOPER,SEMICOLONTYPE), 23 | std::make_pair(LPARENOPER,LPARENTYPE), 24 | std::make_pair(RPARENOPER,RPARENTYPE)}; 25 | 26 | static const std::map OPERATORS(OPERATORS_ARRAY,OPERATORS_ARRAY+OPERATOR_LENGTH); 27 | 28 | std::map::const_iterator iter=OPERATORS.find(str); 29 | if(iter!=OPERATORS.end()) return iter->second; 30 | else return 0; 31 | } 32 | -------------------------------------------------------------------------------- /operatorlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __OPERATORLIST_H 2 | #define __OPERATORLIST_H 3 | 4 | #define BECOMESOPER ":=" 5 | #define GEQOPER ">=" 6 | #define GTROPER ">" 7 | #define LEQOPER "<=" 8 | #define LSSOPER "<" 9 | #define PLUSOPER "+" 10 | #define MINUSOPER "-" 11 | #define TIMESOPER "*" 12 | #define SLASHOPER "/" 13 | #define EQLOPER "=" 14 | #define NEQOPER "#" 15 | #define COMMAOPER "," 16 | #define PERIODOPER "." 17 | #define SEMICOLONOPER ";" 18 | #define LPARENOPER "(" 19 | #define RPARENOPER ")" 20 | 21 | #define BECOMESTYPE 100 22 | #define GEQTYPE 101 23 | #define GTRTYPE 102 24 | #define LEQTYPE 103 25 | #define LSSTYPE 104 26 | #define PLUSTYPE 105 27 | #define MINUSTYPE 106 28 | #define TIMESTYPE 107 29 | #define SLASHTYPE 108 30 | #define EQLTYPE 109 31 | #define NEQTYPE 110 32 | #define COMMATYPE 111 33 | #define PERIODTYPE 112 34 | #define SEMICOLONTYPE 113 35 | #define LPARENTYPE 114 36 | #define RPARENTYPE 115 37 | 38 | #endif 39 | 40 | -------------------------------------------------------------------------------- /program.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"keywordlist.h" 5 | #include"operatorlist.h" 6 | #include"wordlist.h" 7 | 8 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::analyze(LexicalAnalyzer& lexical_analyzer) 9 | { 10 | if(!subprogram(lexical_analyzer)) return ERROR; 11 | if(lexical_analyzer.peeksymtype()!=PERIODTYPE) 12 | { 13 | if(lexical_analyzer.peeksymtype()==0) this->errorinfo="程序有错,这个程序到这里看上去应该已经结束了,但其实不是。是不是少了运算符或漏了左括号?"; 14 | else this->errorinfo="必须在程序结尾加一个句号,不要问我为神马,这就是语法!"; 15 | return ERROR; 16 | } 17 | else 18 | { 19 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(SyntacticAnalyzer::IntermediateCodeNode(HALT)); 20 | } 21 | return RIGHT; 22 | } 23 | 24 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::subprogram(LexicalAnalyzer& lexical_analyzer) 25 | { 26 | int type=lexical_analyzer.peeksymtype(); 27 | 28 | if(type==CONSTTYPE) 29 | { 30 | if(!constsym(lexical_analyzer)) return ERROR; 31 | type=lexical_analyzer.peeksymtype(); 32 | } 33 | if(type==VARTYPE) 34 | { 35 | if(!varsym(lexical_analyzer)) return ERROR; 36 | type=lexical_analyzer.peeksymtype(); 37 | } 38 | if(type==PROCTYPE) 39 | { 40 | do 41 | { 42 | if(!procsym(lexical_analyzer)) return ERROR; 43 | }while((type=lexical_analyzer.peeksymtype())==PROCTYPE); 44 | } 45 | 46 | return statement(lexical_analyzer); 47 | } 48 | 49 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::constsym(LexicalAnalyzer& lexical_analyzer) 50 | { 51 | int type; 52 | SyntacticAnalyzer::IdentStackNode newnode(CONST); 53 | if(lexical_analyzer.getsymtype()!=CONSTTYPE) 54 | { 55 | this->errorinfo="这里应该是一个const语句"; 56 | return ERROR; 57 | } 58 | do 59 | { 60 | if(lexical_analyzer.getsymtype()!=IDENTTYPE) 61 | { 62 | this->errorinfo="这里应该是一个标识符,例如:CONST X=6,Y=4;"; 63 | return ERROR; 64 | } 65 | else if(this->ident_stack_find(lexical_analyzer.getprevsymword().c_str(),QUERY_CUR_PROC)!=this->ident_stack.end()) 66 | { 67 | this->errorinfo="我说,常量名好像有重复啊,你检查下,看看本级的,上一级的常量或者变量有没有叫这名儿的"; 68 | return ERROR; 69 | } 70 | else newnode.ident=lexical_analyzer.getprevsymword(); 71 | 72 | if(lexical_analyzer.getsymtype()!=EQLTYPE) 73 | { 74 | this->errorinfo="这里应该是一个等于符号,例如:CONST X=6,Y=4;"; 75 | return ERROR; 76 | } 77 | if(lexical_analyzer.getsymtype()!=NUMBERTYPE) 78 | { 79 | this->errorinfo="这里应该是一个数字,例如:CONST X=6,Y=4;"; 80 | return ERROR; 81 | } 82 | else 83 | { 84 | sscanf(lexical_analyzer.getprevsymword().c_str(),"%d",&newnode.value); 85 | this->ident_stack.push_back(newnode); 86 | } 87 | }while((type=lexical_analyzer.getsymtype())==COMMATYPE); 88 | 89 | if(type==SEMICOLONTYPE) return RIGHT; 90 | else 91 | { 92 | this->errorinfo="const语句必须以分号结尾,例如:CONST X=6,Y=4; 请留意末尾的分号"; 93 | return ERROR; 94 | } 95 | } 96 | 97 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::varsym(LexicalAnalyzer& lexical_analyzer) 98 | { 99 | int type; 100 | SyntacticAnalyzer::IdentStackNode newnode(VAR); 101 | if(lexical_analyzer.getsymtype()!=VARTYPE) 102 | { 103 | this->errorinfo="这里应该是一个var语句"; 104 | return ERROR; 105 | } 106 | do 107 | { 108 | if(lexical_analyzer.getsymtype()!=IDENTTYPE) 109 | { 110 | this->errorinfo="这里应该是一个标识符,例如:VAR X,Y,Z;"; 111 | return ERROR; 112 | } 113 | else if(this->ident_stack_find(lexical_analyzer.getprevsymword().c_str(),QUERY_CUR_PROC)!=this->ident_stack.end()) 114 | { 115 | this->errorinfo="我说,变量名好像有重复啊,你检查下,看看本级的,上一级的变量或者常量有没有叫这名儿的"; 116 | return ERROR; 117 | } 118 | else 119 | { 120 | newnode.ident=lexical_analyzer.getprevsymword(); 121 | this->ident_stack.push_back(newnode); 122 | this->declare_new_var(newnode.ident); 123 | } 124 | }while((type=lexical_analyzer.getsymtype())==COMMATYPE); 125 | if(type==SEMICOLONTYPE) return RIGHT; 126 | else 127 | { 128 | this->errorinfo="var语句必须以分号结尾,例如:VAR X,Y,Z; 请留意末尾的分号"; 129 | return ERROR; 130 | } 131 | } 132 | 133 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::procsym(LexicalAnalyzer& lexical_analyzer) 134 | { 135 | std::string word; 136 | if(lexical_analyzer.getsymtype()!=PROCTYPE) 137 | { 138 | this->errorinfo="这里应该是一个procedure语句"; 139 | return ERROR; 140 | } 141 | 142 | if(lexical_analyzer.getsymtype()!=IDENTTYPE) 143 | { 144 | this->errorinfo="这里应该有一个标识符,作为procedure的名字,例如:PROCEDURE PROC;"; 145 | return ERROR; 146 | } 147 | else if(this->procedure_find(word=lexical_analyzer.getprevsymword())) 148 | { 149 | this->errorinfo="过程名好像重复了耶!要记住哦,PL/0不能出现重复的过程名哦!一定不能重复哦!乖!"; 150 | return ERROR; 151 | } 152 | else 153 | { 154 | this->ident_stack.push_back(SyntacticAnalyzer::IdentStackNode(BOUND,this->cur_procedure_name,this->cur_procedure_index)); 155 | this->cur_procedure_name=word; 156 | this->cur_procedure_index=intermediate_code_deque_vector.size(); 157 | this->intermediate_code_deque_vector.push_back(std::deque()); 158 | this->procedure_vector.push_back(word); 159 | } 160 | 161 | if(lexical_analyzer.getsymtype()!=SEMICOLONTYPE) 162 | { 163 | this->errorinfo="这里应该有一个分号,作为procedure声明和内容的分隔符,例如:PROCEDURE PROC; 请留意末尾的分号"; 164 | return ERROR; 165 | } 166 | if(!subprogram(lexical_analyzer)) return ERROR; 167 | else 168 | { 169 | this->ident_stack_clear(); 170 | } 171 | 172 | if(lexical_analyzer.getsymtype()!=SEMICOLONTYPE) 173 | { 174 | this->errorinfo="这里应该有一个分号,作为一个procedure结束,我知道加一个分号很无聊也不能促进减肥,但是这是语法,是规定,只要你爸不是李刚,就必需遵守这个规定"; 175 | return ERROR; 176 | } 177 | return RIGHT; 178 | } 179 | -------------------------------------------------------------------------------- /statement.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include"LexicalAnalyzer.class.h" 3 | #include"SyntacticAnalyzer.class.h" 4 | #include"keywordlist.h" 5 | #include"operatorlist.h" 6 | #include"wordlist.h" 7 | 8 | #define VALUEBUFFERLENGTH 10 9 | 10 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::statement(LexicalAnalyzer& lexical_analyzer) 11 | { 12 | int type=lexical_analyzer.peeksymtype(); 13 | switch(type) 14 | { 15 | case IDENTTYPE: return ident(lexical_analyzer); 16 | case CALLTYPE: return callsym(lexical_analyzer); 17 | case BEGINTYPE: return beginsym(lexical_analyzer); 18 | case IFTYPE: return ifsym(lexical_analyzer); 19 | case WHILETYPE: return whilesym(lexical_analyzer); 20 | case READTYPE: return readsym(lexical_analyzer); 21 | case WRITETYPE: return writesym(lexical_analyzer); 22 | } 23 | 24 | return RIGHT; 25 | } 26 | 27 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::ident(LexicalAnalyzer& lexical_analyzer) 28 | { 29 | int value; 30 | SyntacticAnalyzer::SyntacticAnalyzerResult res; 31 | SyntacticAnalyzer::IntermediateCodeNode newcodenode(BECOMESOPER); 32 | std::deque::const_iterator iter; 33 | std::string varname; 34 | if(lexical_analyzer.getsymtype()!=IDENTTYPE) 35 | { 36 | this->errorinfo="这里应该有一个标识符,参考赋值语句的语法:X:=2;"; 37 | return ERROR; 38 | } 39 | else if((iter=this->ident_stack_find(lexical_analyzer.getprevsymword().c_str(),QUERY_ALL_PROC))==this->ident_stack.end()) 40 | { 41 | this->errorinfo="找不到这个标识符哦,它确实已经定义了吗?"; 42 | return ERROR; 43 | } 44 | else if(iter->flag!=VAR) 45 | { 46 | this->errorinfo="喂喂喂!这不是变量,是常量吧!你怎么能对常量赋值呢??"; 47 | return ERROR; 48 | } 49 | else varname=iter->ident; 50 | 51 | if(lexical_analyzer.getsymtype()!=BECOMESTYPE) 52 | { 53 | this->errorinfo="这里应该是一个赋值符号 := ,参考赋值语句的语法:X:=2;"; 54 | return ERROR; 55 | } 56 | if((res=expression(lexical_analyzer,value))==ERROR) 57 | { 58 | return ERROR; 59 | } 60 | else 61 | { 62 | newcodenode.oper1=this->tempvar.prev_temp_varname; 63 | newcodenode.oper2=varname; 64 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 65 | } 66 | } 67 | 68 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::callsym(LexicalAnalyzer& lexical_analyzer) 69 | { 70 | std::string word; 71 | if(lexical_analyzer.getsymtype()!=CALLTYPE) 72 | { 73 | this->errorinfo="这里应该是一个call语句,call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 74 | return ERROR; 75 | } 76 | 77 | if(lexical_analyzer.getsymtype()!=IDENTTYPE) 78 | { 79 | this->errorinfo="这个应该是一个标识符,否则我怎么知道你要call谁?call语句的语法是这样紫滴:CALL NIMEI; 其中NIMEI是个过程的名字,事先用procedure语句定义它"; 80 | return ERROR; 81 | } 82 | else if(!this->procedure_find(word=lexical_analyzer.getprevsymword())) 83 | { 84 | this->errorinfo="这神马过程啊,我真的不认识这货!"; 85 | return ERROR; 86 | } 87 | else 88 | { 89 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(SyntacticAnalyzer::IntermediateCodeNode(CALLSYM,word)); 90 | } 91 | 92 | return RIGHT; 93 | } 94 | 95 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::beginsym(LexicalAnalyzer& lexical_analyzer) 96 | { 97 | if(lexical_analyzer.getsymtype()!=BEGINTYPE) 98 | { 99 | this->errorinfo="这里应该有一个begin语句的吧"; 100 | return ERROR; 101 | } 102 | if(!statement(lexical_analyzer)) return ERROR; 103 | while(lexical_analyzer.peeksymtype()!=ENDTYPE) 104 | { 105 | if(lexical_analyzer.getsymtype()!=SEMICOLONTYPE) 106 | { 107 | this->errorinfo="这里必须有一个分号的啊,如果BEGIN..END语句中有多于一句语句的话,每句语句都必须用分号分隔"; 108 | return ERROR; 109 | } 110 | if(!statement(lexical_analyzer)) return ERROR; 111 | } 112 | lexical_analyzer.getsymtype(); 113 | return RIGHT; 114 | } 115 | 116 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::ifsym(LexicalAnalyzer& lexical_analyzer) 117 | { 118 | bool value; 119 | std::string point; 120 | SyntacticAnalyzer::SyntacticAnalyzerResult res; 121 | if(lexical_analyzer.getsymtype()!=IFTYPE) 122 | { 123 | this->errorinfo="这里应该是一个if语句"; 124 | return ERROR; 125 | } 126 | 127 | point=this->temppoint.next(); 128 | 129 | if(!(res=condition(lexical_analyzer,point,value))) return ERROR; 130 | 131 | //这里不生成任何条件语句,因为condition会为我们完成的 132 | 133 | if(lexical_analyzer.getsymtype()!=THENTYPE) 134 | { 135 | this->errorinfo="喂喂..if语句没有跟then,你这个if语句是干啥的?if语句参考语法:IF X=0 THEN X:=1;"; 136 | return ERROR; 137 | } 138 | if(!statement(lexical_analyzer)) return ERROR; 139 | else if(res!=VALUE || !value) //和生成point的逻辑条件完全一致 140 | { 141 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back( 142 | SyntacticAnalyzer::IntermediateCodeNode(DECLARE,point)); 143 | } 144 | return RIGHT; 145 | } 146 | 147 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::whilesym(LexicalAnalyzer& lexical_analyzer) 148 | { 149 | bool value; 150 | std::string point1,point2; 151 | SyntacticAnalyzer::SyntacticAnalyzerResult res; 152 | if(lexical_analyzer.getsymtype()!=WHILETYPE) 153 | { 154 | this->errorinfo="这里应该是一个while语句"; 155 | return ERROR; 156 | } 157 | 158 | point1=this->temppoint.next(); 159 | point2=this->temppoint.next(); 160 | 161 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back( 162 | SyntacticAnalyzer::IntermediateCodeNode(DECLARE,point1)); 163 | 164 | if(!(res=condition(lexical_analyzer,point2,value))) return ERROR; 165 | if(lexical_analyzer.getsymtype()!=DOTYPE) 166 | { 167 | this->errorinfo="这里应该有一个do的,没有do,单单一个while有神马意义呢?"; 168 | return ERROR; 169 | } 170 | if(!statement(lexical_analyzer)) return ERROR; 171 | 172 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back( 173 | SyntacticAnalyzer::IntermediateCodeNode(JUMP,point1)); 174 | 175 | if(res!=VALUE || !value) //和生成point的逻辑条件完全一致 176 | { 177 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back( 178 | SyntacticAnalyzer::IntermediateCodeNode(DECLARE,point2)); 179 | } 180 | return RIGHT; 181 | } 182 | 183 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::readsym(LexicalAnalyzer& lexical_analyzer) 184 | { 185 | int type1=lexical_analyzer.getsymtype(),type2; 186 | std::deque::const_iterator iter; 187 | SyntacticAnalyzer::IntermediateCodeNode newcodenode(READSYM); 188 | 189 | if(type1!=READTYPE) 190 | { 191 | this->errorinfo="这里应该是一个函数"; 192 | return ERROR; 193 | } 194 | if(lexical_analyzer.getsymtype()!=LPARENTYPE) 195 | { 196 | this->errorinfo="这是函数诶!他的语法应该是 READ(X); 你貌似漏了左括号"; 197 | return ERROR; 198 | } 199 | do{ 200 | if(lexical_analyzer.getsymtype()!=IDENTTYPE) 201 | { 202 | this->errorinfo="函数里面要有标识符的啊,他的语法应该是 READ(X,Y,Z);"; 203 | return ERROR; 204 | } 205 | else if((iter=this->ident_stack_find(lexical_analyzer.getprevsymword().c_str(),QUERY_ALL_PROC))==this->ident_stack.end()) 206 | { 207 | this->errorinfo="找不到这个标识符哦,它确实已经定义了吗?"; 208 | return ERROR; 209 | } 210 | else if(iter->flag!=VAR) 211 | { 212 | this->errorinfo="喂喂喂!这不是变量,是常量吧!你怎么能对常量赋值呢??"; 213 | return ERROR; 214 | } 215 | else 216 | { 217 | newcodenode.oper1=iter->ident; 218 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 219 | } 220 | }while((type2=lexical_analyzer.getsymtype())==COMMATYPE); 221 | if(type2==RPARENTYPE) return RIGHT; 222 | else 223 | { 224 | this->errorinfo="函数参数要用右括号扩起来的啊,你加右括号了吗"; 225 | return ERROR; 226 | } 227 | } 228 | 229 | SyntacticAnalyzer::SyntacticAnalyzerResult SyntacticAnalyzer::writesym(LexicalAnalyzer& lexical_analyzer) 230 | { 231 | int value,type1=lexical_analyzer.getsymtype(),type2; 232 | SyntacticAnalyzer::SyntacticAnalyzerResult res; 233 | SyntacticAnalyzer::IntermediateCodeNode newcodenode(WRITESYM); 234 | char buffer[VALUEBUFFERLENGTH]; 235 | 236 | if(type1!=WRITETYPE) 237 | { 238 | this->errorinfo="这里应该是一个函数"; 239 | return ERROR; 240 | } 241 | if(lexical_analyzer.getsymtype()!=LPARENTYPE) 242 | { 243 | this->errorinfo="这是函数诶!他的语法应该是 WRITE(Y); 吧,你貌似漏了左括号"; 244 | return ERROR; 245 | } 246 | do{ 247 | if((res=expression(lexical_analyzer,value))==ERROR) 248 | { 249 | return ERROR; 250 | } 251 | else 252 | { 253 | if(res==RIGHT) newcodenode.oper1=this->tempvar.prev_temp_varname; 254 | else /*res==VALUE*/ 255 | { 256 | sprintf(buffer,"%d",value); 257 | newcodenode.oper1=buffer; 258 | } 259 | this->intermediate_code_deque_vector[this->cur_procedure_index].push_back(newcodenode); 260 | } 261 | }while((type2=lexical_analyzer.getsymtype())==COMMATYPE); 262 | if(type2==RPARENTYPE) return RIGHT; 263 | else 264 | { 265 | this->errorinfo="函数参数要用右括号扩起来的啊,你加右括号了吗"; 266 | return ERROR; 267 | } 268 | } 269 | -------------------------------------------------------------------------------- /wordlist.h: -------------------------------------------------------------------------------- 1 | #ifndef __WORDLIST_H 2 | #define __WORDLIST_H 3 | 4 | #define IDENTTYPE 1 5 | #define NUMBERTYPE 2 6 | 7 | #endif 8 | 9 | --------------------------------------------------------------------------------