mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #8879 from a3d4/partfix-5819-add-error-tags-to-parser
Add error tags to ParserBase and derived classes
This commit is contained in:
commit
561a586203
@ -77,9 +77,9 @@ void ParserBase::expectToken(Token _value, bool _advance)
|
|||||||
{
|
{
|
||||||
string const expectedToken = ParserBase::tokenName(_value);
|
string const expectedToken = ParserBase::tokenName(_value);
|
||||||
if (m_parserErrorRecovery)
|
if (m_parserErrorRecovery)
|
||||||
parserError("Expected " + expectedToken + " but got " + tokenName(tok));
|
parserError(6635_error, "Expected " + expectedToken + " but got " + tokenName(tok));
|
||||||
else
|
else
|
||||||
fatalParserError("Expected " + expectedToken + " but got " + tokenName(tok));
|
fatalParserError(2314_error, "Expected " + expectedToken + " but got " + tokenName(tok));
|
||||||
// Do not advance so that recovery can sync or make use of the current token.
|
// Do not advance so that recovery can sync or make use of the current token.
|
||||||
// This is especially useful if the expected token
|
// This is especially useful if the expected token
|
||||||
// is the only one that is missing and is at the end of a construct.
|
// is the only one that is missing and is at the end of a construct.
|
||||||
@ -108,21 +108,21 @@ void ParserBase::expectTokenOrConsumeUntil(Token _value, string const& _currentN
|
|||||||
// rollback to where the token started, and raise exception to be caught at a higher level.
|
// rollback to where the token started, and raise exception to be caught at a higher level.
|
||||||
m_scanner->setPosition(startPosition);
|
m_scanner->setPosition(startPosition);
|
||||||
m_inParserRecovery = true;
|
m_inParserRecovery = true;
|
||||||
fatalParserError(errorLoc, msg);
|
fatalParserError(1957_error, errorLoc, msg);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_inParserRecovery)
|
if (m_inParserRecovery)
|
||||||
parserWarning("Recovered in " + _currentNodeName + " at " + expectedToken + ".");
|
parserWarning(3796_error, "Recovered in " + _currentNodeName + " at " + expectedToken + ".");
|
||||||
else
|
else
|
||||||
parserError(errorLoc, msg + "Recovered at next " + expectedToken);
|
parserError(1054_error, errorLoc, msg + "Recovered at next " + expectedToken);
|
||||||
m_inParserRecovery = false;
|
m_inParserRecovery = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (m_inParserRecovery)
|
else if (m_inParserRecovery)
|
||||||
{
|
{
|
||||||
string expectedToken = ParserBase::tokenName(_value);
|
string expectedToken = ParserBase::tokenName(_value);
|
||||||
parserWarning("Recovered in " + _currentNodeName + " at " + expectedToken + ".");
|
parserWarning(3347_error, "Recovered in " + _currentNodeName + " at " + expectedToken + ".");
|
||||||
m_inParserRecovery = false;
|
m_inParserRecovery = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ void ParserBase::increaseRecursionDepth()
|
|||||||
{
|
{
|
||||||
m_recursionDepth++;
|
m_recursionDepth++;
|
||||||
if (m_recursionDepth >= 1200)
|
if (m_recursionDepth >= 1200)
|
||||||
fatalParserError("Maximum recursion depth reached during parsing.");
|
fatalParserError(7319_error, "Maximum recursion depth reached during parsing.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParserBase::decreaseRecursionDepth()
|
void ParserBase::decreaseRecursionDepth()
|
||||||
@ -143,27 +143,27 @@ void ParserBase::decreaseRecursionDepth()
|
|||||||
m_recursionDepth--;
|
m_recursionDepth--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParserBase::parserWarning(string const& _description)
|
void ParserBase::parserWarning(ErrorId _error, string const& _description)
|
||||||
{
|
{
|
||||||
m_errorReporter.warning(6635_error, currentLocation(), _description);
|
m_errorReporter.warning(_error, currentLocation(), _description);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParserBase::parserError(SourceLocation const& _location, string const& _description)
|
void ParserBase::parserError(ErrorId _error, SourceLocation const& _location, string const& _description)
|
||||||
{
|
{
|
||||||
m_errorReporter.parserError(2314_error, _location, _description);
|
m_errorReporter.parserError(_error, _location, _description);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParserBase::parserError(string const& _description)
|
void ParserBase::parserError(ErrorId _error, string const& _description)
|
||||||
{
|
{
|
||||||
parserError(currentLocation(), _description);
|
parserError(_error, currentLocation(), _description);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParserBase::fatalParserError(string const& _description)
|
void ParserBase::fatalParserError(ErrorId _error, string const& _description)
|
||||||
{
|
{
|
||||||
fatalParserError(currentLocation(), _description);
|
fatalParserError(_error, currentLocation(), _description);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParserBase::fatalParserError(SourceLocation const& _location, string const& _description)
|
void ParserBase::fatalParserError(ErrorId _error, SourceLocation const& _location, string const& _description)
|
||||||
{
|
{
|
||||||
m_errorReporter.fatalParserError(1957_error, _location, _description);
|
m_errorReporter.fatalParserError(_error, _location, _description);
|
||||||
}
|
}
|
||||||
|
@ -32,6 +32,7 @@ namespace solidity::langutil
|
|||||||
|
|
||||||
class ErrorReporter;
|
class ErrorReporter;
|
||||||
class Scanner;
|
class Scanner;
|
||||||
|
struct ErrorId;
|
||||||
|
|
||||||
class ParserBase
|
class ParserBase
|
||||||
{
|
{
|
||||||
@ -88,17 +89,17 @@ protected:
|
|||||||
|
|
||||||
/// Creates a @ref ParserError and annotates it with the current position and the
|
/// Creates a @ref ParserError and annotates it with the current position and the
|
||||||
/// given @a _description.
|
/// given @a _description.
|
||||||
void parserError(std::string const& _description);
|
void parserError(ErrorId _error, std::string const& _description);
|
||||||
void parserError(SourceLocation const& _location, std::string const& _description);
|
void parserError(ErrorId _error, SourceLocation const& _location, std::string const& _description);
|
||||||
|
|
||||||
/// Creates a @ref ParserWarning and annotates it with the current position and the
|
/// Creates a @ref ParserWarning and annotates it with the current position and the
|
||||||
/// given @a _description.
|
/// given @a _description.
|
||||||
void parserWarning(std::string const& _description);
|
void parserWarning(ErrorId _error, std::string const& _description);
|
||||||
|
|
||||||
/// Creates a @ref ParserError and annotates it with the current position and the
|
/// Creates a @ref ParserError and annotates it with the current position and the
|
||||||
/// given @a _description. Throws the FatalError.
|
/// given @a _description. Throws the FatalError.
|
||||||
void fatalParserError(std::string const& _description);
|
void fatalParserError(ErrorId _error, std::string const& _description);
|
||||||
void fatalParserError(SourceLocation const& _location, std::string const& _description);
|
void fatalParserError(ErrorId _error, SourceLocation const& _location, std::string const& _description);
|
||||||
|
|
||||||
std::shared_ptr<Scanner> m_scanner;
|
std::shared_ptr<Scanner> m_scanner;
|
||||||
/// The reference to the list of errors and warning to add errors/warnings during parsing
|
/// The reference to the list of errors and warning to add errors/warnings during parsing
|
||||||
|
@ -103,7 +103,7 @@ ASTPointer<SourceUnit> Parser::parse(shared_ptr<Scanner> const& _scanner)
|
|||||||
nodes.push_back(parseEnumDefinition());
|
nodes.push_back(parseEnumDefinition());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fatalParserError(string("Expected pragma, import directive or contract/interface/library/struct/enum definition."));
|
fatalParserError(7858_error, "Expected pragma, import directive or contract/interface/library/struct/enum definition.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
solAssert(m_recursionDepth == 0, "");
|
solAssert(m_recursionDepth == 0, "");
|
||||||
@ -163,7 +163,7 @@ ASTPointer<PragmaDirective> Parser::parsePragmaDirective()
|
|||||||
{
|
{
|
||||||
Token token = m_scanner->currentToken();
|
Token token = m_scanner->currentToken();
|
||||||
if (token == Token::Illegal)
|
if (token == Token::Illegal)
|
||||||
parserError("Token incompatible with Solidity parser as part of pragma directive.");
|
parserError(6281_error, "Token incompatible with Solidity parser as part of pragma directive.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string literal = m_scanner->currentLiteral();
|
string literal = m_scanner->currentLiteral();
|
||||||
@ -241,18 +241,18 @@ ASTPointer<ImportDirective> Parser::parseImportDirective()
|
|||||||
unitAlias = expectIdentifierToken();
|
unitAlias = expectIdentifierToken();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fatalParserError("Expected string literal (path), \"*\" or alias list.");
|
fatalParserError(9478_error, "Expected string literal (path), \"*\" or alias list.");
|
||||||
// "from" is not a keyword but parsed as an identifier because of backwards
|
// "from" is not a keyword but parsed as an identifier because of backwards
|
||||||
// compatibility and because it is a really common word.
|
// compatibility and because it is a really common word.
|
||||||
if (m_scanner->currentToken() != Token::Identifier || m_scanner->currentLiteral() != "from")
|
if (m_scanner->currentToken() != Token::Identifier || m_scanner->currentLiteral() != "from")
|
||||||
fatalParserError("Expected \"from\".");
|
fatalParserError(8208_error, "Expected \"from\".");
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
if (m_scanner->currentToken() != Token::StringLiteral)
|
if (m_scanner->currentToken() != Token::StringLiteral)
|
||||||
fatalParserError("Expected import path.");
|
fatalParserError(6845_error, "Expected import path.");
|
||||||
path = getLiteralAndAdvance();
|
path = getLiteralAndAdvance();
|
||||||
}
|
}
|
||||||
if (path->empty())
|
if (path->empty())
|
||||||
fatalParserError("Import path cannot be empty.");
|
fatalParserError(6326_error, "Import path cannot be empty.");
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::Semicolon);
|
expectToken(Token::Semicolon);
|
||||||
return nodeFactory.createNode<ImportDirective>(path, unitAlias, move(symbolAliases));
|
return nodeFactory.createNode<ImportDirective>(path, unitAlias, move(symbolAliases));
|
||||||
@ -279,7 +279,7 @@ std::pair<ContractKind, bool> Parser::parseContractKind()
|
|||||||
kind = ContractKind::Library;
|
kind = ContractKind::Library;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
parserError("Expected keyword \"contract\", \"interface\" or \"library\".");
|
parserError(3515_error, "Expected keyword \"contract\", \"interface\" or \"library\".");
|
||||||
return std::make_pair(ContractKind::Contract, abstract);
|
return std::make_pair(ContractKind::Contract, abstract);
|
||||||
}
|
}
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
@ -344,7 +344,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
|||||||
else if (currentTokenValue == Token::Using)
|
else if (currentTokenValue == Token::Using)
|
||||||
subNodes.push_back(parseUsingDirective());
|
subNodes.push_back(parseUsingDirective());
|
||||||
else
|
else
|
||||||
fatalParserError(string("Function, variable, struct or modifier declaration expected."));
|
fatalParserError(9182_error, "Function, variable, struct or modifier declaration expected.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (FatalError const&)
|
catch (FatalError const&)
|
||||||
@ -463,6 +463,7 @@ StateMutability Parser::parseStateMutability()
|
|||||||
case Token::Constant:
|
case Token::Constant:
|
||||||
stateMutability = StateMutability::View;
|
stateMutability = StateMutability::View;
|
||||||
parserError(
|
parserError(
|
||||||
|
7698_error,
|
||||||
"The state mutability modifier \"constant\" was removed in version 0.5.0. "
|
"The state mutability modifier \"constant\" was removed in version 0.5.0. "
|
||||||
"Use \"view\" or \"pure\" instead."
|
"Use \"view\" or \"pure\" instead."
|
||||||
);
|
);
|
||||||
@ -495,11 +496,12 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVari
|
|||||||
// Detect this and return early.
|
// Detect this and return early.
|
||||||
if (_isStateVariable && (result.visibility == Visibility::External || result.visibility == Visibility::Internal))
|
if (_isStateVariable && (result.visibility == Visibility::External || result.visibility == Visibility::Internal))
|
||||||
break;
|
break;
|
||||||
parserError(string(
|
parserError(
|
||||||
|
9439_error,
|
||||||
"Visibility already specified as \"" +
|
"Visibility already specified as \"" +
|
||||||
Declaration::visibilityToString(result.visibility) +
|
Declaration::visibilityToString(result.visibility) +
|
||||||
"\"."
|
"\"."
|
||||||
));
|
);
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -509,11 +511,12 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVari
|
|||||||
{
|
{
|
||||||
if (result.stateMutability != StateMutability::NonPayable)
|
if (result.stateMutability != StateMutability::NonPayable)
|
||||||
{
|
{
|
||||||
parserError(string(
|
parserError(
|
||||||
|
9680_error,
|
||||||
"State mutability already specified as \"" +
|
"State mutability already specified as \"" +
|
||||||
stateMutabilityToString(result.stateMutability) +
|
stateMutabilityToString(result.stateMutability) +
|
||||||
"\"."
|
"\"."
|
||||||
));
|
);
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -522,14 +525,14 @@ Parser::FunctionHeaderParserResult Parser::parseFunctionHeader(bool _isStateVari
|
|||||||
else if (!_isStateVariable && token == Token::Override)
|
else if (!_isStateVariable && token == Token::Override)
|
||||||
{
|
{
|
||||||
if (result.overrides)
|
if (result.overrides)
|
||||||
parserError("Override already specified.");
|
parserError(1827_error, "Override already specified.");
|
||||||
|
|
||||||
result.overrides = parseOverrideSpecifier();
|
result.overrides = parseOverrideSpecifier();
|
||||||
}
|
}
|
||||||
else if (!_isStateVariable && token == Token::Virtual)
|
else if (!_isStateVariable && token == Token::Virtual)
|
||||||
{
|
{
|
||||||
if (result.isVirtual)
|
if (result.isVirtual)
|
||||||
parserError("Virtual already specified.");
|
parserError(6879_error, "Virtual already specified.");
|
||||||
|
|
||||||
result.isVirtual = true;
|
result.isVirtual = true;
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
@ -577,9 +580,9 @@ ASTPointer<ASTNode> Parser::parseFunctionDefinition()
|
|||||||
"the \"function\" keyword to define it."
|
"the \"function\" keyword to define it."
|
||||||
};
|
};
|
||||||
if (m_scanner->currentToken() == Token::Constructor)
|
if (m_scanner->currentToken() == Token::Constructor)
|
||||||
parserError(message);
|
parserError(3323_error, message);
|
||||||
else
|
else
|
||||||
parserWarning(message);
|
parserWarning(3445_error, message);
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -660,10 +663,10 @@ ASTPointer<EnumDefinition> Parser::parseEnumDefinition()
|
|||||||
break;
|
break;
|
||||||
expectToken(Token::Comma);
|
expectToken(Token::Comma);
|
||||||
if (m_scanner->currentToken() != Token::Identifier)
|
if (m_scanner->currentToken() != Token::Identifier)
|
||||||
fatalParserError(string("Expected identifier after ','"));
|
fatalParserError(1612_error, "Expected identifier after ','");
|
||||||
}
|
}
|
||||||
if (members.empty())
|
if (members.empty())
|
||||||
parserError({"enum with no members is not allowed."});
|
parserError(3147_error, "enum with no members is not allowed.");
|
||||||
|
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
expectToken(Token::RBrace);
|
expectToken(Token::RBrace);
|
||||||
@ -690,6 +693,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
|
|
||||||
if (dynamic_cast<FunctionTypeName*>(type.get()) && _options.isStateVariable && m_scanner->currentToken() == Token::LBrace)
|
if (dynamic_cast<FunctionTypeName*>(type.get()) && _options.isStateVariable && m_scanner->currentToken() == Token::LBrace)
|
||||||
fatalParserError(
|
fatalParserError(
|
||||||
|
2915_error,
|
||||||
"Expected a state variable declaration. If you intended this as a fallback function "
|
"Expected a state variable declaration. If you intended this as a fallback function "
|
||||||
"or a function to handle plain ether transactions, use the \"fallback\" keyword "
|
"or a function to handle plain ether transactions, use the \"fallback\" keyword "
|
||||||
"or the \"receive\" keyword instead."
|
"or the \"receive\" keyword instead."
|
||||||
@ -710,11 +714,12 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
if (visibility != Visibility::Default)
|
if (visibility != Visibility::Default)
|
||||||
{
|
{
|
||||||
parserError(string(
|
parserError(
|
||||||
|
4110_error,
|
||||||
"Visibility already specified as \"" +
|
"Visibility already specified as \"" +
|
||||||
Declaration::visibilityToString(visibility) +
|
Declaration::visibilityToString(visibility) +
|
||||||
"\"."
|
"\"."
|
||||||
));
|
);
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -723,7 +728,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
else if (_options.isStateVariable && token == Token::Override)
|
else if (_options.isStateVariable && token == Token::Override)
|
||||||
{
|
{
|
||||||
if (overrides)
|
if (overrides)
|
||||||
parserError("Override already specified.");
|
parserError(9125_error, "Override already specified.");
|
||||||
|
|
||||||
overrides = parseOverrideSpecifier();
|
overrides = parseOverrideSpecifier();
|
||||||
}
|
}
|
||||||
@ -735,6 +740,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
{
|
{
|
||||||
if (mutability != VariableDeclaration::Mutability::Mutable)
|
if (mutability != VariableDeclaration::Mutability::Mutable)
|
||||||
parserError(
|
parserError(
|
||||||
|
3109_error,
|
||||||
string("Mutability already set to ") +
|
string("Mutability already set to ") +
|
||||||
(mutability == VariableDeclaration::Mutability::Constant ? "\"constant\"" : "\"immutable\"")
|
(mutability == VariableDeclaration::Mutability::Constant ? "\"constant\"" : "\"immutable\"")
|
||||||
);
|
);
|
||||||
@ -746,9 +752,9 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
|||||||
else if (_options.allowLocationSpecifier && TokenTraits::isLocationSpecifier(token))
|
else if (_options.allowLocationSpecifier && TokenTraits::isLocationSpecifier(token))
|
||||||
{
|
{
|
||||||
if (location != VariableDeclaration::Location::Unspecified)
|
if (location != VariableDeclaration::Location::Unspecified)
|
||||||
parserError(string("Location already specified."));
|
parserError(3548_error, "Location already specified.");
|
||||||
else if (!type)
|
else if (!type)
|
||||||
parserError(string("Location specifier needs explicit type name."));
|
parserError(7439_error, "Location specifier needs explicit type name.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
switch (token)
|
switch (token)
|
||||||
@ -837,13 +843,13 @@ ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()
|
|||||||
if (m_scanner->currentToken() == Token::Override)
|
if (m_scanner->currentToken() == Token::Override)
|
||||||
{
|
{
|
||||||
if (overrides)
|
if (overrides)
|
||||||
parserError("Override already specified.");
|
parserError(9102_error, "Override already specified.");
|
||||||
overrides = parseOverrideSpecifier();
|
overrides = parseOverrideSpecifier();
|
||||||
}
|
}
|
||||||
else if (m_scanner->currentToken() == Token::Virtual)
|
else if (m_scanner->currentToken() == Token::Virtual)
|
||||||
{
|
{
|
||||||
if (isVirtual)
|
if (isVirtual)
|
||||||
parserError("Virtual already specified.");
|
parserError(2662_error, "Virtual already specified.");
|
||||||
|
|
||||||
isVirtual = true;
|
isVirtual = true;
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
@ -991,7 +997,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
parserError("State mutability can only be specified for address types.");
|
parserError(9106_error, "State mutability can only be specified for address types.");
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1000,7 +1006,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
|||||||
else if (token == Token::Var)
|
else if (token == Token::Var)
|
||||||
{
|
{
|
||||||
if (!_allowVar)
|
if (!_allowVar)
|
||||||
parserError(string("Expected explicit type name."));
|
parserError(7059_error, "Expected explicit type name.");
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else if (token == Token::Function)
|
else if (token == Token::Function)
|
||||||
@ -1010,7 +1016,7 @@ ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
|||||||
else if (token == Token::Identifier)
|
else if (token == Token::Identifier)
|
||||||
type = parseUserDefinedTypeName();
|
type = parseUserDefinedTypeName();
|
||||||
else
|
else
|
||||||
fatalParserError(string("Expected type name"));
|
fatalParserError(3546_error, "Expected type name");
|
||||||
|
|
||||||
if (type)
|
if (type)
|
||||||
// Parse "[...]" postfixes for arrays.
|
// Parse "[...]" postfixes for arrays.
|
||||||
@ -1053,7 +1059,7 @@ ASTPointer<Mapping> Parser::parseMapping()
|
|||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fatalParserError(string("Expected elementary type name or identifier for mapping key type"));
|
fatalParserError(1005_error, "Expected elementary type name or identifier for mapping key type");
|
||||||
expectToken(Token::Arrow);
|
expectToken(Token::Arrow);
|
||||||
bool const allowVar = false;
|
bool const allowVar = false;
|
||||||
ASTPointer<TypeName> valueType = parseTypeName(allowVar);
|
ASTPointer<TypeName> valueType = parseTypeName(allowVar);
|
||||||
@ -1079,7 +1085,7 @@ ASTPointer<ParameterList> Parser::parseParameterList(
|
|||||||
while (m_scanner->currentToken() != Token::RParen)
|
while (m_scanner->currentToken() != Token::RParen)
|
||||||
{
|
{
|
||||||
if (m_scanner->currentToken() == Token::Comma && m_scanner->peekNextToken() == Token::RParen)
|
if (m_scanner->currentToken() == Token::Comma && m_scanner->peekNextToken() == Token::RParen)
|
||||||
fatalParserError("Unexpected trailing comma in parameter list.");
|
fatalParserError(7591_error, "Unexpected trailing comma in parameter list.");
|
||||||
expectToken(Token::Comma);
|
expectToken(Token::Comma);
|
||||||
parameters.push_back(parseVariableDeclaration(options));
|
parameters.push_back(parseVariableDeclaration(options));
|
||||||
}
|
}
|
||||||
@ -1214,7 +1220,7 @@ ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> con
|
|||||||
if (m_scanner->currentToken() == Token::StringLiteral)
|
if (m_scanner->currentToken() == Token::StringLiteral)
|
||||||
{
|
{
|
||||||
if (m_scanner->currentLiteral() != "evmasm")
|
if (m_scanner->currentLiteral() != "evmasm")
|
||||||
fatalParserError("Only \"evmasm\" supported.");
|
fatalParserError(4531_error, "Only \"evmasm\" supported.");
|
||||||
// This can be used in the future to set the dialect.
|
// This can be used in the future to set the dialect.
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
@ -1377,7 +1383,7 @@ ASTPointer<EmitStatement> Parser::parseEmitStatement(ASTPointer<ASTString> const
|
|||||||
ASTNodeFactory eventCallNodeFactory(*this);
|
ASTNodeFactory eventCallNodeFactory(*this);
|
||||||
|
|
||||||
if (m_scanner->currentToken() != Token::Identifier)
|
if (m_scanner->currentToken() != Token::Identifier)
|
||||||
fatalParserError("Expected event name or path.");
|
fatalParserError(5620_error, "Expected event name or path.");
|
||||||
|
|
||||||
IndexAccessedPath iap;
|
IndexAccessedPath iap;
|
||||||
while (true)
|
while (true)
|
||||||
@ -1845,7 +1851,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
if (m_scanner->currentToken() == Token::Illegal)
|
if (m_scanner->currentToken() == Token::Illegal)
|
||||||
fatalParserError(to_string(m_scanner->currentError()));
|
fatalParserError(5428_error, to_string(m_scanner->currentError()));
|
||||||
expression = nodeFactory.createNode<Literal>(token, make_shared<ASTString>(literal));
|
expression = nodeFactory.createNode<Literal>(token, make_shared<ASTString>(literal));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1876,7 +1882,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
if (m_scanner->currentToken() != Token::Comma && m_scanner->currentToken() != oppositeToken)
|
if (m_scanner->currentToken() != Token::Comma && m_scanner->currentToken() != oppositeToken)
|
||||||
components.push_back(parseExpression());
|
components.push_back(parseExpression());
|
||||||
else if (isArray)
|
else if (isArray)
|
||||||
parserError("Expected expression (inline array elements cannot be omitted).");
|
parserError(4799_error, "Expected expression (inline array elements cannot be omitted).");
|
||||||
else
|
else
|
||||||
components.push_back(ASTPointer<Expression>());
|
components.push_back(ASTPointer<Expression>());
|
||||||
|
|
||||||
@ -1891,7 +1897,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Token::Illegal:
|
case Token::Illegal:
|
||||||
fatalParserError(to_string(m_scanner->currentError()));
|
fatalParserError(8936_error, to_string(m_scanner->currentError()));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (TokenTraits::isElementaryTypeName(token))
|
if (TokenTraits::isElementaryTypeName(token))
|
||||||
@ -1907,7 +1913,7 @@ ASTPointer<Expression> Parser::parsePrimaryExpression()
|
|||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fatalParserError(string("Expected primary expression."));
|
fatalParserError(6933_error, "Expected primary expression.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return expression;
|
return expression;
|
||||||
@ -1965,7 +1971,7 @@ pair<vector<ASTPointer<Expression>>, vector<ASTPointer<ASTString>>> Parser::pars
|
|||||||
m_scanner->peekNextToken() == Token::RBrace
|
m_scanner->peekNextToken() == Token::RBrace
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
parserError("Unexpected trailing comma.");
|
parserError(2074_error, "Unexpected trailing comma.");
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2084,7 +2090,7 @@ ASTPointer<TypeName> Parser::typeNameFromIndexAccessStructure(Parser::IndexAcces
|
|||||||
for (auto const& lengthExpression: _iap.indices)
|
for (auto const& lengthExpression: _iap.indices)
|
||||||
{
|
{
|
||||||
if (lengthExpression.end)
|
if (lengthExpression.end)
|
||||||
parserError(lengthExpression.location, "Expected array length expression.");
|
parserError(5464_error, lengthExpression.location, "Expected array length expression.");
|
||||||
nodeFactory.setLocation(lengthExpression.location);
|
nodeFactory.setLocation(lengthExpression.location);
|
||||||
type = nodeFactory.createNode<ArrayTypeName>(type, lengthExpression.start);
|
type = nodeFactory.createNode<ArrayTypeName>(type, lengthExpression.start);
|
||||||
}
|
}
|
||||||
|
@ -122,11 +122,11 @@ Statement Parser::parseStatement()
|
|||||||
if (currentToken() == Token::Default)
|
if (currentToken() == Token::Default)
|
||||||
_switch.cases.emplace_back(parseCase());
|
_switch.cases.emplace_back(parseCase());
|
||||||
if (currentToken() == Token::Default)
|
if (currentToken() == Token::Default)
|
||||||
fatalParserError("Only one default case allowed.");
|
fatalParserError(6931_error, "Only one default case allowed.");
|
||||||
else if (currentToken() == Token::Case)
|
else if (currentToken() == Token::Case)
|
||||||
fatalParserError("Case not allowed after default case.");
|
fatalParserError(4904_error, "Case not allowed after default case.");
|
||||||
if (_switch.cases.empty())
|
if (_switch.cases.empty())
|
||||||
fatalParserError("Switch statement without any cases.");
|
fatalParserError(2418_error, "Switch statement without any cases.");
|
||||||
_switch.location.end = _switch.cases.back().body.location.end;
|
_switch.location.end = _switch.cases.back().body.location.end;
|
||||||
return Statement{move(_switch)};
|
return Statement{move(_switch)};
|
||||||
}
|
}
|
||||||
@ -184,6 +184,7 @@ Statement Parser::parseStatement()
|
|||||||
auto const token = currentToken() == Token::Comma ? "," : ":=";
|
auto const token = currentToken() == Token::Comma ? "," : ":=";
|
||||||
|
|
||||||
fatalParserError(
|
fatalParserError(
|
||||||
|
2856_error,
|
||||||
std::string("Variable name must precede \"") +
|
std::string("Variable name must precede \"") +
|
||||||
token +
|
token +
|
||||||
"\"" +
|
"\"" +
|
||||||
@ -194,7 +195,7 @@ Statement Parser::parseStatement()
|
|||||||
auto const& identifier = std::get<Identifier>(elementary);
|
auto const& identifier = std::get<Identifier>(elementary);
|
||||||
|
|
||||||
if (m_dialect.builtin(identifier.name))
|
if (m_dialect.builtin(identifier.name))
|
||||||
fatalParserError("Cannot assign to builtin function \"" + identifier.name.str() + "\".");
|
fatalParserError(6272_error, "Cannot assign to builtin function \"" + identifier.name.str() + "\".");
|
||||||
|
|
||||||
variableNames.emplace_back(identifier);
|
variableNames.emplace_back(identifier);
|
||||||
|
|
||||||
@ -218,7 +219,7 @@ Statement Parser::parseStatement()
|
|||||||
return Statement{std::move(assignment)};
|
return Statement{std::move(assignment)};
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fatalParserError("Call or assignment expected.");
|
fatalParserError(6913_error, "Call or assignment expected.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +251,7 @@ Case Parser::parseCase()
|
|||||||
advance();
|
advance();
|
||||||
ElementaryOperation literal = parseElementaryOperation();
|
ElementaryOperation literal = parseElementaryOperation();
|
||||||
if (!holds_alternative<Literal>(literal))
|
if (!holds_alternative<Literal>(literal))
|
||||||
fatalParserError("Literal expected.");
|
fatalParserError(4805_error, "Literal expected.");
|
||||||
_case.value = make_unique<Literal>(std::get<Literal>(std::move(literal)));
|
_case.value = make_unique<Literal>(std::get<Literal>(std::move(literal)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -353,7 +354,7 @@ Parser::ElementaryOperation Parser::parseElementaryOperation()
|
|||||||
break;
|
break;
|
||||||
case Token::Number:
|
case Token::Number:
|
||||||
if (!isValidNumberLiteral(currentLiteral()))
|
if (!isValidNumberLiteral(currentLiteral()))
|
||||||
fatalParserError("Invalid number literal.");
|
fatalParserError(4828_error, "Invalid number literal.");
|
||||||
kind = LiteralKind::Number;
|
kind = LiteralKind::Number;
|
||||||
break;
|
break;
|
||||||
case Token::TrueLiteral:
|
case Token::TrueLiteral:
|
||||||
@ -382,7 +383,7 @@ Parser::ElementaryOperation Parser::parseElementaryOperation()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
fatalParserError("Literal or identifier expected.");
|
fatalParserError(1856_error, "Literal or identifier expected.");
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -472,7 +473,7 @@ Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
|
|||||||
else if (holds_alternative<FunctionCall>(_initialOp))
|
else if (holds_alternative<FunctionCall>(_initialOp))
|
||||||
ret = std::move(std::get<FunctionCall>(_initialOp));
|
ret = std::move(std::get<FunctionCall>(_initialOp));
|
||||||
else
|
else
|
||||||
fatalParserError("Function name expected.");
|
fatalParserError(9980_error, "Function name expected.");
|
||||||
|
|
||||||
expectToken(Token::LParen);
|
expectToken(Token::LParen);
|
||||||
if (currentToken() != Token::RParen)
|
if (currentToken() != Token::RParen)
|
||||||
@ -525,7 +526,7 @@ YulString Parser::expectAsmIdentifier()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_dialect.builtin(name))
|
if (m_dialect.builtin(name))
|
||||||
fatalParserError("Cannot use builtin function name \"" + name.str() + "\" as identifier name.");
|
fatalParserError(5568_error, "Cannot use builtin function name \"" + name.str() + "\" as identifier name.");
|
||||||
advance();
|
advance();
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)
|
|||||||
RecursionGuard guard(*this);
|
RecursionGuard guard(*this);
|
||||||
|
|
||||||
if (currentToken() != Token::Identifier || currentLiteral() != "object")
|
if (currentToken() != Token::Identifier || currentLiteral() != "object")
|
||||||
fatalParserError("Expected keyword \"object\".");
|
fatalParserError(4294_error, "Expected keyword \"object\".");
|
||||||
advance();
|
advance();
|
||||||
|
|
||||||
shared_ptr<Object> ret = make_shared<Object>();
|
shared_ptr<Object> ret = make_shared<Object>();
|
||||||
@ -83,7 +83,7 @@ shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)
|
|||||||
else if (currentToken() == Token::Identifier && currentLiteral() == "data")
|
else if (currentToken() == Token::Identifier && currentLiteral() == "data")
|
||||||
parseData(*ret);
|
parseData(*ret);
|
||||||
else
|
else
|
||||||
fatalParserError("Expected keyword \"data\" or \"object\" or \"}\".");
|
fatalParserError(8143_error, "Expected keyword \"data\" or \"object\" or \"}\".");
|
||||||
}
|
}
|
||||||
if (_containingObject)
|
if (_containingObject)
|
||||||
addNamedSubObject(*_containingObject, ret->name, ret);
|
addNamedSubObject(*_containingObject, ret->name, ret);
|
||||||
@ -96,7 +96,7 @@ shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)
|
|||||||
shared_ptr<Block> ObjectParser::parseCode()
|
shared_ptr<Block> ObjectParser::parseCode()
|
||||||
{
|
{
|
||||||
if (currentToken() != Token::Identifier || currentLiteral() != "code")
|
if (currentToken() != Token::Identifier || currentLiteral() != "code")
|
||||||
fatalParserError("Expected keyword \"code\".");
|
fatalParserError(4846_error, "Expected keyword \"code\".");
|
||||||
advance();
|
advance();
|
||||||
|
|
||||||
return parseBlock();
|
return parseBlock();
|
||||||
@ -133,11 +133,11 @@ YulString ObjectParser::parseUniqueName(Object const* _containingObject)
|
|||||||
expectToken(Token::StringLiteral, false);
|
expectToken(Token::StringLiteral, false);
|
||||||
YulString name{currentLiteral()};
|
YulString name{currentLiteral()};
|
||||||
if (name.empty())
|
if (name.empty())
|
||||||
parserError("Object name cannot be empty.");
|
parserError(3287_error, "Object name cannot be empty.");
|
||||||
else if (_containingObject && _containingObject->name == name)
|
else if (_containingObject && _containingObject->name == name)
|
||||||
parserError("Object name cannot be the same as the name of the containing object.");
|
parserError(8311_error, "Object name cannot be the same as the name of the containing object.");
|
||||||
else if (_containingObject && _containingObject->subIndexByName.count(name))
|
else if (_containingObject && _containingObject->subIndexByName.count(name))
|
||||||
parserError("Object name \"" + name.str() + "\" already exists inside the containing object.");
|
parserError(8794_error, "Object name \"" + name.str() + "\" already exists inside the containing object.");
|
||||||
advance();
|
advance();
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user