1 | import { TokenKind } from './Token';
|
2 | import { TokenSequence } from './TokenSequence';
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | var TokenReader = (function () {
|
14 | function TokenReader(parserContext, embeddedTokenSequence) {
|
15 | this._parserContext = parserContext;
|
16 | this.tokens = parserContext.tokens;
|
17 | if (embeddedTokenSequence) {
|
18 | if (embeddedTokenSequence.parserContext !== this._parserContext) {
|
19 | throw new Error('The embeddedTokenSequence must use the same parser context');
|
20 | }
|
21 | this._readerStartIndex = embeddedTokenSequence.startIndex;
|
22 | this._readerEndIndex = embeddedTokenSequence.endIndex;
|
23 | }
|
24 | else {
|
25 | this._readerStartIndex = 0;
|
26 | this._readerEndIndex = this.tokens.length;
|
27 | }
|
28 | this._currentIndex = this._readerStartIndex;
|
29 | this._accumulatedStartIndex = this._readerStartIndex;
|
30 | }
|
31 | |
32 |
|
33 |
|
34 |
|
35 | TokenReader.prototype.extractAccumulatedSequence = function () {
|
36 | if (this._accumulatedStartIndex === this._currentIndex) {
|
37 |
|
38 | throw new Error('Parser assertion failed: The queue should not be empty when' +
|
39 | ' extractAccumulatedSequence() is called');
|
40 | }
|
41 | var sequence = new TokenSequence({
|
42 | parserContext: this._parserContext,
|
43 | startIndex: this._accumulatedStartIndex,
|
44 | endIndex: this._currentIndex
|
45 | });
|
46 | this._accumulatedStartIndex = this._currentIndex;
|
47 | return sequence;
|
48 | };
|
49 | |
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 | TokenReader.prototype.isAccumulatedSequenceEmpty = function () {
|
56 | return this._accumulatedStartIndex === this._currentIndex;
|
57 | };
|
58 | |
59 |
|
60 |
|
61 |
|
62 | TokenReader.prototype.tryExtractAccumulatedSequence = function () {
|
63 | if (this.isAccumulatedSequenceEmpty()) {
|
64 | return undefined;
|
65 | }
|
66 | return this.extractAccumulatedSequence();
|
67 | };
|
68 | |
69 |
|
70 |
|
71 |
|
72 | TokenReader.prototype.assertAccumulatedSequenceIsEmpty = function () {
|
73 | if (!this.isAccumulatedSequenceEmpty()) {
|
74 |
|
75 | var sequence = new TokenSequence({
|
76 | parserContext: this._parserContext,
|
77 | startIndex: this._accumulatedStartIndex,
|
78 | endIndex: this._currentIndex
|
79 | });
|
80 | var tokenStrings = sequence.tokens.map(function (x) { return x.toString(); });
|
81 | throw new Error('Parser assertion failed: The queue should be empty, but it contains:\n' +
|
82 | JSON.stringify(tokenStrings));
|
83 | }
|
84 | };
|
85 | |
86 |
|
87 |
|
88 |
|
89 | TokenReader.prototype.peekToken = function () {
|
90 | return this.tokens[this._currentIndex];
|
91 | };
|
92 | |
93 |
|
94 |
|
95 |
|
96 | TokenReader.prototype.peekTokenKind = function () {
|
97 | if (this._currentIndex >= this._readerEndIndex) {
|
98 | return TokenKind.EndOfInput;
|
99 | }
|
100 | return this.tokens[this._currentIndex].kind;
|
101 | };
|
102 | |
103 |
|
104 |
|
105 | TokenReader.prototype.peekTokenAfterKind = function () {
|
106 | if (this._currentIndex + 1 >= this._readerEndIndex) {
|
107 | return TokenKind.EndOfInput;
|
108 | }
|
109 | return this.tokens[this._currentIndex + 1].kind;
|
110 | };
|
111 | |
112 |
|
113 |
|
114 | TokenReader.prototype.peekTokenAfterAfterKind = function () {
|
115 | if (this._currentIndex + 2 >= this._readerEndIndex) {
|
116 | return TokenKind.EndOfInput;
|
117 | }
|
118 | return this.tokens[this._currentIndex + 2].kind;
|
119 | };
|
120 | |
121 |
|
122 |
|
123 |
|
124 |
|
125 | TokenReader.prototype.readToken = function () {
|
126 | if (this._currentIndex >= this._readerEndIndex) {
|
127 |
|
128 | throw new Error('Cannot read past end of stream');
|
129 | }
|
130 | var token = this.tokens[this._currentIndex];
|
131 | if (token.kind === TokenKind.EndOfInput) {
|
132 |
|
133 |
|
134 |
|
135 | throw new Error('The EndOfInput token cannot be read');
|
136 | }
|
137 | this._currentIndex++;
|
138 | return token;
|
139 | };
|
140 | |
141 |
|
142 |
|
143 | TokenReader.prototype.peekPreviousTokenKind = function () {
|
144 | if (this._currentIndex === 0) {
|
145 | return TokenKind.EndOfInput;
|
146 | }
|
147 | return this.tokens[this._currentIndex - 1].kind;
|
148 | };
|
149 | |
150 |
|
151 |
|
152 | TokenReader.prototype.createMarker = function () {
|
153 | return this._currentIndex;
|
154 | };
|
155 | |
156 |
|
157 |
|
158 | TokenReader.prototype.backtrackToMarker = function (marker) {
|
159 | if (marker > this._currentIndex) {
|
160 |
|
161 | throw new Error('The marker has expired');
|
162 | }
|
163 | this._currentIndex = marker;
|
164 | if (marker < this._accumulatedStartIndex) {
|
165 | this._accumulatedStartIndex = marker;
|
166 | }
|
167 | };
|
168 | return TokenReader;
|
169 | }());
|
170 | export { TokenReader };
|
171 |
|
\ | No newline at end of file |