自己动手写C语言编译器(2)

本文详细介绍了如何从零开始构建一个简单的C语言编译器,涵盖了词法分析、语法分析和语义分析的基本步骤,带你深入理解编译原理。
摘要由CSDN通过智能技术生成

 

直接上代码 :

支持:左右结合性
// MyCompiler.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <fstream>
#include <list>
#include <map>
#include <string>
#include <iostream>
#include <vector>
//把Token转换为字符串
#define  ATokenToString(l, r) if(l == r)return #r;
using namespace std;
namespace tokens{
	enum TOKEN
	{
		INVALID_TYPE,
			WHITE_SPACE,
			NAME,
			NUMBER,
			END,
			PLUS,
			MINUS,
			MUL,
			DIV,
			PRINT,
			ASSIGN,
			LP,
			RP,
	};
	static string MyTokenToString(TOKEN token)
	{
		ATokenToString(token, WHITE_SPACE)
			ATokenToString(token, NAME)
			ATokenToString(token, NUMBER)
			ATokenToString(token, END)
			ATokenToString(token, PLUS)
			ATokenToString(token, MINUS)
			ATokenToString(token, MUL)
			ATokenToString(token, DIV)
			ATokenToString(token, PRINT)
			ATokenToString(token, ASSIGN)
			ATokenToString(token, LP)
			ATokenToString(token, RP)
			return "";
	}
}

class tokenizer
{
	int mTokenTypes[256];
	string mCurrentStrToken;
	tokens::TOKEN mCurrentTokenType;
	istream& mIfStream;
public:
	tokenizer(istream& infile):mIfStream(infile)
	{
		memset(mTokenTypes, 0, 256);
		mTokenTypes['+'] = tokens::PLUS;
		mTokenTypes['-'] = tokens::MINUS;
		mTokenTypes['*'] = tokens::MUL;
		mTokenTypes['/'] = tokens::DIV;
		mTokenTypes[';'] = tokens::PRINT;
		mTokenTypes['='] = tokens::ASSIGN;
		mTokenTypes['('] = tokens::LP;
		mTokenTypes[')'] = tokens::RP;
		mTokenTypes['\t'] = tokens::WHITE_SPACE;
		mTokenTypes[' '] = tokens::WHITE_SPACE;
		char ch = 0;
		for (ch = 'a'; ch <= 'z'; ch ++)
		{
			mTokenTypes[ch] = tokens::NAME; 
		}
		for(ch = 'A'; ch <= 'Z'; ch ++)
		{
			mTokenTypes[ch] = tokens::NAME; 
		}
		for(ch = '0'; ch <= '9'; ch ++)
		{
			mTokenTypes[ch] = tokens::NUMBER; 
		}
		mTokenTypes['.'] = tokens::NUMBER;
		
	}
	bool hasNext()
	{
		char temptoken = 0;
		if(mIfStream.get(temptoken))
		{
			mIfStream.putback(temptoken);
			return true;
		}
		return false;
	}
	const string getCurrent()
	{
		return mCurrentStrToken;
	}
	tokens::TOKEN getTokenType()
	{
		return mCurrentTokenType;
	}
	const string getNext()
	{
		string strValue;
		char ch = 0;
		mIfStream>>ch;
		mCurrentTokenType = (tokens::TOKEN)mTokenTypes[ch];
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
一个C语言编译器是一项非常复杂的任务,需要对编译原理、语言设计、数据结构与算法等多个领域有深入的理解和掌握。以下是一个简单的自制C语言编译器的步骤: 1. 设计语言规范:定义C语言的语法、语义、关键字、运算符、数据类型等规范。 2. 词法分析:编词法分析器,将源代码转换为令牌(token)序列,识别出关键字、标识符、运算符、常量等。 3. 语法分析:使用语法分析器将令牌序列转换为语法树(syntax tree),检查语法是否正确,建立抽象语法树(abstract syntax tree)。 4. 语义分析:对抽象语法树进行语义分析,检查类型、作用域、符号引用等语义信息。 5. 中间代码生成:将抽象语法树转换为中间代码(intermediate code),如三地址代码、四元式等。 6. 代码优化:对生成的中间代码进行优化,如常数合并、循环展开、函数内联、死代码删除等。 7. 目标代码生成:将优化后的中间代码转换为目标代码(target code),如汇编语言或机器码等。 8. 目标代码优化:对生成的目标代码进行优化,如指令选择、寄存器分配、代码调度等。 9. 目标代码链接:将生成的目标代码与库文件、其他目标代码链接成可执行程序。 以上是一个简单的自制C语言编译器的步骤,但实际上编一个完整的C语言编译器需要考虑更多的问题和细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值