#pragma once
#include <liblangutil/Exceptions.h>
#include <libsolutil/CommonData.h>
#include <test/libsolidity/util/SoltestTypes.h>
#include <iosfwd>
#include <iterator>
#include <numeric>
#include <stdexcept>
#include <string>
#include <vector>
#include <utility>
namespace solidity::frontend::test
{
class TestFileParser
{
public:
explicit TestFileParser(std::istream& _stream, std::map<std::string, Builtin> const& _builtins):
m_scanner(_stream),
m_builtins(_builtins)
{}
std::vector<FunctionCall> parseFunctionCalls(std::size_t _lineOffset);
private:
class Scanner
{
public:
Scanner(std::istream& _stream) { readStream(_stream); }
void readStream(std::istream& _stream);
void scanNextToken();
soltest::Token currentToken() { return m_currentToken; }
std::string currentLiteral() { return m_currentLiteral; }
std::string scanComment();
std::string scanIdentifierOrKeyword();
std::string scanDecimalNumber();
std::string scanHexNumber();
std::string scanString();
std::string readLine();
char scanHexPart();
private:
void advance(unsigned n = 1)
{
solAssert(m_char != m_source.end(), "Cannot advance beyond end.");
m_char = std::next(m_char, n);
}
char current() const noexcept
{
if (m_char == m_source.end())
return '\0';
return *m_char;
}
char peek() const noexcept;
bool isEndOfFile() const { return m_char == m_source.end(); }
std::string m_source;
std::string::const_iterator m_char;
std::string m_currentLiteral;
soltest::Token m_currentToken = soltest::Token::Unknown;
};
bool accept(soltest::Token _token, bool const _expect = false);
bool expect(soltest::Token _token, bool const _advance = true);
std::pair<std::string, bool> parseFunctionSignature();
FunctionValue parseFunctionCallValue();
FunctionCallArgs parseFunctionCallArguments();
FunctionCallExpectations parseFunctionCallExpectations();
Parameter parseParameter();
std::string parseIdentifierOrTuple();
std::string parseBoolean();
std::string parseComment();
std::string parseDecimalNumber();
std::string parseHexNumber();
std::string parseString();
std::vector<std::string> parseFunctionCallSideEffects();
bool isBuiltinFunction(std::string const& _signature);
Scanner m_scanner;
size_t m_lineNumber = 0;
std::map<std::string, Builtin> const& m_builtins;
};
}