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

📄 compilerdlg.cpp

📁 一个词法分析编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}
		
	for (; i <= lastentry; i++)//if the lexeme is found and is a program variable
		if (strcmp (symtable[i].lexptr, lexm) == 0){
			tuple[++lasttuple].line = lineno;
			tuple[lasttuple].kind = symtable[i].token;
			tuple[lasttuple].value = i;
			lexeme_beginning = forward + 1;
			return i;
		}

	//if the lexeme is not found in the symbol table, create the new entry
	lastentry += 1;
	symtable[lastentry].token = ID;
	symtable[lastentry].lexptr = &lexemes[lastchar + 1];
	lastchar = lastchar + len + 1;
	strcpy (symtable[lastentry].lexptr, lexm);
	lexeme_beginning = forward + 1;
	tuple[++lasttuple].line = lineno;
	tuple[lasttuple].kind = symtable[i].token;
	tuple[lasttuple].value = lastentry;

	return lastentry;
}

int Install_num ()
{	//handle the number
	int		i, len;
	char	lexm[32];
	int		tokenval;

	len = forward - lexeme_beginning + 1;//the length of lexeme

	if (lastentry + 1 >= SYMMAX){
		//if symbol table is full then exit
		::MessageBox (NULL, "符号表已满!", "提示", 48);
		exit (0);
	}
	if (lastchar + len + 1 >= STRMAX){
		//if lexemes array is full then exit
		::MessageBox (NULL, "lexemes array is full!", "提示", 48);
		exit (0);
	}

	for (i = 0; i < len; i++){
		lexm[i] = *(lexeme_beginning + i);
	}
	lexm[i] = '\0';
	
	lastentry += 1;
	symtable[lastentry].token = INT;
	symtable[lastentry].lexptr = &lexemes[lastchar + 1];
	lastchar = lastchar + len + 1;
	strcpy (symtable[lastentry].lexptr, lexm);
	lexeme_beginning = forward + 1;
	tokenval = lexm[0] - '0';
	for (i = 1; i < len; i++){
		tokenval = tokenval * 10 + lexm[i] - '0';
	}
	symtable[lastentry].attribute = tokenval;
	tuple[++lasttuple].line = lineno;
	tuple[lasttuple].kind = symtable[lastentry].token;
	tuple[lasttuple].value = symtable[lastentry].attribute;

	return lastentry;
}

int Install_operator () 
{
	int		op_id;
	char	op[2];

	if (lastentry + 1 >= SYMMAX){
		//if symbol table is full then exit
		::MessageBox (NULL, "符号表已满!", "提示", 48);
		exit (0);
	}
	if (lastchar + 2 >= STRMAX){
		//if lexemes array is full then exit
		::MessageBox (NULL, "lexemes array is full!", "提示", 48);
		exit (0);
	}
	switch (c){
	case '+':
		op_id = PLUS;
		strcpy (op, "+");
		break;
	case '*':
		op_id = MUL;
		strcpy (op, "*");
		break;
	case '(':
		op_id = LEFTBRACKET;
		strcpy (op, "(");
		break;
	case ')':
		op_id = RIGHTBRACKET;
		strcpy (op, ")");
		break;
	}
	lastentry += 1;
	symtable[lastentry].attribute = OPERATOR;
	symtable[lastentry].token = op_id;
	symtable[lastentry].lexptr = &lexemes[lastchar + 1];
	lastchar = lastchar + 2;
	strcpy (symtable[lastentry].lexptr, op);
	lexeme_beginning = forward + 1;
	tuple[++lasttuple].line = lineno;
	tuple[lasttuple].kind = symtable[lastentry].attribute;
	tuple[lasttuple].value = symtable[lastentry].token;
	return lastentry;
}

