📄 lexer.cpp
字号:
#include "global.h"
int lexan();
void init();
void program();
void block();
void const_decl();
void var_decl();
void proc_decl();
void statement();
void const_assignment_list();
void ident_list();
void expression();
void statement_list();
void condition();
void relation();
void term();
void adding_operator();
void factor();
void multiplying_operator();
void match(int t);
void print(int t,int tt);
void error();
int lookahead;
entry s[18]={{"const",CONST},
{"var",VAR},
{ "=",EQU},
{"<=",LESS_EQU},
{">=",MORE_EQU},
{"<>",NOT_EQU},
{">",MORE},
{ "<",LESS},
{"call",CALL},
{"begin",BEGIN},
{"end",END},
{"odd",ODD},
{"if",IF},
{"then",THEN},
{"while",WHILE},
{"do",DO},
{"procedure",PROCEDURE},
{":=",EVU}
};
char buf[BSIZE];
int b;
int lineno=1;
int tokenval=NONE;
int lexan()
{
char t;
map<string,pair<int,int> >::iterator iter;
while(1)
{
t=getchar();
if(t==' '||t=='\t');
else if(t=='\n') lineno++;
else if(isdigit(t))
{
ungetc(t,stdin);
scanf("%d",&tokenval);
return NUM;
}
else if(isalpha(t))
{
b=0;
memset(buf,'\0',sizeof(buf));
while(isalnum(t))
{
buf[b++]=t;
t=getchar();
if(b>=BSIZE)
{
error();
break;
}
}
if(t!=EOF)
ungetc(t,stdin);
iter=symtable.find(buf);
if(iter==symtable.end())
{
tokenval=token_num++;
strcpy(token[tokenval],buf);
symtable[buf]=make_pair(ID,tokenval);
}
tokenval=symtable[buf].second;
return symtable[buf].first;
}
else if(t==EOF)
return DONE;
else if(t=='=')
return EQU;
else if(t==':')
{
t=getchar();
if(t=='=')
return EVU;
else return NONE;
}
else if(t=='<')
{
t=getchar();
if(t=='=')
return LESS_EQU;
else
{
ungetc(t,stdin);
return LESS;
}
}
else if(t=='>')
{
t=getchar();
if(t=='=')
return MORE_EQU;
else
{
ungetc(t,stdin);
return MORE;
}
}
else
return t;
}
}
void match(int t)
{
if(lookahead!=t)
error();
lookahead=lexan();
}
void program()
{
lookahead=lexan();
//printf("%d\n",lookahead);
block();
match('.');
}
void block()
{
const_decl();
var_decl();
proc_decl();
statement();
}
void const_decl()
{
if(lookahead==CONST)
{
match(CONST);
print(CONST,NONE);
const_assignment_list();
match(';');
}
}
void const_assignment_list()
{
while(lookahead!=ID)
match(ID);
print(ID,tokenval);
match(ID);
while(lookahead!=EQU&&lookahead!=DONE)
match(EQU);
if(lookahead==DONE)
return;
print(EQU,NONE);
match(EQU);
while(lookahead!=NUM&&lookahead!=DONE)
match(NUM);
if(lookahead==DONE)
return;
print(NUM,tokenval);
match(NUM);
if(lookahead==',')
{
match(',');
const_assignment_list();
}
}
void var_decl()
{
if(lookahead==VAR)
{
print(VAR,NONE);
match(VAR);
ident_list();
match(';');
}
}
void ident_list()
{
while(lookahead!=ID&&lookahead!=DONE)
match(ID);
if(lookahead==DONE)
return ;
print(ID,tokenval);
match(ID);
if(lookahead==',')
{
match(',');
ident_list();
}
}
void proc_decl()
{
if(lookahead==PROCEDURE)
{
print(PROCEDURE,NONE);
match(PROCEDURE);
while(lookahead!=ID&&lookahead!=DONE)
match(ID);
if(lookahead==DONE)
return;
print(ID,tokenval);
match(ID);
match(';');
block();
match(';');
}
}
void statement()
{
switch(lookahead)
{
case ID:
print(ID,tokenval);
match(ID);
while(lookahead!=EVU&&lookahead!=DONE)
match(EVU);
if(lookahead==DONE)
return;
print(EVU,NONE);
match(EVU);
expression();
break;
case CALL:
print(CALL,NONE);
match(CALL);
while(lookahead!=ID&&lookahead!=DONE)
match(ID);
if(lookahead==DONE)
return;
print(ID,tokenval);
match(ID);
break;
case BEGIN:
print(BEGIN,NONE);
match(BEGIN);
statement_list();
while(lookahead!=END&&lookahead!=DONE)
match(END);
if(lookahead==DONE)
return;
print(END,NONE);
match(END);
break;
case IF:
print(IF,NONE);
match(IF);
condition();
while(lookahead!=THEN&&lookahead!=DONE)
match(THEN);
if(lookahead==DONE)
return;
print(THEN,NONE);
match(THEN);
statement();break;
case WHILE:
print(WHILE,NONE);
match(WHILE);condition();
while(lookahead!=DO&&lookahead!=DONE)
match(DO);
if(lookahead==DONE)
return;
print(DO,NONE);
match(DO);
statement();
break;
}
}
void statement_list()
{
statement();
if(lookahead==';')
{
match(';');
statement_list();
}
}
void condition()
{
if(lookahead==ODD)
{
print(ODD,NONE);
match(ODD);
expression();
return;
}
expression();
relation();
expression();
}
void relation()
{
switch(lookahead)
{
case EQU:
case NOT_EQU:
case LESS_EQU:
case MORE_EQU:
case LESS:
case MORE:
print(lookahead,NONE);match(lookahead);break;
default:
error();break;
}
}
void expression()
{
if(lookahead=='+'||lookahead=='-')
{
print(lookahead,NONE);
adding_operator();
term();
return;
}
term();
if(lookahead=='+'||lookahead=='-')
{
print(lookahead,NONE);
adding_operator();
expression();
}
}
void adding_operator()
{
switch(lookahead)
{
case '+': match('+');break;
case '-': match('-');break;
default: error();break;
}
}
void term()
{
factor();
if(lookahead=='*'||lookahead=='/')
{
print(lookahead,NONE);
multiplying_operator();
term();
}
}
void multiplying_operator()
{
switch(lookahead)
{
case '*':match('*');break;
case '/':match('/');break;
default:error();break;
}
}
void factor()
{
switch(lookahead)
{
case ID:print(ID,tokenval);match(ID);break;
case NUM:print(NUM,tokenval);match(NUM);break;
case '(': match('(');expression();match(')');break;
default: error();break;
}
}
void init()
{
int i;
symtable.clear();
for(i=0;i<18;i++)
symtable[s[i].lexptr]=make_pair(s[i].token,NONE);
token_num=0;
lineno=1;
}
void print(int t,int tt)
{
switch(t)
{
case '+':
case '-':
case '*':
case '/':
printf("%c %d\n",t,t);break;
case EQU:printf("= %d\n",t);break;
case LESS_EQU:printf("<= %d\n",t);break;
case LESS: printf("< %d\n",t);break;
case MORE: printf("> %d\n",t);break;
case MORE_EQU: printf(">= %d\n",t);break;
case NOT_EQU: printf("<> %d\n",t);break;
case CALL: printf("call %d\n",t);break;
case BEGIN: printf("begin %d\n",t);break;
case END: printf("end %d\n",t);break;
case ODD: printf("odd %d\n",t);break;
case IF: printf("if %d\n",t);break;
case THEN: printf("then %d\n",t);break;
case WHILE: printf("while %d\n",t);break;
case DO: printf("do %d\n",t);break;
case PROCEDURE: printf("procedure %d\n",t);break;
case NUM: printf("%d %d\n",tt,t);break;
case VAR: printf("var %d\n",t);break;
case EVU: printf(":= %d\n",t);break;
case ID:
printf("%s %d\n",token[tt],t);break;
}
}
void error()
{
//printf("%d\n",lookahead);
printf("%d error\n",lineno);
}
int main()
{
freopen("input.txt","r",stdin);
init();
program();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -