diff options
author | Christian <c@ethdev.com> | 2014-10-09 02:53:50 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2014-10-09 02:53:50 +0800 |
commit | 0a1ebe4f516a5c1e8ebc12798a94529bdda9b6df (patch) | |
tree | dcc068f33caaa625872b1c1e612f6c362b13145f /Scanner.cpp | |
parent | 56e9cc8db71f8af949123e13e6a97cc056cf766d (diff) | |
download | dexon-solidity-0a1ebe4f516a5c1e8ebc12798a94529bdda9b6df.tar.gz dexon-solidity-0a1ebe4f516a5c1e8ebc12798a94529bdda9b6df.tar.zst dexon-solidity-0a1ebe4f516a5c1e8ebc12798a94529bdda9b6df.zip |
Parse everything up to function bodies and report parser errors with location.
Diffstat (limited to 'Scanner.cpp')
-rw-r--r-- | Scanner.cpp | 48 |
1 files changed, 43 insertions, 5 deletions
diff --git a/Scanner.cpp b/Scanner.cpp index a936e24f..836e0d09 100644 --- a/Scanner.cpp +++ b/Scanner.cpp @@ -40,6 +40,9 @@ // You should have received a copy of the GNU General Public License // along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. +#include <algorithm> +#include <tuple> + #include <libsolidity/Scanner.h> namespace dev { @@ -121,6 +124,7 @@ Token::Value Scanner::next() return m_current_token.token; } + bool Scanner::skipWhitespace() { const int start_position = getSourcePos(); @@ -182,7 +186,7 @@ void Scanner::scanToken() Token::Value token; do { // Remember the position of the next token - m_next_token.location.beg_pos = getSourcePos(); + m_next_token.location.start = getSourcePos(); switch (m_char) { case '\n': @@ -401,7 +405,7 @@ void Scanner::scanToken() // whitespace. } while (token == Token::WHITESPACE); - m_next_token.location.end_pos = getSourcePos(); + m_next_token.location.end = getSourcePos(); m_next_token.token = token; } @@ -546,7 +550,7 @@ Token::Value Scanner::scanNumber(bool _periodSeen) #define KEYWORDS(KEYWORD_GROUP, KEYWORD) \ KEYWORD_GROUP('a') \ - KEYWORD("address", Token::BREAK) \ + KEYWORD("address", Token::ADDRESS) \ KEYWORD_GROUP('b') \ KEYWORD("break", Token::BREAK) \ KEYWORD("bool", Token::BOOL) \ @@ -588,8 +592,8 @@ Token::Value Scanner::scanNumber(bool _periodSeen) KEYWORD("interface", Token::FUTURE_STRICT_RESERVED_WORD) \ KEYWORD_GROUP('l') \ KEYWORD_GROUP('m') \ - KEYWORD_GROUP('n') \ KEYWORD("mapping", Token::MAPPING) \ + KEYWORD_GROUP('n') \ KEYWORD("new", Token::NEW) \ KEYWORD("null", Token::NULL_LITERAL) \ KEYWORD_GROUP('p') \ @@ -600,8 +604,9 @@ Token::Value Scanner::scanNumber(bool _periodSeen) KEYWORD_GROUP('r') \ KEYWORD("real", Token::REAL) \ KEYWORD("return", Token::RETURN) \ + KEYWORD("returns", Token::RETURNS) \ KEYWORD_GROUP('s') \ - KEYWORD("string", Token::STRING_TYPE) \ + KEYWORD("string", Token::STRING_TYPE) \ KEYWORD("struct", Token::STRUCT) \ KEYWORD("switch", Token::SWITCH) \ KEYWORD_GROUP('t') \ @@ -671,5 +676,38 @@ Token::Value Scanner::scanIdentifierOrKeyword() return KeywordOrIdentifierToken(m_next_token.literal); } +std::string CharStream::getLineAtPosition(int _position) const +{ + // if _position points to \n, it returns the line before the \n + using size_type = std::string::size_type; + size_type searchStart = std::min<size_type>(m_source.size(), _position); + if (searchStart > 0) searchStart--; + size_type lineStart = m_source.rfind('\n', searchStart); + if (lineStart == std::string::npos) + lineStart = 0; + else + lineStart++; + return m_source.substr(lineStart, + std::min(m_source.find('\n', lineStart), + m_source.size()) - lineStart); +} + +std::tuple<int, int> CharStream::translatePositionToLineColumn(int _position) const +{ + using size_type = std::string::size_type; + size_type searchPosition = std::min<size_type>(m_source.size(), _position); + int lineNumber = std::count(m_source.begin(), m_source.begin() + searchPosition, '\n'); + + size_type lineStart; + if (searchPosition == 0) { + lineStart = 0; + } else { + lineStart = m_source.rfind('\n', searchPosition - 1); + lineStart = lineStart == std::string::npos ? 0 : lineStart + 1; + } + + return std::tuple<int, int>(lineNumber, searchPosition - lineStart); +} + } } |