token NextToken ()
{
			
	start = state = 0;
	while (1){
		switch (state){
		case 0:
			c = NextChar ();
			if (c == '#' && (forward == buffer + 127 || forward == buffer + 255))
				return NONE;
			if ( c == ' ' || c == '\t'){
				state = 0;
				lexeme_beginning++;
			}
			else if (c == '\n'){ 
				lexeme_beginning++;
				lineno++;
			}
			else if (c == '<')
				state = 1;
			else if (c == '=')
				state = 5;
			else if (c == '>')
				state = 6;
			else
				state = Fail ();
			break;
		case 1:
			c = NextChar ();
			if (c == '#' && (forward == buffer + 127 || forward == buffer + 255))
				return NONE;
			if (c == '=')
				state = 2;
			else if (c == '>')
				state = 3;
			else
				state = 4;
			break;
		case 2:
			Install_relop ();
			return 0;
			break;
		case 3:
			Install_relop ();
			return 0;
			break;
		case 4:
			Retract ();
			Install_relop ();
			return 0;
			break;
		case 5:
			Install_relop ();
			return 0;
			break;
		case 6:
			c = NextChar ();
			if (c == '#' && (forward == buffer + 127 || forward == buffer + 255))
				return NONE;
			if (c == '=')
				state = 7;
			else 
				state = 8;
			break;
		case 7:
			Install_relop ();
			return 0;
			break;
		case 8:
			Retract ();
			Install_relop ();
			return 0;
			break;
		case 9:
			if (isalpha (c))
				state = 10;
			else 
				state = Fail ();
			break;
		case 10:
			c = NextChar ();
			if (c == '#' && (forward == buffer + 127 || forward == buffer + 255))
				return NONE;
			if (isalpha (c))
				state = 10;
			else if (isdigit (c))
				state = 10;
			else
				state = 11;
			break;
		case 11:
			Retract ();
			Install_id ();
			return 0;
			break;
		case 12:
			if (isdigit (c))
				state = 13;
			else
				state = Fail ();
			break;
		case 13:
			c = NextChar ();
			if (c == '#' && (forward == buffer + 127 || forward == buffer + 255))
				return NONE;
			if (isdigit (c))
				state = 13;
			else
				state = 14;
			break;
		case 14:
			Retract ();
			Install_num ();
			return 0;
			break;
		case 15:
			if (c == '+')
				state = 16;
			else if (c == '-')
				state = 17;
			else if (c == '*')
				state = 18;
			else if (c == '/')
				state = 19;
			else if (c == '(')
				state = 20;
			else if (c == ')')
				state = 21;
			else
				state = Fail ();
			break;
		case 16:
			Install_operator ();
			return 0;
			break;
		case 17:
			Install_operator ();
			return 0;
			break;
		case 18:
			Install_operator ();
			return 0;
			break;
		case 19:
			Install_operator ();
			return 0;
			break;
		case 20:
			Install_operator ();
			return 0;
			break;
		case 21:
			Install_operator ();
			return 0;
			break;
		case 22:
			if (c == ';')
				state = 23;
			else if (c == ':')
				state = 24;
			else 
				state = Fail ();
			break;
		case 23:
			Install_id ();
			return 0;
			break;
		case 24:
			c = NextChar ();
			if (c == '#' && (forward == buffer + 127 || forward == buffer + 255))
				return NONE;
			if (c == '=')
				state = 25; 
			break;
		case 25:
			Install_id ();
			return 0;
			break;
		}
	}
}

void Lexical ()
{
	c = ' ';
	Initialization ();
	while (c != '#')
		NextToken ();
	fclose (fp);
	
}

void Push (int e)
{
	if (Stack.top - Stack.base >= Stack.stacksize){
		Stack.base = (int *) realloc (Stack.base, 
			(STACK_INIT_SIZE + STACKINCREMENT) * sizeof (int));
		if (!Stack.base){
			::MessageBox (NULL, "内存分配失败!", "提示", 48);
			exit (0);
		}
		Stack.top = Stack.base + Stack.stacksize;
		Stack.stacksize += STACKINCREMENT;
	}
	*Stack.top++ = e;
}

void Pop ()
{
	if (Stack.top == Stack.base){
		::MessageBox (NULL, "栈已满!", "提示", 48);
		return;
	}
	--Stack.top;
}

void CCompilerDlg::ParseError () 
{
	char lin[20];
	char szError[50] = "第";
	sprintf (lin, "%d", tuple[nIndexTuple].line);
	strcat (szError, lin);
	strcat (szError, "行有错");
	::MessageBox (NULL, szError, "提示", 48);
	if (nIndexTuple = lasttuple)
		exit (0);
}

int CCompilerDlg::Production (int pos)
{
	int		i = 0, j = 0;
	char	*p, *q;
	char	word[10];

	p = &lpProduction[pos][0];	
	while (*p++ != '>')
		;

	q = p;
	while (*p){
		while (*p != ' '){
			if (*p == '\0'){
				p--;
				break;
			}
			word[i++] = *p++;		
		}
		word[i] = '\0';
		p++;
		for (i = 0; szToken[i]; i++)
			if (strcmp (szToken[i], word) == 0)
				break;
		switch (i){
		case 0://while
			szProduction[j++] = 1;
			break;
		case 1://do
			szProduction[j++] = 2;
			break;
		case 2://begin
			szProduction[j++] = 3;
			break;
		case 3://end
			szProduction[j++] = 4;
			break;
		case 4://if
			szProduction[j++] = 5;
			break;
		case 5://then
			szProduction[j++] = 6;
			break;
		case 6://else
			szProduction[j++] = 7;
			break;
		case 7://and
			szProduction[j++] = 8;
			break;
		case 8://or
			szProduction[j++] = 9;
			break;
		case 9://not
			szProduction[j++] = 10;
			break;
		case 10://;
			szProduction[j++] = 11;
			break;
		case 11://:=
			szProduction[j++] = 12;
			break;
		case 12://+
			szProduction[j++] = 13;
			break;
		case 13://*
			szProduction[j++] = 14;
			break;
		case 14://(
			szProduction[j++] = 15;
			break;
		case 15://)
			szProduction[j++] = 16;
			break;
		case 16://i
			szProduction[j++] = 17;
			break;
		case 17://rop
			szProduction[j++] = 18;
			break;
		case 18://S
			szProduction[j++] = 100;
			break;
		case 19://L
			szProduction[j++] = 101;
			break;
		case 20://M
			szProduction[j++] = 102;
			break;
		case 21://A
			szProduction[j++] = 103;
			break;
		case 22://B
			szProduction[j++] = 104;
			break;
		case 23://C
			szProduction[j++] = 105;
			break;
		case 24://D
			szProduction[j++] = 106;
			break;
		case 25://E
			szProduction[j++] = 107;
			break;
		case 26://F
			szProduction[j++] = 108;
			break;
		case 27://$
			szProduction[j++] = 19;
			break;
		}
		i = 0;
	}

	return j;
}

void CCompilerDlg::OutPut (int pos)
{
	m_ListSyntax.AddString (lpProduction[pos]);
}

void CCompilerDlg::Parsing ()
{
	int		i;
	int		a;			//存储从输入串中读取的token
	int		top;		//存储当前栈顶元素
	int		pos;		//存储GetTable ()返回值,即哪条产生式
	int		len;

	Push (S);
	while ((top = *(Stack.top - 1)) != $){
		if (tuple[nIndexTuple].kind == ID || tuple[nIndexTuple].kind == INT)
			a = id;
		else if (tuple[nIndexTuple].kind == RELOP)
			a = ROP;
		else
			a = tuple[nIndexTuple].value;
		if (top < 100 || top == $)
			if (top == a){			
				Pop ();
				nIndexTuple++;
			}
			else
				ParseError ();
		else{
			if (pos = szpredictiveTable[top-100][a]){//得到分析表中待选的产生式
				Pop ();
				len = Production (pos);
				//将产生式中含有的终结符和非终结符的总和给len
				for (i = len - 1; i >= 0; i--)
					//将产生式右端反向压入栈中
					Push (szProduction[i]);
				OutPut (pos);
			}
			else
				ParseError ();
		}
	}
}

void InitStack ()
{
	Stack.base = (int *) malloc (STACK_INIT_SIZE * sizeof (int));
	if (!Stack.base){
		printf ("allocate fail!\n");
		exit (0);
	}
	Stack.top = Stack.base;
	Push ($);
	Stack.stacksize = STACK_INIT_SIZE;
}

void CCompilerDlg::Syntax ()
{
	InitStack ();
	Parsing ();
}

void CCompilerDlg::OnButtonCompile() 
{
	// TODO: Add your control notification handler code here
	char str1[50];
	char str2[50];
	
	if (InputFile){
		InputFile = false;
		Lexical ();
		for (int i = 0; i <= lasttuple; i++){
			sprintf (str1, "%d", tuple[i].line);
			sprintf (str2, "%d", tuple[i].kind);
			strcat (str1, "          ");
			strcat (str1, str2);
			strcat (str1, "          ");
			if (tuple[i].kind == ID){											
				strcat (str1, symtable[tuple[i].value].lexptr);
			}
			else{
				sprintf (str2, "%d", tuple[i].value);
				strcat (str1, str2);		
			}
			m_ListLexical.AddString (str1);
		}
		Syntax ();
	}
	else
		::MessageBox (NULL, "请读入源程序!", "提示", 48);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -