有空再来写注释^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();
}