Материалы (5) (1115032), страница 2
Текст из файла (страница 2)
ихсодержимое не зависит от исходной программы.Таблица TID формируется в процессе анализа.Ident–––––Table_identN (0…N)char * name;bool declare;type_of_lex type;bool assign;int value;–––++89Ident * p;intsize;inttop;Ident &operator[](int k);int put(constchar *buf);Lex––++type_of_lext_lex;intv_lex;type_of_lex get_type ();intget_value( );friend ostream&operator << (ostream&s, Lex l );Scanner–$–$–$–$++–char *TW [];type_of_lex words[];char *TD [];type_of_lex dlms[];Scanner(const char * program);Lex get_lex ();look(const char * buf, char ** list);…90класс Lex:class Lex {type_of_lex t_lex;intv_lex;public:Lex ( type_of_lex t = LEX_NULL, int v = 0) {t_lex = t;v_lex = v;}type_of_lex get_type () { return t_lex; }intget_value () { return v_lex; }friend ostream& operator << (ostream &s, Lex l){s << '(' << l.t_lex << ',' << l.v_lex <<");" ;return s;}};91Класс Ident:class Ident {char * name;booldeclare;type_of_lex type;boolassign;intvalue;public:Ident() { declare = false; assign = false; }char * get_name () { return name; }voidput_name (const char *n){name = new char [strlen(n)+1];strcpy(name,n);}bool get_declare () { return declare; }void put_declare () { declare = true; }type_of_lex get_type() { return type; }void put_type(type_of_lex t) { type = t; }bool get_assign () { return assign; }void put_assign (){ assign = true; }intget_value () { return value; }void put_value (int v){ value = v; }};92Класс tabl_ident:class tabl_ident{ident *p;int size;int top;public:tabl_ident(int max_size){ p=new ident[size=max_size]; top=1;}~tabl_ident(){delete []p;}ident& operator[](int k){return p[k];}int put(const char *buf);};int tabl_ident::put(const char *buf){for (int j=1; j<top; j++)if(!strcmp(buf,p[j].get_name())) return j;p[top].put_name(buf); top++;return top-1;};93Класс Scanner:class Scanner {enum state{H,IDENT, NUMB, COM, ALE, DELIM, NEQ };static char * TW [];static type_of_lex words [];static char * TD [];static type_of_lex dlms [];state CS;FILE * fp;charc;charbuf [ 80 ];intbuf_top;voidclear () {buf_top = 0;for (int j = 0; j < 80; j++ )buf[j] = '\0';}94voidint}voidadd () { buf [ buf_top ++ ] = c; }look (const char *buf, char **list) {int i = 0;while (list[i]) {if (!strcmp(buf, list[i])) return i;i++;}return 0;gc () { c = fgetc (fp); }public:Scanner (const char * program){fp = fopen ( program, "r" ); CS = H;clear(); gc();}Lex get_lex ();};95Таблицы лексем М-языка:char * Scanner:: TW [] = {////NULL,"and","begin","bool","do","else","end",0123456"if","false","int","not","or","program","read",78910111213"then","true","var","while","write"14//};15161718char * Scanner:: TD [] = {NULL,";", "@", ",", ":", ":=", "(", ")",01234567//"=","<",">","+","-","*","/","<=","!=",">="89101112 1314151617//};tabl_identTID(100);96type_of_lexScanner::words [] = {LEX_NULL, LEX_AND, LEX_BEGIN,LEX_BOOL, LEX_DO, LEX_ELSE, LEX_END, LEX_IF,LEX_FALSE, LEX_INT,LEX_NOT, LEX_OR,LEX_PROGRAM, LEX_READ, LEX_THEN, LEX_TRUE,LEX_VAR, LEX_WHILE, LEX_WRITE, LEX_NULL};type_of_lexScanner::dlms [] = {LEX_NULL, LEX_FIN,LEX_SEMICOLON,LEX_COMMA, LEX_COLON, LEX_ASSIGN, LEX_LPAREN,LEX_RPAREN, LEX_EQ,LEX_LSS, LEX_GTR, LEX_PLUS,LEX_MINUS, LEX_TIMES, LEX_SLASH, LEX_LEQ,LEX_NEQ, LEX_GEQ, LEX_NULL};97Диаграмма состояний для лексического анализатораgc();‘_‘Hбукваclear(); add(); gc();add();gc()буква,цифраIDENTj=look(buf,TW);Lex(words[j],j); илиj=TID.put(buf); Lex(LEX_ID, j);d=d*10+(c–’0’); gc();цифрацифраd=c –’0’; gc();NUMBLex(LEX_NUM, d);gc();{gc();COM}gc();⊥ERR98ДС ЛА (продолжение):, <, >clear(); add(); gc();ALE=j=look(buf,TD); Lex(dlms[j], j)add(); gc(); j=look(buf,TD); Lex(dlms[j], j);⊥Lex (LEX_FIN)!gc();NEQ =gc(); Lex (LEX_NEQ)ERRDELIM+, -, *, /, ;, ,, (, ), =clear(); add(); gc(); j=look(buf,TD);Lex(dlms[j], j);99Lex Scanner::get_lex (){int d, j;CS = H;do {switch(CS) {case H:if(c ==' ' || c =='\n' || c=='\r' || c =='\t') gc();elseif(isalpha(c)) {clear(); add(); gc(); CS = IDENT;}elseif ( isdigit(c) ) { d = c - '0'; gc(); CS = NUMB; }elseif ( c== '{' ) { gc(); CS = COM; }elseif (c== ':' || c== '<' || c== '>') {clear(); add();gc(); CS = ALE; }elseif (c == '@') return Lex(LEX_FIN);elseif (c == '!') {clear(); add(); gc(); CS = NEQ; }else CS = DELIM;break;100case IDENT:if ( isalpha(c) || isdigit(c) ) {add(); gc();}elseif ( j = look (buf, TW) ) return Lex (words[j], j);else { j = TID.put(buf); return Lex (LEX_ID, j);}break;case NUMB:if ( isdigit(c) ) {d = d * 10 + (c - '0'); gc(); }else return Lex ( LEX_NUM, d);break;case COM:if ( c == '}' ) { gc(); CS = H; }elseif (c == '@' || c == '{' ) throw c;else gc();break;case ALE:if (c=='=') { add(); gc(); j = look ( buf, TD );return Lex ( dlms[j], j);}else {j = look (buf, TD); return Lex ( dlms[j],j );}break;101case NEQ:case DELIM:if (c == '=') {add(); gc(); j = look ( buf, TD );return Lex ( LEX_NEQ, j ); }else throw '!';break;clear(); add();if (j = look(buf, TD)) {gc(); return Lex (dlms[j], j);}else throw c;break;} //end of switch} while (true);}// end of getlex().