其它解析
下一步的目标是处理函数声明。在Kaleidoscope中有两种函数声明方式,一是用"extern"声明外部函数,二是直接声明函数体。实现这部分的代码很简单直接,但是并不那么有趣:
- /// prototype
- /// ::= id '(' id* ')'
- static PrototypeAST *ParsePrototype() {
- if (CurTok != tok_identifier)
- return ErrorP("Expected function name in prototype");
- std::string FnName = IdentifierStr;
- getNextToken();
- if (CurTok != '(')
- return ErrorP("Expected '(' in prototype");
- // Read the list of argument names.
- std::vector<std::string> ArgNames;
- while (getNextToken() == tok_identifier)
- ArgNames.push_back(IdentifierStr);
- if (CurTok != ')')
- return ErrorP("Expected ')' in prototype");
- // success.
- getNextToken(); // eat ')'.
- return new PrototypeAST(FnName, ArgNames);
- }
有了以上,记录一个声明的函数就很简单了——仅仅需要保存一个函数原型和函数体的一串表达式:
- /// definition ::= 'def' prototype expression
- static FunctionAST *ParseDefinition() {
- getNextToken(); // eat def.
- PrototypeAST *Proto = ParsePrototype();
- if (Proto == 0) return 0;
- if (ExprAST *E = ParseExpression())
- return new FunctionAST(Proto, E);
- return 0;
- }
另外,我们也支持"extern"声明外部函数比如"sin"和"cos"或者用户定义的函数。"extern"与上面函数声明的区别仅仅在于没有具体的函数体:
- /// external ::= 'extern' prototype
- static PrototypeAST *ParseExtern() {
- getNextToken(); // eat extern.
- return ParsePrototype();
- }
最后,我们将让用户输入任意的外层表达式(top-level expressions),在运行的同时会计算出表达式结果。为此,我们需要处理无参数函数:
- /// toplevelexpr ::= expression
- static FunctionAST *ParseTopLevelExpr() {
- if (ExprAST *E = ParseExpression()) {
- // Make an anonymous proto.
- PrototypeAST *Proto = new PrototypeAST("", std::vector<std::string>());
- return new FunctionAST(Proto, E);
- }
- return 0;
- }
现在我们完成了所有的零碎的部分,让我们用一段短小的驱动代码来调用他们吧!