自制编程语言(9)---语法分析---函数声明

0.简介

前面写了那么多,现在我们可以支持函数声明了。

1.函数声明

//声明1
int fun(int a,int b)
{
    ...
}


//声明2
int fun(int a,int b);
int fun(int a,int b)
{
    ...
}

我打算支持这两种声明格式。先设计函数表达式类

//代码块表达式
class CodeBlockStatement : public Statement
{
public:
	CodeBlockStatement(int _line, int _column) :Statement(_line, _column) {}
	//代码块
	std::vector<std::shared_ptr<Statement>> statements;
	~CodeBlockStatement() {}
};

//函数声明表达式
class FunctionDeclareStatement :public Statement
{
public:
	FunctionDeclareStatement(int _line, int _column) :Statement(_line, _column) {}
	//类型
	Token type;
	//类型名字
	std::string typeName;
	//函数名
	std::string functionName;
	//函数参数列表,参数列表中必须都是声明表达式
	std::vector<std::shared_ptr<Statement>> argsList;
	//代码块
	std::shared_ptr<CodeBlockStatement> block;
	~FunctionDeclareStatement(){}
};

其中还包括了代码块表达式。

函数和代码块分析如下。

std::shared_ptr<FunctionDeclareStatement> Parser::functionDeclare()
{
	auto result = std::make_shared<FunctionDeclareStatement>(lines.front(),columns.front());
	//获取类别
	result->type = getToken();
	//获取类型名
	result->typeName = getLexeme();
	//吃掉类型
	pushNextToken();
	//获取函数名字
	result->functionName = getLexeme();;
	//吃掉函数名
	pushNextToken();
	//吃掉括号
	pushNextToken();

	//获取参数列表
	while (getToken() != TK_RPAREN)
	{
		//放入参数
		auto statement = variableDeclare();
		result->argsList.push_back(statement);

		//到了参数列表结尾
		if (getToken() == TK_RPAREN)
		{
			//吃掉括号
			pushNextToken();
			break;
		}
		//如果不是逗号则报错
		if (getToken() != TK_COMMA)
		{
			//如果下一个不是逗号或者右括号就继续报错吃符号
			while (getToken() != TK_COMMA && getToken() != TK_RPAREN)
			{
				error(MISSING_COMMA, lines.front(), columns.front());
				pushNextToken();
				//如果一直延续到结尾,直接返回
				if (getToken() == TK_EOF)
					return nullptr;
			}
		}
		else//吃掉逗号
			pushNextToken();
	}
	//获取函数块
	result->block = codeBlock();
	return result;
}

std::shared_ptr<CodeBlockStatement> Parser::codeBlock()
{
	//不是大括号要报错
	if (getToken() != TK_LBRACE)
	{
		error(MISSING_BRACE, lines.front(), columns.front());
		return nullptr;
	}
	else
		pushNextToken();
	auto result = std::make_shared<CodeBlockStatement>(lines.front(),columns.front());
	//获取代码
	while (getToken() != TK_RBRACE)
	{
		result->statements.push_back(parseStatement());
	}
	//吃掉大括号
	pushNextToken();
	return result;
}

漏洞肯定是有,等到时候慢慢发现吧。

2.源码

这里

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值