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;
}
漏洞肯定是有,等到时候慢慢发现吧。