]> gitweb.ps.run Git - toc/blob - antlr4-cpp-runtime-4.9.2-source/runtime/src/ANTLRInputStream.cpp
add antlr source code and ReadMe
[toc] / antlr4-cpp-runtime-4.9.2-source / runtime / src / ANTLRInputStream.cpp
1 /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved.
2  * Use of this file is governed by the BSD 3-clause license that
3  * can be found in the LICENSE.txt file in the project root.
4  */
5
6 #include <string.h>
7
8 #include "Exceptions.h"
9 #include "misc/Interval.h"
10 #include "IntStream.h"
11
12 #include "support/StringUtils.h"
13 #include "support/CPPUtils.h"
14
15 #include "ANTLRInputStream.h"
16
17 using namespace antlr4;
18 using namespace antlrcpp;
19
20 using misc::Interval;
21
22 ANTLRInputStream::ANTLRInputStream() {
23   InitializeInstanceFields();
24 }
25
26 #if __cplusplus >= 201703L
27 ANTLRInputStream::ANTLRInputStream(const std::string_view &input): ANTLRInputStream() {
28   load(input.data(), input.length());
29 }
30 #endif
31
32 ANTLRInputStream::ANTLRInputStream(const std::string &input): ANTLRInputStream() {
33   load(input.data(), input.size());
34 }
35
36 ANTLRInputStream::ANTLRInputStream(const char *data, size_t length) {
37   load(data, length);
38 }
39
40 ANTLRInputStream::ANTLRInputStream(std::istream &stream): ANTLRInputStream() {
41   load(stream);
42 }
43
44 void ANTLRInputStream::load(const std::string &input) {
45   load(input.data(), input.size());
46 }
47
48 void ANTLRInputStream::load(const char *data, size_t length) {
49   // Remove the UTF-8 BOM if present.
50   const char *bom = "\xef\xbb\xbf";
51   if (length >= 3 && strncmp(data, bom, 3) == 0)
52     _data = antlrcpp::utf8_to_utf32(data + 3, data + length);
53   else
54     _data = antlrcpp::utf8_to_utf32(data, data + length);
55   p = 0;
56 }
57
58 void ANTLRInputStream::load(std::istream &stream) {
59   if (!stream.good() || stream.eof()) // No fail, bad or EOF.
60     return;
61
62   _data.clear();
63
64   std::string s((std::istreambuf_iterator<char>(stream)), std::istreambuf_iterator<char>());
65   load(s.data(), s.length());
66 }
67
68 void ANTLRInputStream::reset() {
69   p = 0;
70 }
71
72 void ANTLRInputStream::consume() {
73   if (p >= _data.size()) {
74     assert(LA(1) == IntStream::EOF);
75     throw IllegalStateException("cannot consume EOF");
76   }
77
78   if (p < _data.size()) {
79     p++;
80   }
81 }
82
83 size_t ANTLRInputStream::LA(ssize_t i) {
84   if (i == 0) {
85     return 0; // undefined
86   }
87
88   ssize_t position = static_cast<ssize_t>(p);
89   if (i < 0) {
90     i++; // e.g., translate LA(-1) to use offset i=0; then _data[p+0-1]
91     if ((position + i - 1) < 0) {
92       return IntStream::EOF; // invalid; no char before first char
93     }
94   }
95
96   if ((position + i - 1) >= static_cast<ssize_t>(_data.size())) {
97     return IntStream::EOF;
98   }
99
100   return _data[static_cast<size_t>((position + i - 1))];
101 }
102
103 size_t ANTLRInputStream::LT(ssize_t i) {
104   return LA(i);
105 }
106
107 size_t ANTLRInputStream::index() {
108   return p;
109 }
110
111 size_t ANTLRInputStream::size() {
112   return _data.size();
113 }
114
115 // Mark/release do nothing. We have entire buffer.
116 ssize_t ANTLRInputStream::mark() {
117   return -1;
118 }
119
120 void ANTLRInputStream::release(ssize_t /* marker */) {
121 }
122
123 void ANTLRInputStream::seek(size_t index) {
124   if (index <= p) {
125     p = index; // just jump; don't update stream state (line, ...)
126     return;
127   }
128   // seek forward, consume until p hits index or n (whichever comes first)
129   index = std::min(index, _data.size());
130   while (p < index) {
131     consume();
132   }
133 }
134
135 std::string ANTLRInputStream::getText(const Interval &interval) {
136   if (interval.a < 0 || interval.b < 0) {
137     return "";
138   }
139
140   size_t start = static_cast<size_t>(interval.a);
141   size_t stop = static_cast<size_t>(interval.b);
142
143
144   if (stop >= _data.size()) {
145     stop = _data.size() - 1;
146   }
147
148   size_t count = stop - start + 1;
149   if (start >= _data.size()) {
150     return "";
151   }
152
153   return antlrcpp::utf32_to_utf8(_data.substr(start, count));
154 }
155
156 std::string ANTLRInputStream::getSourceName() const {
157   if (name.empty()) {
158     return IntStream::UNKNOWN_SOURCE_NAME;
159   }
160   return name;
161 }
162
163 std::string ANTLRInputStream::toString() const {
164   return antlrcpp::utf32_to_utf8(_data);
165 }
166
167 void ANTLRInputStream::InitializeInstanceFields() {
168   p = 0;
169 }