有空再来写注释^o^ 测试用Pascal代码片断 begin ab2a:=9; if x>=0 then x:=x+1; while a=0 do b:=a*x/33455; end # --------------------------------------------------------------------- 测试结果 syn |value ________|________ 1 |begin 10 |ab2a 18 |:= 11 |9 26 |; 2 |if 10 |x 24 |>= 11 |0 3 |then 10 |x 18 |:= 10 |x 14 |+ 11 |1 26 |; 4 |while 10 |a 25 |= 11 |0 5 |do 10 |b 18 |:= 10 |a 16 |* 10 |x 17 |/ 11 |33455 26 |; 6 |end 0 |# Press any key to continue 分析器的C代码------------------------------------------------------------------------------------------ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define MAX_WD_LEN 255 #define MAX_INT 32767 #define MAX_SRC_LEN 1000 #define MAX_WD_CNT 100 #define KWD_CNT 6 /************************************************/ union value_type{ int d; char c; char s[MAX_WD_LEN]; }; typedef struct{ int syn; union value_type value; }word_type; /************************************************/ char *keywords[20]={"begin","if","then","while","do","end"}; char source[MAX_SRC_LEN]; word_type word_stack[MAX_WD_CNT]; int line=1,wtop=0,ip=0; /************************************************/ void p_word_stack(){ int i;word_type w; printf("syn\t|value\n"); printf("________|________\n"); for(i=0;i<wtop;i++){ w=word_stack[i]; if( (w.syn>=1 && w.syn<=10) || w.syn==18 || w.syn==21 || w.syn==22 || w.syn==24) printf("%d\t|%s\n",w.syn,w.value.s); else if(w.syn==11) printf("%d\t|%d\n",w.syn,w.value.d); else printf("%d\t|%c\n",w.syn,w.value.c); } return ; } void tell_err(){ printf("error in line %d\n",line); exit(1); return ; } void scan(){ word_type w; char c; int j=0; if(isdigit(c=source[ip])){ w.syn=11; /* dd* */ w.value.d=c-'0'; while(isdigit(c=source[++ip])) w.value.d=w.value.d*10+c-'0'; if(!isalpha(c)) word_stack[wtop++]=w; else tell_err(); return; } if(isalpha(c=source[ip])){ w.syn=10; /* (ll|d) */ w.value.s[0]=c; while(isalpha(c=source[++ip]) || isdigit(c)) w.value.s[++j]=c; w.value.s[j+1]='\0'; for(j=0;j<KWD_CNT;j++){ if(strcmp(keywords[j],w.value.s)==0) w.syn=j+1; } word_stack[wtop++]=w; return ; } switch(c=source[ip]){ case '+' : w.syn=14; /* '+' */ w.value.c='+'; word_stack[wtop++]=w; ip++; break; case '-' : w.syn=15; /* '-' */ w.value.c='-'; word_stack[wtop++]=w; ip++; break; case '*' : w.syn=16; /* '*' */ w.value.c='*'; word_stack[wtop++]=w; ip++; break; case '/' : w.syn=17; w.value.c='/'; word_stack[wtop++]=w; ip++; break; case ':' : w.syn=19; w.value.c=':'; if( (c=source[++ip]) !='='){ word_stack[wtop++]=w; } else if(c=='='){ strcpy(w.value.s,":="); w.syn=18; word_stack[wtop++]=w; ip++; } break; case '<' : w.syn=20; w.value.c='<'; if( (c=source[++ip]) !='>' && c!='='){ word_stack[wtop++]=w; } else if(c=='>'){ w.syn=21; strcpy(w.value.s,"<>"); word_stack[wtop++]=w; ip++; } else if(c=='='){ w.syn=22; strcpy(w.value.s,"<="); word_stack[wtop++]=w; ip++; } break; case '>' : w.syn=23; w.value.c='>'; if( (c=source[++ip]) !='='){ word_stack[wtop++]=w; } else if(c=='='){ w.syn=24; strcpy(w.value.s,">="); word_stack[wtop++]=w; ip++; } break; case '=' : w.syn=25; w.value.c='='; word_stack[wtop++]=w; ip++; break; case ';' : w.syn=26; w.value.c=';'; word_stack[wtop++]=w; ip++; break; case '(' : w.syn=27; w.value.c='('; word_stack[wtop++]=w; ip++; break; case ')' : w.syn=28; w.value.c=')'; word_stack[wtop++]=w; ip++; break; case ' ' : while(source[++ip]==' '); break; case '\n' : line++; while(source[++ip]=='\n')line++; break; case '\t' : while(source[++ip]=='\t'); break; case '\r' : while(source[++ip]=='\r'); break; default: tell_err(); } return; } int main(){ FILE* fp; int i=0; word_type w; fp=fopen("input.txt","r"); while(!feof(fp)) source[i++]=getc(fp); fclose(fp); while(source[ip]!='#') scan(ip); w.syn=0; w.value.c='#'; word_stack[wtop++]=w; p_word_stack(); }

|