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

📄 compiler.cpp

📁 编译原理的作业 编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
				}
				break;
			case 'm':
				if (strcmp(_tok.text, "mult") == 0)
				{
					instr.opcode = MULT;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else
				{
					errorNo = ER_ELF0001;
				}
				break;
			case 'n':
				if (strcmp(_tok.text, "neg") == 0)
				{
					instr.opcode = NEG;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "nop") == 0)
				{
					instr.opcode = NOP;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "not") == 0)
				{
					instr.opcode = NOT;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else
				{
					errorNo = ER_ELF0001;
				}
				break;
			case 'o':
				if (strcmp(_tok.text, "or") == 0)
				{
					instr.opcode = OR;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else
				{
					errorNo = ER_ELF0001;
				}
				break;
			case 'p':
				if (strcmp(_tok.text, "pop") == 0)
				{
					instr.opcode = POP;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "prt") == 0)
				{
					instr.opcode = PRT;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "prts") == 0)
				{
					instr.opcode = PRTS;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else
				{
					errorNo = ER_ELF0001;
				}
				break;
			case 'r':
				if (strcmp(_tok.text, "rem") == 0)
				{
					instr.opcode = REM;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "ret") == 0)
				{
					eoi = true;
					instr.opcode = RET;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else
				{
					errorNo = ER_ELF0001;
				}
				break;
			case 's':
				if (strcmp(_tok.text, "shl") == 0)
				{
					instr.opcode = SHL;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "shr") == 0)
				{
					instr.opcode = SHR;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.0") == 0)
				{
					instr.opcode = ST0;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.1") == 0)
				{
					instr.opcode = ST1;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.2") == 0)
				{
					instr.opcode = ST2;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.3") == 0)
				{
					instr.opcode = ST3;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.4") == 0)
				{
					instr.opcode = ST4;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.5") == 0)
				{
					instr.opcode = ST5;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.6") == 0)
				{
					instr.opcode = ST6;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.7") == 0)
				{
					instr.opcode = ST7;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.8") == 0)
				{
					instr.opcode = ST8;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "st.9") == 0)
				{
					instr.opcode = ST9;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else if (strcmp(_tok.text, "sub") == 0)
				{
					instr.opcode = SUB;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else
				{
					errorNo = ER_ELF0001;
				}
				break;
			case 'x':
				if (strcmp(_tok.text, "xor") == 0)
				{
					instr.opcode = XOR;
					_instrs.PushBack(instr); 
					_curMethod._addr += 2;
				}
				else
				{
					errorNo = ER_ELF0001;
				}
				break;
			default:
				errorNo = ER_ELF0001;
			}
			instr.hasArg = false;
		}
		else if (Lexer::Match(_tok, TOK_RP_B))
		{
			errorNo = ER_ELF0020;
			eoi = true;
		}
		else
		{
			errorNo = ER_ELF0001;
		}
		
 
		if (errorNo != -1)
		{
			OutputError(_curLine, errorNo);
		}
	}
}

int Compiler::ILCallArgumentList()
{
	int errorNo = -1;

	_lexer->GetNextToken(_tok);
	if(!Lexer::Match(_tok, TOK_IDENTIFIER))
	{
		errorNo = ER_ELF0021;
	}
	else
	{
		//TODO: HashIndexer;
	}

	if (!Lexer::Match(_lexer ->GetNextToken(), TOK_LP_S))
	{
		OutputError(_curLine, ER_ELF0010);  
	}

	_lexer ->GetNextToken(_tok);
	if (Lexer::Match(_tok, TOK_RP_S))
	{
		return errorNo;
	}

	while (true)
	{
		ILCallArgument();
		_lexer ->GetNextToken(_tok);

		if (!Lexer::Match(_tok, TOK_COMMA))
		{
			break;
		}
		_lexer ->GetNextToken(_tok);

		if (Lexer::Match(_tok, TOK_RP_S))
		{
			OutputError(_curLine, ER_ELF0024);
			return errorNo;					//For continue compiling;
		}
	}

	if (Lexer::Match(_tok, TOK_RP_S))
	{
		//TODO: HashIndexer;
		//instr.arg = ;
		return errorNo;
	}
	else
	{
		OutputError(_curLine, ER_ELF0017);
	}
	return errorNo;
}


void Compiler::ILCallArgument()
{
	if (Lexer::Match(_tok, TOK_KEYWORD))
	{
		_curMethod._params.PushBack(_tok.arg);
	}
	else
	{
		OutputError(_curLine, ER_ELF0022);
	}
}

void Compiler::MetaDataGen()
{
	_metaData.Store(_outExe);
}

void Compiler::ILGen()
{
	List<Instr>::Iterator it(_instrs);
	for (it.First(); !it.IsDone(); it.Next())
	{
		Instr i = it.Current();
		fwrite(&(i.opcode), sizeof(U16), 1, _outExe);
		if (i.hasArg)
		{
			fwrite(&(i.arg), sizeof(S64), 1, _outExe);
		}
	}
}

void Compiler::CodeGen()
{
	_fileHeader.Store(_outExe);
	MetaDataGen();
	ILGen();
	_strPool.Store(_outExe);
	ListGen();
}

void Compiler::ListGen()
{
	DumpFileHeader();
	DumpMethods();
	DumpFields();
	DumpStringPool();
	DumpILCode();
	fwrite(_listFile._buffer, _listFile._curPos, 1, _dumpFile);
}

void Compiler::DumpFileHeader()
{
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "=========================== File Header ===========================\n");
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Num of Methods: \t\t%d\n", _fileHeader._nMethods);
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Num of Fields: \t\t\t%d\n", _fileHeader._nFields);
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Num of Instruction: \t\t%ld\n", _fileHeader._cbinstr);
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Size of StringPool: \t\t%ld\n", _fileHeader._cbStrPool);
}

void Compiler::DumpFields()
{
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "\n=========================== Fields Meta ===========================\n");
	int i = 0;

	List<FieldDesc>::Iterator it(_metaData._fields);
	for (it.First(); !it.IsDone(); it.Next())
	{
		++i;
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "\nField \t\t(%d):\n", i);
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, 
			"Name: \t\t%d(str index in Pool) == %s\n", it.Current()._name, _strPool._pool+ it.Current()._name);
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Type: %s\n", _listFile.ValueType[it.Current()._type]);
	}
}

void Compiler::DumpMethods()
{
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "\n=========================== Methods Meta ===========================\n");
	int i = 0;
	int p = 0;

	List<MethodDesc>::Iterator it(_metaData._methods);
	for (it.First(); !it.IsDone(); it.Next())
	{
		++i;
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "\nMethod \t\t(%d):\n", i);
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Return Type: \t\t%s\n", _listFile.ValueType[it.Current()._retType]);
		if (it.Current()._isEntry)
		{
			_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Special: This is the entry method of the Program\n");
		}

		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, 
			"Name: \t\t%d(str index in Pool) == %s\n", it.Current()._name, _strPool._pool+ it.Current()._name);
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Start Address = %d\n", it.Current()._addr);

		if (!it.Current()._params.IsEmpty())
		{
			List<int>::Iterator i(it.Current()._params);
			
			for (i.First(); !i.IsDone(); i.Next())
			{
				++p;
				_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Parameter \t(%d):\n", p);
				_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "Index of Field: \t%d\n", i.Current());
			}
		}
	}
}


void Compiler::DumpILCode()
{
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "\n=======================   IL Code Dump   ========================\n\n");
	static int bil;
	List<Instr>::Iterator it(_instrs);

	for (it.First(); !it.IsDone(); it.Next())
	{
		
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "IL00%d\t", bil);
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "%s\t\t", opList[it.Current().opcode]);
		bil += 2;

		if (it.Current().hasArg)
		{
			bil += 8;
			_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "%ld", it.Current().arg);
		}
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "\n");
	}
}

void Compiler::DumpStringPool()
{
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "\n======================= String Pool Dump =======================\n\n");
	int i = 0;

	while (i < _strPool.Size())
	{
		_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "%c", _strPool._pool[i]);
		++i;
	}	
	_listFile._curPos += sprintf(_listFile._buffer + _listFile._curPos, "\n");
}

⌨️ 快捷键说明

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