📄 语法分析器.cpp
字号:
#include "entry.h"
#include <io.h>
#include <fcntl.h>
#include <sys/stat.h>
char lexbuf[50];
int lineno=1;
char file_buf[2050];
char lexeme[5000];
entry symtable[500];
entry keywords[20]={
entry("ifndef",LY_IFNDEF),
entry("if", LY_IF) ,
entry("else", LY_ELSE),
entry("then", LY_THEN),
entry("while", LY_WHILE),
entry("int", LY_INT),
entry("float", LY_FLOAT),
entry("long", LY_LONG),
entry("double", LY_DOUBLE),
entry("bool", LY_BOOL),
entry("char", LY_CHAR),
entry("return", LY_RETURN),
entry("switch", LY_SWITCH),
entry("case", LY_CASE),
entry("break", LY_BREAK),
entry("FILE", LY_FILE),
// entry("default", LY_DEFAULT),
entry("cin", LY_CIN),
entry("cout", LY_COUT),
entry("for", LY_FOR),
// entry("void", LY_VOID),
entry("main", LY_MAIN)
};
int lexeme_beginning=0;
int forward=0;
int state=0;
int start=0;
int lastchar=-1;
int lastentry=0;
int lexical_value;
char ch;
FILE *fp;
bool read_flag=false;
int filelen = 0;
int priority[9][9]={
2,3,3,3,3,3,3,3,3,
1,0,1,1,1,1,1,0,1,
1,3,1,1,3,3,3,3,1,
1,3,1,1,3,3,3,3,1,
1,3,1,1,1,1,3,3,1,
1,3,1,1,1,1,3,3,1,
1,3,1,1,1,1,1,3,1,
0,3,3,3,3,3,3,3,2,
1,0,1,1,1,1,1,0,1
};
char nextchar(){
char ch=file_buf[forward++];
if (ch==LY_EOF) {
if (forward==1025) {
if(!read_flag)
if(fread(file_buf+1025,1,1024,fp)==0) file_buf[filelen+1025]=0;
read_flag=false;
ch=file_buf[forward++];
}
if (forward==2050) {
if(!read_flag)
if(fread(file_buf,1,1024,fp)==0) file_buf[filelen]=0;
forward=0;
read_flag=false;
ch=file_buf[forward++];
}
}
return ch;
}
void retract(){
forward--;
}
int fail(){
if(forward>1024&&lexeme_beginning<=1024
||forward<lexeme_beginning) read_flag=true;
forward=lexeme_beginning;
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=40;
break;
case 40:
start=-1;
break;
default:
cout<<"line"<<lineno<<":\terror"<<endl;
}
return start;
}
int search(char *s){
for(int i=lastentry;i>0;i--)
if(strcmp(symtable[i].lexptr,s)==0)
return i;
return 0;
}
int searchkeyword(char *s){
for(int i=0;i<20;i++)
if (strcmp(keywords[i].lexptr,s)==0)
return keywords[i].token;
return -1;
}
int insert(char *s,int tok){
int len;
len=strlen(s);
if (lastentry+1>=500){
cout<<"error:symbol table full";
return 0;
}
if(lastchar+len+1>=5000){
cout<<"error:lexemes array full";
return 0;
}
lastentry++;
symtable[lastentry].token=tok;
symtable[lastentry].lexptr=&lexeme[lastchar+1];
lastchar=lastchar+len+1;
strcpy(symtable[lastentry].lexptr,s);
if(tok==NUM){
symtable[lastentry].value=numvalue(s);
}
return lastentry;
}
int lexan(){
int i=0;
while(1){
switch(state){
case 0:
ch=nextchar();
if(ch==LY_EOF) return LY_EOF;
if (ch==' '||ch=='\t') {
state=0;
lexeme_beginning=forward;
}
else if (ch=='\n') {
state=0;
lexeme_beginning=forward;
lineno++;
}
else if(ch=='<') state=1;
else if(ch=='=') state=3;
else if(ch=='>') state=6;
else if(ch=='!') state=29;
else if(ch=='&') state=32;
else if(ch=='|') state=34;
else state=fail();
break;
case 1:
ch=nextchar();
if (ch=='=') state=2;
else if(ch=='<') state=36;
else state=4;
break;
case 2:
if(!search("<=")) {
lexical_value=insert("<=",LE);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return LE;
case 36:
if(!search("<<")) {
lexical_value=insert("<<",LM);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return LM;
case 4:
retract();
if(!search("<")) {
lexical_value=insert("<",LT);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return LT;
case 3:
ch=nextchar();
if(ch=='=') state=5;
else state=28;
break;
case 5:
if(!search("==")) {
lexical_value=insert("==",EQ);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return EQ;
case 28:
retract();
if(!search("=")) {
lexical_value=insert("=",EL);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return EL;
case 6:
ch=nextchar();
if (ch=='=') state=7;
else if(ch=='>') state=37;
else state=8;
break;
case 7:
if(!search(">=")) {
lexical_value=insert(">=",GE);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return GE;
case 37:
if(!search(">>")) {
lexical_value=insert(">>",RM);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return RM;
case 8:
retract();
if(!search(">")) {
lexical_value=insert(">",GT);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return GT;
case 29:
ch=nextchar();
if(ch=='=') state=30;
else state=31;
break;
case 30:
if(!search("!=")) {
lexical_value=insert("!=",NE);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return NE;
case 31:
retract();
if(!search("!")) {
lexical_value=insert("!",'i');
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return '!';
case 32:
ch=nextchar();
if(ch=='&') state=33;
else state=38;
break;
case 33:
if(!search("&&")) {
lexical_value=insert("&&",YU);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return YU;
case 38:
retract();
if(!search("&")) {
lexical_value=insert("&",'&');
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return '&';
case 34:
ch=nextchar();
if(ch=='=') state=5;
else state=28;
break;
case 35:
if(!search("||")) {
lexical_value=insert("||",HUO);
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return HUO;
case 39:
retract();
if(!search("|")) {
lexical_value=insert("|",'|');
if(lexical_value==0) return LY_EOF;
}
lexeme_beginning=forward;
return '|';
case 9:
ch=nextchar();
if(ch>=65&&ch<=90||ch>=97&&ch<=122||ch==95) state=10;
else state=fail();
break;
case 10:
ch=nextchar();
if(ch>=65&&ch<=90||ch>=97&&ch<=122||ch==95) state=10;
else if(ch>='0'&&ch<='9') state=10;
else state=11;
break;
case 11:
int j;
retract();
i=0;
while (lexeme_beginning!=forward) {
if(lexeme_beginning==1024) lexeme_beginning++;
else if(lexeme_beginning==2049) lexeme_beginning=0;
else lexbuf[i++]=file_buf[lexeme_beginning++];
}
lexbuf[i]='\0';
if(!(j=search(lexbuf))) {
j=searchkeyword(lexbuf);
if(j==-1){
lexical_value=insert(lexbuf,ID);
j=ID;
}
else
lexical_value=insert(lexbuf,j);
if(lexical_value==0) return LY_EOF;
lexeme_beginning=forward;
return j;
}
lexical_value=j;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -