Add ScannerKind and replace supportPeriodInIdentifier

This commit is contained in:
Alex Beregszaszi 2020-07-10 16:05:52 +01:00
parent 52eeeacafb
commit d9cb8c8c5e
4 changed files with 23 additions and 18 deletions

View File

@ -147,7 +147,7 @@ void Scanner::reset(shared_ptr<CharStream> _source)
void Scanner::reset() void Scanner::reset()
{ {
m_source->reset(); m_source->reset();
m_supportPeriodInIdentifier = false; m_kind = ScannerKind::Solidity;
m_char = m_source->get(); m_char = m_source->get();
skipWhitespace(); skipWhitespace();
next(); next();
@ -163,12 +163,6 @@ void Scanner::setPosition(size_t _offset)
next(); next();
} }
void Scanner::supportPeriodInIdentifier(bool _value)
{
m_supportPeriodInIdentifier = _value;
rescan();
}
bool Scanner::scanHexByte(char& o_scannedByte) bool Scanner::scanHexByte(char& o_scannedByte)
{ {
char x = 0; char x = 0;
@ -970,7 +964,7 @@ tuple<Token, unsigned, unsigned> Scanner::scanIdentifierOrKeyword()
LiteralScope literal(this, LITERAL_TYPE_STRING); LiteralScope literal(this, LITERAL_TYPE_STRING);
addLiteralCharAndAdvance(); addLiteralCharAndAdvance();
// Scan the rest of the identifier characters. // Scan the rest of the identifier characters.
while (isIdentifierPart(m_char) || (m_char == '.' && m_supportPeriodInIdentifier)) while (isIdentifierPart(m_char) || (m_char == '.' && m_kind == ScannerKind::Yul))
addLiteralCharAndAdvance(); addLiteralCharAndAdvance();
literal.complete(); literal.complete();
return TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal); return TokenTraits::fromIdentifierOrKeyword(m_tokens[NextNext].literal);

View File

@ -68,6 +68,12 @@ class AstRawString;
class AstValueFactory; class AstValueFactory;
class ParserRecorder; class ParserRecorder;
enum class ScannerKind
{
Solidity,
Yul
};
enum class ScannerError enum class ScannerError
{ {
NoError, NoError,
@ -107,9 +113,14 @@ public:
/// Resets scanner to the start of input. /// Resets scanner to the start of input.
void reset(); void reset();
/// Enables or disables support for period in identifier. /// Changes the scanner mode.
/// This re-scans the current token and comment literal and thus invalidates it. void setScannerMode(ScannerKind _kind)
void supportPeriodInIdentifier(bool _value); {
m_kind = _kind;
// Invalidate lookahead buffer.
rescan();
}
/// @returns the next token and advances input /// @returns the next token and advances input
Token next(); Token next();
@ -249,8 +260,6 @@ private:
size_t sourcePos() const { return m_source->position(); } size_t sourcePos() const { return m_source->position(); }
bool isSourcePastEndOfInput() const { return m_source->isPastEndOfInput(); } bool isSourcePastEndOfInput() const { return m_source->isPastEndOfInput(); }
bool m_supportPeriodInIdentifier = false;
enum TokenIndex { Current, Next, NextNext }; enum TokenIndex { Current, Next, NextNext };
TokenDesc m_skippedComments[3] = {}; // desc for the current, next and nextnext skipped comment TokenDesc m_skippedComments[3] = {}; // desc for the current, next and nextnext skipped comment
@ -258,6 +267,8 @@ private:
std::shared_ptr<CharStream> m_source; std::shared_ptr<CharStream> m_source;
ScannerKind m_kind = ScannerKind::Solidity;
/// one character look-ahead, equals 0 at end of input /// one character look-ahead, equals 0 at end of input
char m_char; char m_char;
}; };

View File

@ -42,8 +42,8 @@ unique_ptr<Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner, bool _
{ {
m_recursionDepth = 0; m_recursionDepth = 0;
_scanner->supportPeriodInIdentifier(true); _scanner->setScannerMode(ScannerKind::Yul);
ScopeGuard resetScanner([&]{ _scanner->supportPeriodInIdentifier(false); }); ScopeGuard resetScanner([&]{ _scanner->setScannerMode(ScannerKind::Solidity); });
try try
{ {

View File

@ -214,7 +214,7 @@ BOOST_AUTO_TEST_CASE(leading_dot_in_identifier)
BOOST_CHECK_EQUAL(scanner.next(), Token::LParen); BOOST_CHECK_EQUAL(scanner.next(), Token::LParen);
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
scanner.reset(CharStream("function .a(", "")); scanner.reset(CharStream("function .a(", ""));
scanner.supportPeriodInIdentifier(true); scanner.setScannerMode(ScannerKind::Yul);
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function); BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);
BOOST_CHECK_EQUAL(scanner.next(), Token::Period); BOOST_CHECK_EQUAL(scanner.next(), Token::Period);
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier); BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(middle_dot_in_identifier)
BOOST_CHECK_EQUAL(scanner.next(), Token::LParen); BOOST_CHECK_EQUAL(scanner.next(), Token::LParen);
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
scanner.reset(CharStream("function a...a(", "")); scanner.reset(CharStream("function a...a(", ""));
scanner.supportPeriodInIdentifier(true); scanner.setScannerMode(ScannerKind::Yul);
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function); BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier); BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
BOOST_CHECK_EQUAL(scanner.next(), Token::LParen); BOOST_CHECK_EQUAL(scanner.next(), Token::LParen);
@ -249,7 +249,7 @@ BOOST_AUTO_TEST_CASE(trailing_dot_in_identifier)
BOOST_CHECK_EQUAL(scanner.next(), Token::LParen); BOOST_CHECK_EQUAL(scanner.next(), Token::LParen);
BOOST_CHECK_EQUAL(scanner.next(), Token::EOS); BOOST_CHECK_EQUAL(scanner.next(), Token::EOS);
scanner.reset(CharStream("function a.(", "")); scanner.reset(CharStream("function a.(", ""));
scanner.supportPeriodInIdentifier(true); scanner.setScannerMode(ScannerKind::Yul);
BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function); BOOST_CHECK_EQUAL(scanner.currentToken(), Token::Function);
BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier); BOOST_CHECK_EQUAL(scanner.next(), Token::Identifier);
BOOST_CHECK_EQUAL(scanner.next(), Token::LParen); BOOST_CHECK_EQUAL(scanner.next(), Token::LParen);