📄 lexer.c
字号:
#include<stdio.h>
#define OD c=='+'||c=='-'||c=='*'||c=='/'
#define RELOP c=='<'||c=='>'||c=='='
#define SPACE c=='\0'||c=='\n'||c=='\t'||c==' '
int state=0,start=0;
int strmax=0;
char buf[1000];//缓冲区;
char *foward=buf; //指向缓冲区的两指针;
char *begin=buf;
int line=1;
struct S
{
char word[100];
int va;
}smptable[100];//设置大小为100的符号表;
int lookup(char *s){
int i;
for (i=0;i<strmax;i++){
if (strcmp(smptable[i].word,s)==0) return i;
}
return -1;
}//符号表中查找字符串S,有返回位置,没有返回-1;
int insert(char *s,int value){
int i=lookup(s);
if(i==-1) //符号表中没有这个字符串;
{
strcpy(smptable[strmax].word,s);
smptable[strmax].va=value;
return strmax++;
}
return i;
}//在符号表中插入s,并将s标记为记号value;
char nextchar()
{
return *(foward++);
}//超前抄描字符;
void retract()
{
foward--;
}//回流;
void install_id()
{
char a[100]="";
strncpy(a,begin,foward-begin);
begin=foward;
if(lookup(a)<=10&&lookup(a)>=0) printf("%d %s\n",0,a); //区别标示符与关键字,前11个为关键字
//输出标记为0;
else {insert(a,1);printf("%d %s\n",1,a);} //1为标示符;
}//识别标示符;
void install_num()
{
char a[100]="";
strncpy(a,begin,foward-begin);
begin=foward;
printf("%d %s\n",2,a);
insert(a,2);
}//识别数字;
void install_relop()
{
char a[100]="";
strncpy(a,begin,foward-begin);
begin=foward;
printf("%d %s\n",3,a);
insert(a,3);
}//识别关系运算符;
void install_operate()
{
char a[100]="";
strncpy(a,begin,foward-begin);
begin=foward;
printf("%d %s\n",4,a);
insert(a,4);
}//识别操作运算符;
void recover()
{
printf("error in line %d\n",line);
while(*foward!=' '&&*foward!='\t'&&*foward!='\n'&&*foward!='\0'\
&&*foward!='>'&&*foward!='='&&*foward!='<'&&*foward!='+'&&*foward!='-'\
&&*foward!='*'&&*foward!='/'&&*foward!=';'&&*foward!=','&&*foward!=':')
{
foward++;
}
begin=foward;
start=0;state=0;
}//提示错误,并继续处理后面的输入;
char c;
int fail()
{
foward=begin;
switch(start){
case 0:start=9;break;
case 9:start=12;break;
case 12:start=20;break;
case 20:start=25;break;
case 25:start=28;break;
default:recover();
}
return start;
}//找出下一个开始状态;
int nexttoken()
{state=0;
start=0;
while(1)
{
switch(state){
case 28:c=nextchar();
if(c==' '||c=='\t')state=28;
else if(c=='\n'){state=28;line++;}
else state=29;
break;
case 29:retract();
if(*foward=='\0') return 0;
else state=fail();
break;
case 0:c=nextchar();
if(c==' '||c=='\t'){
state=0;
begin++;
}
else if(c=='\n') {state=0;begin++;line++;}
else if(c=='<')state=1;
else if(c=='=')state=5;
else if(c=='>')state=6;
else if(c==';')state=30;
else if(c==':')state=31;
else if(OD||c=='('||c==')'||c==',')state=34;
else state=fail();
break;
case 1:c=nextchar();
if(c=='=') state=2;
else if(c=='>')state=3;
else state=4;
break;
case 2:
case 3:
install_relop();//调用install_relop(),输出操作符;
if(*(foward-1)=='\0') return 0;
else return 1;
case 4:retract();install_relop();
if(*(foward-1)=='\0') return 0;
else return 1;
case 5:
install_relop();
if(*(foward-1)=='\0') return 0;
else return 1;
case 6:c=nextchar();
if(c=='=') state=7;
else state=8;
break;
case 7:
install_relop();
if(*(foward-1)=='\0') return 0;
else return 1;
case 8:retract();install_relop();
if(*(foward-1)=='\0') return 0;
else return 1;
case 9:c=nextchar();
if(isalpha(c)) state=10;
else state=fail();
break;
case 10:c=nextchar();
if(isalpha(c)||isdigit(c)) state=10;
else if(OD||RELOP||SPACE||c==';'||c==',') state=11;
else if(c==':') state=35;
else state=fail();
break;
case 11:retract();install_id();//调用install_id(),输出关键字或标识符;
if(*foward=='\0') return 0;
else return 1;
break;
case 35: c=nextchar();
if(c=='=') {retract();state=11;}
else recover();
break;
case 12:c=nextchar();
if(isdigit(c))state=13;
else state=fail();
break;
case 13:c=nextchar();
if(isdigit(c)) state=13;
else if(c=='.') state=14;
else if(c=='E'||c=='e') state=14;
else state=fail();
break;
case 14:c=nextchar();
if(isdigit(c)) state=15;
else state=fail();
break;
case 15:c=nextchar();
if(isdigit(c)) state=15;
else if(c=='E'||c=='e') state=16;
else state=fail();
break;
case 16:c=nextchar();
if(c=='+'||c=='-') state=17;
else if(isdigit(c)) state=18;
else state=fail();
case 17:c=nextchar();
if(isdigit(c)) state=18;
else state=fail();
break;
case 18:c=nextchar();
if(isdigit(c)) state=18;
else state=19;
break;
case 19:retract();install_num();//调用install_num(),输出数字;
if(*foward=='\0') return 0;
else return 1;
case 20:c=nextchar();
if(isdigit(c)) state=21;
else state=fail();
break;
case 21:c=nextchar();
if(isdigit(c)) state=21;
else if(c=='.')state=22;
else state=fail();
break;
case 22:c=nextchar();
if(isdigit(c))state=23;
else state=fail();
break;
case 23:c=nextchar();
if(isdigit(c)) state=23;
else state=24;
break;
case 24:retract();install_num();//调用install_num(),输出数字;
if(*foward=='\0') return 0;
else return 1;
case 25:c=nextchar();
if(isdigit(c)) state=26;
else state=fail();
break;
case 26:c=nextchar();
if(isdigit(c)) state=26;
else state=27;
break;
case 27:retract();install_num();//调用install_num(),输出数字;
if(*foward=='\0') return 0;
else return 1;
case 30:install_relop();
if(*(foward-1)=='\0') return 0;
else return 1;
case 31:c=nextchar();
if(c=='=') state=32;
else state=fail();
break;
case 32:install_relop();
if(*(foward-1)=='\0') return 0;
else return 1;
case 33:retract();install_relop();
if(*(foward-1)=='\0') return 0;
else return 1;
case 34:install_operate();
if(*(foward-1)=='\0') return 0;
else return 1;
}
}
}//根据状态图进行词法分析;
void keyword()
{
insert( "const",0);
insert("var",0);
insert("procedure",0);
insert("call",0);
insert("begin",0);
insert("end",0);
insert("if",0);
insert("then",0);
insert("while",0);
insert("do",0);
insert("odd",0);
}//初始化符号表,插入关键字,置关键字为0;
/*************************词法分析lexer.c*************************/
int main()
{
int a=1;
int i;
keyword();
freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
for(i=0;i<1000;i++)
scanf("%c",&buf[i]);
while(a)
a=nexttoken(); //一直调用,直到遇到'\0'退出;
free(buf);
exit(0);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -