⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lexer.cpp

📁 编译原理下的作业词法分析器 它是用C++语言写的
💻 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 + -