1 /* 2 * This file is part of solidity. 3 * 4 * solidity is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * solidity is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with solidity. If not, see <http://www.gnu.org/licenses/>. 16 * 17 * This file is derived from the file "scanner.h", which was part of the 18 * V8 project. The original copyright header follows: 19 * 20 * Copyright 2006-2012, the V8 project authors. All rights reserved. 21 * Redistribution and use in source and binary forms, with or without 22 * modification, are permitted provided that the following conditions are 23 * met: 24 * 25 * * Redistributions of source code must retain the above copyright 26 * notice, this list of conditions and the following disclaimer. 27 * * Redistributions in binary form must reproduce the above 28 * copyright notice, this list of conditions and the following 29 * disclaimer in the documentation and/or other materials provided 30 * with the distribution. 31 * * Neither the name of Google Inc. nor the names of its 32 * contributors may be used to endorse or promote products derived 33 * from this software without specific prior written permission. 34 * 35 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 36 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 37 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 38 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 39 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 42 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 43 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 44 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 45 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 46 */ 47 /** 48 * Character stream / input file. 49 */ 50 51 #pragma once 52 53 #include <cstdint> 54 #include <optional> 55 #include <string> 56 #include <tuple> 57 #include <utility> 58 59 namespace solidity::langutil 60 { 61 62 struct SourceLocation; 63 struct LineColumn; 64 65 /** 66 * Bidirectional stream of characters. 67 * 68 * This CharStream is used by lexical analyzers as the source. 69 */ 70 class CharStream 71 { 72 public: 73 CharStream() = default; CharStream(std::string _source,std::string _name)74 CharStream(std::string _source, std::string _name): 75 m_source(std::move(_source)), m_name(std::move(_name)) {} 76 position()77 size_t position() const { return m_position; } 78 bool isPastEndOfInput(size_t _charsForward = 0) const { return (m_position + _charsForward) >= m_source.size(); } 79 80 char get(size_t _charsForward = 0) const { return m_source[m_position + _charsForward]; } 81 char advanceAndGet(size_t _chars = 1); 82 /// Sets scanner position to @ _amount characters backwards in source text. 83 /// @returns The character of the current location after update is returned. 84 char rollback(size_t _amount); 85 /// Sets scanner position to @ _location if it refers a valid offset in m_source. 86 /// If not, nothing is done. 87 /// @returns The character of the current location after update is returned. 88 char setPosition(size_t _location); 89 reset()90 void reset() { m_position = 0; } 91 source()92 std::string const& source() const noexcept { return m_source; } name()93 std::string const& name() const noexcept { return m_name; } 94 size()95 size_t size() const { return m_source.size(); } 96 97 ///@{ 98 ///@name Error printing helper functions 99 /// Functions that help pretty-printing parse errors 100 /// Do only use in error cases, they are quite expensive. 101 std::string lineAtPosition(int _position) const; 102 LineColumn translatePositionToLineColumn(int _position) const; 103 ///@} 104 105 /// Translates a line:column to the absolute position. 106 std::optional<int> translateLineColumnToPosition(LineColumn const& _lineColumn) const; 107 108 /// Translates a line:column to the absolute position for the given input text. 109 static std::optional<int> translateLineColumnToPosition(std::string const& _text, LineColumn const& _input); 110 111 /// Tests whether or not given octet sequence is present at the current position in stream. 112 /// @returns true if the sequence could be found, false otherwise. prefixMatch(std::string_view _sequence)113 bool prefixMatch(std::string_view _sequence) 114 { 115 if (isPastEndOfInput(_sequence.size())) 116 return false; 117 118 for (size_t i = 0; i < _sequence.size(); ++i) 119 if (_sequence[i] != get(i)) 120 return false; 121 122 return true; 123 } 124 125 /// @returns the substring of the source that the source location references. 126 /// Returns an empty string view if the source location does not `hasText()`. 127 std::string_view text(SourceLocation const& _location) const; 128 129 /// @returns the first line of the referenced source fragment. If the fragment is longer than 130 /// one line, appends an ellipsis to indicate that. singleLineSnippet(SourceLocation const & _location)131 std::string singleLineSnippet(SourceLocation const& _location) const 132 { 133 return singleLineSnippet(m_source, _location); 134 } 135 136 static std::string singleLineSnippet(std::string const& _sourceCode, SourceLocation const& _location); 137 138 private: 139 std::string m_source; 140 std::string m_name; 141 size_t m_position{0}; 142 }; 143 144 } 145