?? lexer.cpp
字號:
#include <cstdio>
#include <cctype>
#include <map>
#include <string>
#include <cstring>
#include <utility>
#define BSIZE 100 //規定記號的長度小于100
#define NONE -1
#define EOS '\0'
#define NUM 256
#define ID 257
#define CONST 258
#define VAR 259
#define EQU 260
#define LESS_EQU 261
#define MORE_EQU 262
#define NOT_EQU 263
#define CALL 264
#define BEGIN 265
#define END 266
#define ODD 267
#define IF 268
#define THEN 269
#define WHILE 270
#define DO 271
#define DONE 273
#define PROCEDURE 274
#define EVU 275 //:=
#define LESS 276
#define MORE 277
#define FLOAT 278
using namespace std;
map<string,pair<int,int> > symtable;
struct entry
{
char lexptr[BSIZE];
int token;
};
char token[500][BSIZE];
int token_num;
//#include "global.h"
int lexan();
void init();
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;
double tokenval1;
int lexan()
{
char t;
map<string,pair<int,int> >::iterator iter;
while(1)
{
t=getchar();
if(t==' '||t=='\t')
{
return 0;
}
else if(t=='\n')
{
lineno++;
return 0;
}
else if(isdigit(t))
{
ungetc(t,stdin);
scanf("%d",&tokenval);
t=getchar();
if(t=='.')
{
ungetc(t,stdin);
while(tokenval)
{
ungetc(tokenval%10+'0',stdin);
tokenval/=10;
}
// ungetc(' ',stdin);
scanf("%lf",&tokenval1);
printf("%lf\n",tokenval1);
t=getchar();
if(isalpha(t))
{
error();
ungetc(t,stdin);
return 0;
}
if(t!=EOF)
ungetc(t,stdin);
return FLOAT;
}
if(isalpha(t))
{
error();
ungetc(t,stdin);
return 0;
}
ungetc(t,stdin);
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();
return 0;
}
}
iter=symtable.find(buf);
if(iter==symtable.end())
{
if(t!='\n'&&t!=' '&&t!=EOF)
{
error();
return 0;
}
tokenval=token_num++;
strcpy(token[tokenval],buf);
symtable[buf]=make_pair(ID,tokenval);
}
tokenval=symtable[buf].second;
if(t!=EOF)
ungetc(t,stdin);
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 {error();return 0;}
}
else if(t=='<')
{
t=getchar();
if(t=='=')
return LESS_EQU;
else if(t=='>'){
return NOT_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 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)
{
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("<NUM %d>\n",t);break;
case VAR:
printf("<var %d>\n",t);break;
case EVU:
printf("<:= %d>\n",t);break;
case CONST:
printf("<const %d>\n",t);break;
case FLOAT:
printf("<float %d>\n",t);break;
case ID:
printf("<ID %d>\n",t);break;
default :
printf("<%c>\n",t);
break;
}
}
void error()
{
//printf("%d\n",lookahead);
printf("%d error\n",lineno);
}
int main()
{
freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
init();
int t;
while(1)
{
t=lexan();
if(t==DONE)
break;
if(t!=0)
print(t);
}
//system("pause");
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -