Parser for try/catch.

This commit is contained in:
chriseth 2019-09-03 16:06:00 +02:00
parent a54d9d622f
commit 6d6914f98f
2 changed files with 66 additions and 6 deletions

View File

@ -1106,6 +1106,8 @@ ASTPointer<Statement> Parser::parseStatement()
m_scanner->next();
break;
}
case Token::Try:
return parseTryStatement(docString);
case Token::Assembly:
return parseInlineAssembly(docString);
case Token::Emit:
@ -1187,6 +1189,62 @@ ASTPointer<IfStatement> Parser::parseIfStatement(ASTPointer<ASTString> const& _d
return nodeFactory.createNode<IfStatement>(_docString, condition, trueBody, falseBody);
}
ASTPointer<TryStatement> Parser::parseTryStatement(ASTPointer<ASTString> const& _docString)
{
RecursionGuard recursionGuard(*this);
ASTNodeFactory nodeFactory(*this);
expectToken(Token::Try);
ASTPointer<Expression> externalCall = parseExpression();
vector<ASTPointer<TryCatchClause>> clauses;
ASTNodeFactory successClauseFactory(*this);
ASTPointer<ParameterList> returnsParameters;
if (m_scanner->currentToken() == Token::Returns)
{
m_scanner->next();
VarDeclParserOptions options;
options.allowEmptyName = true;
options.allowLocationSpecifier = true;
returnsParameters = parseParameterList(options, false);
}
ASTPointer<Block> successBlock = parseBlock();
successClauseFactory.setEndPositionFromNode(successBlock);
clauses.emplace_back(successClauseFactory.createNode<TryCatchClause>(
make_shared<ASTString>(), returnsParameters, successBlock
));
do
{
clauses.emplace_back(parseCatchClause());
}
while (m_scanner->currentToken() == Token::Catch);
nodeFactory.setEndPositionFromNode(clauses.back());
return nodeFactory.createNode<TryStatement>(
_docString, externalCall, clauses
);
}
ASTPointer<TryCatchClause> Parser::parseCatchClause()
{
RecursionGuard recursionGuard(*this);
ASTNodeFactory nodeFactory(*this);
expectToken(Token::Catch);
ASTPointer<ASTString> errorName = make_shared<string>();
ASTPointer<ParameterList> errorParameters;
if (m_scanner->currentToken() != Token::LBrace)
{
if (m_scanner->currentToken() == Token::Identifier)
errorName = expectIdentifierToken();
VarDeclParserOptions options;
options.allowEmptyName = true;
options.allowLocationSpecifier = true;
errorParameters = parseParameterList(options, !errorName->empty());
}
ASTPointer<Block> block = parseBlock();
nodeFactory.setEndPositionFromNode(block);
return nodeFactory.createNode<TryCatchClause>(errorName, errorParameters, block);
}
ASTPointer<WhileStatement> Parser::parseWhileStatement(ASTPointer<ASTString> const& _docString)
{
RecursionGuard recursionGuard(*this);

View File

@ -119,6 +119,8 @@ private:
ASTPointer<Statement> parseStatement();
ASTPointer<InlineAssembly> parseInlineAssembly(ASTPointer<ASTString> const& _docString = {});
ASTPointer<IfStatement> parseIfStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<TryStatement> parseTryStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<TryCatchClause> parseCatchClause();
ASTPointer<WhileStatement> parseWhileStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<WhileStatement> parseDoWhileStatement(ASTPointer<ASTString> const& _docString);
ASTPointer<ForStatement> parseForStatement(ASTPointer<ASTString> const& _docString);