1、扫描程序用到:scanner.h,scanner.cpp scanner.h:声明词法状态,词法分析/DFA中的状态typedef enum START = 1, INNUM, INID, INDBSYM, DONE DFAState;/定义的Token的类型(31种),分别对应于else、if、int、return、void、while、+、-、*、/、=、=、!=、=、;、,、(、)、/*、*/、num、id、错误、结束 ELSE = 1,IF,INT,RETURN,VOID,WHILE, PLUS,MINUS,TIMES,OVER,LT,LEQ,GT,GEQ,EQ,NEQ,ASSIGN,
2、SEMI,COMMA,LPAREN,RPAREN,LMBRACKET,RMBRACKET,LBBRACKET,RBBRACKET,LCOMMENT,RCOMMENT, NUM,ID,ERROR,ENDFILE TokenType;/定义的Token结构体,包括类型、对应的串、所在代码的行号struct Token TokenType tokenType; string tokenString; int lineNo; /每种TokenType对应的串,如tokenTypeStringELSE=ELSEconst string tokenTypeString32 = OTHER, IFINTRE
3、TURNVOIDWHILEPLUSMINUSTIMESOVERLTLEQGTGEQEQNEQASSIGNSEMICOMMALPARENRPARENLMBRACKETRMBRACKETLBBRACKETRBBRACKETLCOMMENTRCOMMENTNUMIDERRORENDFILEclass Scanner:定义scanner.cpp中函数 scanner.cpp文件函数说明void Scanner : scan():设置输出结果界面以及设置各种输出状态。 if(scanSuccess=false) cout词法分析出错!endl; else词法分析成功了! printToken();/*输
4、出Token到文件Token.txt中*/正在删除注释 deleteComments()TokenType Scanner : returnTokenType(string s)/返回Token的类型DFAState Scanner : charType(char c)/返回字符的类型 ENDFILE,ERROR, IF,ELSE,INT,RETURN,VOID,WHILE, /关键字ID,NUM, ASSIGN,PLUS,MINUS,TIMES,OVER,EQ,UEQ,LT,LPAREN,RPAREN,SEMI,BT,LQ,BQ, DOU,LZGH,RZGH,LDGH,RDGH,/特殊字符:
5、= + - * / = != declaration-list 2.declaration-list-declaration-list declaration | declaration 3.declaration-var-declaration|fun-declaration 4.var-declaration-type-specifier ID;|type-specfier IDNUM 5.type-specifier-int|void 6.fun-specifier ID(parans) compound-stmt 7.params-params-list|void 8.param-li
6、st-param-list,param|param 9.param-type-specifier ID|type-specifier ID pound-stmt-local-declarations statement-list 11.local-declarations-local-declarations var-declaration|empty 12.statement-list-statement-list statement|empty 13.statement-expression-stmt|compound-stmt|selection-stmt|iteration-stmt|
7、return-stmt 14.expression-stmt-expression;|; 15.selection-stmt-if(expression)statement|if(expression)statement else statement 16.iteration-stmt-while(expression)statement 17.return-stmt-return ;|return expression; 18.expression-var=expression|simple-expression 19.var-ID|IDexpression 20.simple-expres
8、sion-additive-expression relop additive-expression|additive-expression 21.relop-=|=|=|!= 22.additive-expression-additive-expression addop term|term 23.addop-+|- 24.term-term mulop factor|factor 25.mulop-*|/ 26.factor-(expression)|var|call|NUM 27.call-ID(args) 28.args-arg-list|empty 29.arg-list-arg-l
9、ist,expression|expression2.1.2语法分析程序流程图 语法分析程序包括:parser.cpp,parser.h parser.cpp: Parser : Parser()/界面设计 Token Parser : getToken()/获取scanner中保存在TokenList数组中的Token,并且每次获取完之后数组下标指向下一个void Parser : syntaxError(string s)/出错处理 match(TokenType ex)/匹配出错TreeNode * Parser : declaration(void)/类型匹配错误 param_list
10、(TreeNode * k)/k可能是已经被取出来的VoidK,但又不是(void)类型的参数列表,所以一直传到param中去,作为其一个子节点 parse.h:对parse.c的函数声明 /19种节点类型,分别表示int、id、void、数值、变量声明、数组声明、函数声明、函数声明参数列表、函数声明参数、复合语句体、if、while、return、赋值、运算、数组元素、函数调用、函数调用参数列表、未知节点typedef enum IntK, IdK, VoidK, ConstK, Var_DeclK, Arry_DeclK, FunK, ParamsK, ParamK, CompK, Sel
11、ection_StmtK, Iteration_StmtK, Return_StmtK, AssignK, OpK, Arry_ElemK, CallK, ArgsK, UnkownK Nodekind;typedef enum Void,Integer ExpType;ofstream fout_Tree(tokenTree.txt);/输出语法树到文件/treeNode定义 包括子节点、兄弟节点、所处行号、节点类型、属性、表达式返回类型typedef struct treeNode TreeNode * newNode(Nodekind k);/根据节点类型新建节点 TreeNode *
12、declaration_list(void); TreeNode * declaration(void); TreeNode * params(void); TreeNode * param_list(TreeNode * k); TreeNode * param(TreeNode * k); TreeNode * compound_stmt(void); TreeNode * local_declaration(void); TreeNode * statement_list(void); TreeNode * statement(void); TreeNode * expression_s
13、tmt(void); TreeNode * selection_stmt(void); TreeNode * iteration_stmt(void); TreeNode * return_stmt(void); TreeNode * expression(void); TreeNode * var(void); TreeNode * simple_expression(TreeNode * k); TreeNode * additive_expression(TreeNode * k); TreeNode * term(TreeNode * k); TreeNode * factor(Tre
14、eNode * k); TreeNode * call(TreeNode * k); TreeNode * args(void);3. 程序代码实现按文件列出主要程序代码, 添加必要的注释.Scanner.cpp:#include iostreamfstreamstring#include scanner.h#includeusing namespace std;/*Name: 词法分析器Copyright:Author: XXXDate: 19-05-14 12:00Description: 提取出token*/Scanner : Scanner() scanSuccess = true;
15、charIndex = 0; str = ; commentFlag = true; sourseString = lineCount = 0; scan() cout开始词法分析. bool doubleSym = false; getSourseStringFromFile(sourseFile.txt int state = START; char ch; while(state6) ch = getNextChar(); if(0=ch) Token t; t.lineNo = lineCount; t.tokenString = t.tokenType = ENDFILE; toke
16、nList.push_back(t); break; if(START=state)/初始状态和空格 state = charType(ch); if(state!=START) str += ch; else if(INNUM=state)/digit=INNUM) state = DONE; else else if(INID=state)/letter=INID) else if(INDBSYM=state)/除了=!之外的各种符号 if(= doubleSym = true; doubleSym = false; state = DONE; if(DONE=state)/接收状态 in
17、t tp = 0;n tp = 1; t.lineNo = lineCount-tp; t.tokenString = str; t.tokenType = returnTokenType(str); if(ERROR=t.tokenType) scanSuccess = false; int lastState = charType(strstr.length()-1); if(lastState=INNUM | lastState=INID | (lastState=INDBSYM & doubleSym=false) backToLastChar(); str = state = STA
18、RT; if(doubleSym=true) /输出Token到文件Token.txt中Token Scanner : getTokenAt(int tokenIndex) Token token; token.lineNo = lineCount; token.tokenString = token.tokenType = ENDFILE; if(tokenIndextokenList.size() token = tokenList.at(tokenIndex+); return token; getSourseStringFromFile(string path) ifstream fi
19、n(path.c_str(); string temp; while(getline(fin,temp) sourseString += temp; sourseString += fin.close();正在删除注释. ofstream fout_Sourse( int state = 1;=ch)/文件结束 if(1=state)/ state = 2; state = 1; fout_Soursech; else if(2=state)* state = 3; commentFlag = false; / else if(3=state) state = 4; else if(4=state) else if( state = 5; if(5=state)/结束状态,处理 commentFlag = true; state = 1; if(!commentFlag)注释错误,没有结束符! scanSuccess = false;注释已经成功删除! TokenType t; if(s=else) t = ELSE; else if(s=if t = IF;int t = INT;return t = RETURN;void t = VOID;while t = WHILE;+ t = PLUS; els