mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #3554 from ethereum/reuseScannerOrNot
Expect end of string at end of top-level block for assembly parser.
This commit is contained in:
commit
3076a434ba
@ -8,6 +8,7 @@ Features:
|
|||||||
Bugfixes:
|
Bugfixes:
|
||||||
* JSON-AST: Add "documentation" property to function, event and modifier definition.
|
* JSON-AST: Add "documentation" property to function, event and modifier definition.
|
||||||
* Resolver: Properly determine shadowing for imports with aliases.
|
* Resolver: Properly determine shadowing for imports with aliases.
|
||||||
|
* Standalone Assembly: Do not ignore input after closing brace of top level block.
|
||||||
* Standard JSON: catch errors properly when invalid "sources" are passed
|
* Standard JSON: catch errors properly when invalid "sources" are passed
|
||||||
* Type Checker: Properly warn when using ``_offset`` and ``_slot`` for constants in inline assembly.
|
* Type Checker: Properly warn when using ``_offset`` and ``_slot`` for constants in inline assembly.
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ void CompilerContext::appendInlineAssembly(
|
|||||||
ErrorList errors;
|
ErrorList errors;
|
||||||
ErrorReporter errorReporter(errors);
|
ErrorReporter errorReporter(errors);
|
||||||
auto scanner = make_shared<Scanner>(CharStream(_assembly), "--CODEGEN--");
|
auto scanner = make_shared<Scanner>(CharStream(_assembly), "--CODEGEN--");
|
||||||
auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::Strict).parse(scanner);
|
auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::Strict).parse(scanner, false);
|
||||||
#ifdef SOL_OUTPUT_ASM
|
#ifdef SOL_OUTPUT_ASM
|
||||||
cout << assembly::AsmPrinter()(*parserResult) << endl;
|
cout << assembly::AsmPrinter()(*parserResult) << endl;
|
||||||
#endif
|
#endif
|
||||||
|
@ -34,13 +34,16 @@ using namespace dev;
|
|||||||
using namespace dev::solidity;
|
using namespace dev::solidity;
|
||||||
using namespace dev::solidity::assembly;
|
using namespace dev::solidity::assembly;
|
||||||
|
|
||||||
shared_ptr<assembly::Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner)
|
shared_ptr<assembly::Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner)
|
||||||
{
|
{
|
||||||
m_recursionDepth = 0;
|
m_recursionDepth = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
m_scanner = _scanner;
|
m_scanner = _scanner;
|
||||||
return make_shared<Block>(parseBlock());
|
auto block = make_shared<Block>(parseBlock());
|
||||||
|
if (!_reuseScanner)
|
||||||
|
expectToken(Token::EOS);
|
||||||
|
return block;
|
||||||
}
|
}
|
||||||
catch (FatalError const&)
|
catch (FatalError const&)
|
||||||
{
|
{
|
||||||
|
@ -41,8 +41,9 @@ public:
|
|||||||
ParserBase(_errorReporter), m_flavour(_flavour) {}
|
ParserBase(_errorReporter), m_flavour(_flavour) {}
|
||||||
|
|
||||||
/// Parses an inline assembly block starting with `{` and ending with `}`.
|
/// Parses an inline assembly block starting with `{` and ending with `}`.
|
||||||
|
/// @param _reuseScanner if true, do check for end of input after the `}`.
|
||||||
/// @returns an empty shared pointer on error.
|
/// @returns an empty shared pointer on error.
|
||||||
std::shared_ptr<Block> parse(std::shared_ptr<Scanner> const& _scanner);
|
std::shared_ptr<Block> parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using ElementaryOperation = boost::variant<assembly::Instruction, assembly::Literal, assembly::Identifier>;
|
using ElementaryOperation = boost::variant<assembly::Instruction, assembly::Literal, assembly::Identifier>;
|
||||||
|
@ -69,7 +69,7 @@ bool AssemblyStack::parseAndAnalyze(std::string const& _sourceName, std::string
|
|||||||
m_errors.clear();
|
m_errors.clear();
|
||||||
m_analysisSuccessful = false;
|
m_analysisSuccessful = false;
|
||||||
m_scanner = make_shared<Scanner>(CharStream(_source), _sourceName);
|
m_scanner = make_shared<Scanner>(CharStream(_source), _sourceName);
|
||||||
m_parserResult = assembly::Parser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner);
|
m_parserResult = assembly::Parser(m_errorReporter, languageToAsmFlavour(m_language)).parse(m_scanner, false);
|
||||||
if (!m_errorReporter.errors().empty())
|
if (!m_errorReporter.errors().empty())
|
||||||
return false;
|
return false;
|
||||||
solAssert(m_parserResult, "");
|
solAssert(m_parserResult, "");
|
||||||
|
@ -926,7 +926,7 @@ ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> con
|
|||||||
}
|
}
|
||||||
|
|
||||||
assembly::Parser asmParser(m_errorReporter);
|
assembly::Parser asmParser(m_errorReporter);
|
||||||
shared_ptr<assembly::Block> block = asmParser.parse(m_scanner);
|
shared_ptr<assembly::Block> block = asmParser.parse(m_scanner, true);
|
||||||
nodeFactory.markEndPosition();
|
nodeFactory.markEndPosition();
|
||||||
return nodeFactory.createNode<InlineAssembly>(_docString, block);
|
return nodeFactory.createNode<InlineAssembly>(_docString, block);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ pair<shared_ptr<Block>, shared_ptr<assembly::AsmAnalysisInfo>> dev::julia::test:
|
|||||||
ErrorList errors;
|
ErrorList errors;
|
||||||
ErrorReporter errorReporter(errors);
|
ErrorReporter errorReporter(errors);
|
||||||
auto scanner = make_shared<Scanner>(CharStream(_source), "");
|
auto scanner = make_shared<Scanner>(CharStream(_source), "");
|
||||||
auto parserResult = assembly::Parser(errorReporter, flavour).parse(scanner);
|
auto parserResult = assembly::Parser(errorReporter, flavour).parse(scanner, false);
|
||||||
if (parserResult)
|
if (parserResult)
|
||||||
{
|
{
|
||||||
BOOST_REQUIRE(errorReporter.errors().empty());
|
BOOST_REQUIRE(errorReporter.errors().empty());
|
||||||
|
@ -52,7 +52,7 @@ bool parse(string const& _source, ErrorReporter& errorReporter)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto scanner = make_shared<Scanner>(CharStream(_source));
|
auto scanner = make_shared<Scanner>(CharStream(_source));
|
||||||
auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::IULIA).parse(scanner);
|
auto parserResult = assembly::Parser(errorReporter, assembly::AsmFlavour::IULIA).parse(scanner, false);
|
||||||
if (parserResult)
|
if (parserResult)
|
||||||
{
|
{
|
||||||
assembly::AsmAnalysisInfo analysisInfo;
|
assembly::AsmAnalysisInfo analysisInfo;
|
||||||
|
@ -168,6 +168,11 @@ BOOST_AUTO_TEST_CASE(smoke_test)
|
|||||||
BOOST_CHECK(successParse("{ }"));
|
BOOST_CHECK(successParse("{ }"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(surplus_input)
|
||||||
|
{
|
||||||
|
CHECK_PARSE_ERROR("{ } { }", ParserError, "Expected token EOS");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(simple_instructions)
|
BOOST_AUTO_TEST_CASE(simple_instructions)
|
||||||
{
|
{
|
||||||
BOOST_CHECK(successParse("{ dup1 dup1 mul dup1 sub pop }"));
|
BOOST_CHECK(successParse("{ dup1 dup1 mul dup1 sub pop }"));
|
||||||
|
Loading…
Reference in New Issue
Block a user