0.简介
数组我觉得不太好管理,所以先把这个问题解决掉。
1.数组声明
数组声明语法如下。
int a[10]
其中包含类型、数组名、元素个数
新建一个数组声明语句
//数组声明语句
class ArrayDeclareStatement :public Statement
{
public:
ArrayDeclareStatement(int _line, int _column) :Statement(_line, _column) {}
//数组类型
Token type;
//类型名
std::string typeName;
//数组元素个数
std::vector<std::shared_ptr<Expression>> elementNums;
//数组名字
std::string name;
~ArrayDeclareStatement() {}
};
然后添加上数组声明的语法分析代码
std::shared_ptr<ArrayDeclareStatement> Parser::arrayDeclare()
{
auto result = std::make_shared<ArrayDeclareStatement>(line,column);
//获取类型,类型名
result->type = getToken();
result->typeName = getLexeme();
//吃掉类型
pushNextToken();
//获取数组名
result->name = getLexeme();
//吃掉数组名
pushNextToken();
//获取多维数组
while (getToken() == TK_LBRACKET)
{
//吃掉中括号
pushNextToken();
//检测下标是否符合规则,要求下标是整形数字
std::shared_ptr<Expression> index = parseExpression();
if (typeid(*index) == typeid(IntExpression))
{
result->elementNums.push_back(index);
}
else
{
//这里要报错,暂时抛出个异常
throw("error");
}
//吃掉中括号
pushNextToken();
}
return result;
}
2.数组访问
数组访问语法如下
a[0]
a[1][2]
3[a]
由于第三种方法也需要支持,所以就不能简单的依靠判断中括号来解决,所以将访问的中括号直接看做是一种二元运算符,其操作就是基址+偏移,但是直接用二元表达式不方便,所以再添加一种表达式。
//寻址表达式
class AddressingExpression : public Expression
{
public:
AddressingExpression(int _line, int _column) :Expression(_line, _column) {}
//基地址
std::shared_ptr<Expression> base;
//下标,偏移地址
std::vector<std::shared_ptr<Expression>> offset;
~AddressingExpression(){}
};
然后添加这个语法解析
std::shared_ptr<Expression> Parser::parseExpression()
{
...
if (token == TK_LBRACKET)
{
//二元表达式
auto result = std::make_shared<AddressingExpression>(line, column);
//这里放之前的一元表达式
result->base = unary_result;
while (getToken() == TK_LBRACKET)
{
//吃掉中括号
pushNextToken();
//右分支也是表达式
result->offset.push_back(parseExpression());
//吃掉中括号
pushNextToken();
}
return result;
}
...
}