├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .gitmodules
├── .npmignore
├── .travis.yml
├── CHANGES.md
├── LICENSE
├── README.md
├── index.d.ts
├── package.json
├── scripts
└── antlr4.sh
├── src
├── ASTBuilder.js
├── ErrorListener.js
├── antlr4
│ ├── BufferedTokenStream.js
│ ├── CharStreams.js
│ ├── CommonTokenFactory.js
│ ├── CommonTokenStream.js
│ ├── FileStream.js
│ ├── InputStream.js
│ ├── IntervalSet.js
│ ├── LL1Analyzer.js
│ ├── Lexer.js
│ ├── Parser.js
│ ├── ParserRuleContext.js
│ ├── PredictionContext.js
│ ├── README.md
│ ├── Recognizer.js
│ ├── RuleContext.js
│ ├── Token.js
│ ├── Utils.js
│ ├── atn
│ │ ├── ATN.js
│ │ ├── ATNConfig.js
│ │ ├── ATNConfigSet.js
│ │ ├── ATNDeserializationOptions.js
│ │ ├── ATNDeserializer.js
│ │ ├── ATNSimulator.js
│ │ ├── ATNState.js
│ │ ├── ATNType.js
│ │ ├── LexerATNSimulator.js
│ │ ├── LexerAction.js
│ │ ├── LexerActionExecutor.js
│ │ ├── ParserATNSimulator.js
│ │ ├── PredictionMode.js
│ │ ├── SemanticContext.js
│ │ ├── Transition.js
│ │ └── index.js
│ ├── dfa
│ │ ├── DFA.js
│ │ ├── DFASerializer.js
│ │ ├── DFAState.js
│ │ └── index.js
│ ├── error
│ │ ├── DiagnosticErrorListener.js
│ │ ├── ErrorListener.js
│ │ ├── ErrorStrategy.js
│ │ ├── Errors.js
│ │ └── index.js
│ ├── index.js
│ ├── package.json
│ ├── polyfills
│ │ ├── codepointat.js
│ │ └── fromcodepoint.js
│ └── tree
│ │ ├── Tree.js
│ │ ├── Trees.js
│ │ └── index.js
├── index.js
├── lib
│ ├── Solidity.interp
│ ├── Solidity.tokens
│ ├── SolidityLexer.interp
│ ├── SolidityLexer.js
│ ├── SolidityLexer.tokens
│ ├── SolidityListener.js
│ └── SolidityParser.js
└── tokens.js
├── test
├── ast.js
├── index.js
├── test.sol
└── utils.js
├── tslint.json
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env"],
3 | "plugins": [
4 | ["babel-plugin-inline-import", {
5 | "extensions": [".tokens"]
6 | }]
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | trim_trailing_whitespace = true
8 |
9 | [*.js]
10 | indent_style = space
11 | indent_size = 2
12 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | src/lib
2 | src/antlr4
3 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["eslint:recommended"],
3 | "plugins": [
4 | "promise"
5 | ],
6 | "rules": {
7 | "no-var": 2,
8 | "object-curly-spacing": [2, "always"],
9 | "object-shorthand": 2,
10 | "prefer-const": 2,
11 | "max-len": 2
12 | },
13 | "parserOptions": {
14 | "ecmaVersion": 2017,
15 | "sourceType": "module"
16 | },
17 | "env": {
18 | "es6": true,
19 | "mocha": true,
20 | "node": true
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .nyc_output/
3 | dist/
4 | .vscode/settings.json
5 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "solidity-antlr4"]
2 | path = solidity-antlr4
3 | url = https://github.com/consensys/solidity-antlr4
4 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src/
2 | test/
3 | scripts/
4 | .nyc_output/
5 | .travis.yml
6 | .gitmodules
7 | .eslintrc
8 | .editorconfig
9 | solidity-antlr4/
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "8"
4 |
--------------------------------------------------------------------------------
/CHANGES.md:
--------------------------------------------------------------------------------
1 | ### 0.5.0 (Unreleased)
2 |
3 | * Remove `ParameterList` and `Parameter` node types. Parameters are now always
4 | of type `VariableDeclaration` and lists of parameters are represented as
5 | lists of nodes of type `VariableDeclaration`. This is a breaking change.
6 |
7 | ### 0.4.12 (Unreleased)
8 |
9 | * Fix type name expressions to also support user-defined type names.
10 |
11 | ### 0.4.11
12 |
13 | * Bugfix release
14 |
15 | ### 0.4.9
16 |
17 | * Fix parsing of inheritance specifier with no arguments.
18 |
19 | ### 0.4.8
20 |
21 | * Fix parsing of string literals with escaped characters.
22 |
23 | ### 0.4.7
24 |
25 | * Fix parsing of underscores in number literals.
26 |
27 | ### 0.4.6
28 |
29 | * Add support for the `type` keyword.
30 | * Add support for underscores in number literals.
31 |
32 | ### 0.4.5
33 |
34 | * Improve TypeScript type definitions.
35 |
36 | ### 0.4.4
37 |
38 | * Add missing `storageLocation` to variables in VariableDeclarationStatement.
39 | * Return `null` for `arguments` instead of `[]` when `ModifierInvocation`
40 | contains no arguments and no parentheses to distinguish the two cases.
41 | * Improve TypeScript type definitions.
42 |
43 | ### 0.4.3
44 |
45 | * Improve TypeScript type definitions, thanks @Leeleo3x and @yxliang01.
46 |
47 | ### 0.4.2
48 |
49 | * Fix parsing of assembly function definitions with no args or return args.
50 |
51 | ### 0.4.1
52 |
53 | * Fix parsing of for loops with missing initial and condition statements.
54 |
55 | ### 0.4.0
56 |
57 | * Correctly handle non-existent tuple components. Thanks @maxsam4
58 | * Accept calldata as identifier
59 |
60 | ### 0.3.3
61 |
62 | * Add support for `address payable` typename.
63 |
64 | ### 0.3.2
65 |
66 | * Fix parsing of hex numbers with uppercase X.
67 |
68 | ### 0.3.1
69 |
70 | * Fix parsing of zero-component tuples.
71 |
72 | ### 0.3.0
73 |
74 | * Use `components` for all `TupleExpression` nodes. Earlier versions
75 | incorrectly stored tuple components under the `elements` key.
76 | * Fix parsing of decimal literals without integer part.
77 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017-2018 Federico Bond
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [
12 | // This token stream ignores the value of {@link Token//getChannel}. If your
13 | // parser requires the token stream filter tokens to only those on a particular
14 | // channel, such as {@link Token//DEFAULT_CHANNEL} or
15 | // {@link Token//HIDDEN_CHANNEL}, use a filtering token stream such a
16 | // {@link CommonTokenStream}. This field is set to -1 when the stream is first constructed or when
44 | // {@link //setTokenSource} is called, indicating that the first token has
45 | // not yet been fetched from the token source. For additional information,
46 | // see the documentation of {@link IntStream} for a description of
47 | // Initializing Methods. For example, {@link CommonTokenStream} overrides this method to ensure
211 | // that
212 | // the seek target is always an on-channel token.
32 | // The default value is {@code false} to avoid the performance and memory
33 | // overhead of copying text for every token unless explicitly requested.
46 | // This token factory does not explicitly copy token text when constructing
47 | // tokens.
14 | // This token stream provides access to all tokens by index or when calling
15 | // methods like {@link //getText}. The channel filtering is only used for code
16 | // accessing tokens via the lookahead methods {@link //LA}, {@link //LT}, and
17 | // {@link //LB}.
20 | // By default, tokens are placed on the default channel
21 | // ({@link Token//DEFAULT_CHANNEL}), but may be reassigned by using the
22 | // {@code ->channel(HIDDEN)} lexer command, or by using an embedded action to
23 | // call {@link Lexer//setChannel}.
24 | //
27 | // Note: lexer rules which use the {@code ->skip} lexer command or call
28 | // {@link Lexer//skip} do not produce tokens at all, so input text matched by
29 | // such a rule will not be available as part of the token stream, regardless of
30 | // channel. If {@code ctx} is {@code null} and the end of the rule containing
71 | // {@code s} is reached, {@link Token//EPSILON} is added to the result set.
72 | // If {@code ctx} is not {@code null} and the end of the outermost rule is
73 | // reached, {@link Token//EOF} is added to the result set. If {@code ctx} is {@code null} and {@code stopState} or the end of the
98 | // rule containing {@code s} is reached, {@link Token//EPSILON} is added to
99 | // the result set. If {@code ctx} is not {@code null} and {@code addEOF} is
100 | // {@code true} and {@code stopState} or the end of the outermost rule is
101 | // reached, {@link Token//EOF} is added to the result set.](https://diligence.consensys.net)
2 |
3 | [[ 🌐 ](https://diligence.consensys.net/?utm_source=github_npm&utm_medium=banner&utm_campaign=solidity-parser-diligence) [ 📩 ](mailto:diligence@consensys.net) [ 🔥 ](https://consensys.github.io/diligence/)]
4 |
5 |
6 |
7 | solidity-parser-diligence
8 | =====================
9 |
10 | A Solidity parser built on top of a robust [ANTLR4 grammar](https://github.com/consensys/solidity-antlr4).
11 |
12 | Now maintained by the ConsenSys Diligence team! :tada:
13 |
14 | You can find this new package in NPM at `solidity-parser-diligence` (https://www.npmjs.com/package/solidity-parser-diligence).
15 |
16 | ### Usage
17 |
18 | ```javascript
19 | import parser from 'solidity-parser-diligence';
20 |
21 | var input = `
22 | contract test {
23 | uint256 a;
24 | function f() {}
25 | }
26 | `
27 | try {
28 | parser.parse(input)
29 | } catch (e) {
30 | if (e instanceof parser.ParserError) {
31 | console.log(e.errors)
32 | }
33 | }
34 | ```
35 |
36 | The `parse` method also accepts a second argument which lets you specify the
37 | following options, in a style similar to the _esprima_ API:
38 |
39 | | Key | Type | Default | Description |
40 | |----------|---------|---------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
41 | | tolerant | Boolean | false | When set to `true` it will collect syntax errors and place them in a list under the key `errors` inside the root node of the returned AST. Otherwise, it will raise a `parser.ParserError`. |
42 | | loc | Boolean | false | When set to `true`, it will add location information to each node, with start and stop keys that contain the corresponding line and column numbers. Column numbers start from 0, lines start from 1. |
43 | | range | Boolean | false | When set to `true`, it will add range information to each node, which consists of a two-element array with start and stop character indexes in the input. |
44 |
45 |
46 | #### Example with location information
47 |
48 | ```javascript
49 | parser.parse('contract test { uint a; }', { loc: true })
50 |
51 | // { type: 'SourceUnit',
52 | // children:
53 | // [ { type: 'ContractDefinition',
54 | // name: 'test',
55 | // baseContracts: [],
56 | // subNodes: [Array],
57 | // kind: 'contract',
58 | // loc: [Object] } ],
59 | // loc: { start: { line: 1, column: 0 }, end: { line: 1, column: 24 } } }
60 |
61 | ```
62 |
63 | #### Example using a visitor to walk over the AST
64 |
65 | ```javascript
66 | var ast = parser.parse('contract test { uint a; }')
67 |
68 | // output the path of each import found
69 | parser.visit(ast, {
70 | ImportDirective: function(node) {
71 | console.log(node.path)
72 | }
73 | })
74 | ```
75 |
76 | ### Authors
77 |
78 | Gonçalo Sá ([@gnsps](https://twitter.com/gnsps))
79 |
80 | Federico Bond ([@federicobond](https://github.com/federicobond))
81 |
82 | ### License
83 |
84 | MIT
85 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "solidity-parser-diligence",
3 | "version": "0.4.18",
4 | "description": "A Solidity parser built from a robust ANTLR 4 grammar",
5 | "main": "dist/index.js",
6 | "types": "./index.d.ts",
7 | "scripts": {
8 | "antlr4": "sh scripts/antlr4.sh",
9 | "build": "rm -rf dist && babel --out-dir=dist src --copy-files",
10 | "prepare": "yarn build",
11 | "prettier": "find src -name *.js | egrep -v '^src/(lib|antlr4)/' | xargs prettier --no-semi --single-quote --write",
12 | "eslint": "eslint src",
13 | "pretest": "eslint src && tslint-config-prettier-check ./tslint.json",
14 | "test": "nyc mocha --require babel-register",
15 | "tslint": "tslint-config-prettier-check ./tslint.json"
16 | },
17 | "author": [
18 | "Gonçalo Sá
55 | //
64 | this.fetchedEOF = false;
65 | return this;
66 | }
67 |
68 | BufferedTokenStream.prototype = Object.create(TokenStream.prototype);
69 | BufferedTokenStream.prototype.constructor = BufferedTokenStream;
70 |
71 | BufferedTokenStream.prototype.mark = function() {
72 | return 0;
73 | };
74 |
75 | BufferedTokenStream.prototype.release = function(marker) {
76 | // no resources to release
77 | };
78 |
79 | BufferedTokenStream.prototype.reset = function() {
80 | this.seek(0);
81 | };
82 |
83 | BufferedTokenStream.prototype.seek = function(index) {
84 | this.lazyInit();
85 | this.index = this.adjustSeekIndex(index);
86 | };
87 |
88 | BufferedTokenStream.prototype.get = function(index) {
89 | this.lazyInit();
90 | return this.tokens[index];
91 | };
92 |
93 | BufferedTokenStream.prototype.consume = function() {
94 | var skipEofCheck = false;
95 | if (this.index >= 0) {
96 | if (this.fetchedEOF) {
97 | // the last token in tokens is EOF. skip check if p indexes any
98 | // fetched token except the last.
99 | skipEofCheck = this.index < this.tokens.length - 1;
100 | } else {
101 | // no EOF token in tokens. skip check if p indexes a fetched token.
102 | skipEofCheck = this.index < this.tokens.length;
103 | }
104 | } else {
105 | // not yet initialized
106 | skipEofCheck = false;
107 | }
108 | if (!skipEofCheck && this.LA(1) === Token.EOF) {
109 | throw "cannot consume EOF";
110 | }
111 | if (this.sync(this.index + 1)) {
112 | this.index = this.adjustSeekIndex(this.index + 1);
113 | }
114 | };
115 |
116 | // Make sure index {@code i} in tokens has a token.
117 | //
118 | // @return {@code true} if a token is located at index {@code i}, otherwise
119 | // {@code false}.
120 | // @see //get(int i)
121 | // /
122 | BufferedTokenStream.prototype.sync = function(i) {
123 | var n = i - this.tokens.length + 1; // how many more elements we need?
124 | if (n > 0) {
125 | var fetched = this.fetch(n);
126 | return fetched >= n;
127 | }
128 | return true;
129 | };
130 |
131 | // Add {@code n} elements to buffer.
132 | //
133 | // @return The actual number of elements added to the buffer.
134 | // /
135 | BufferedTokenStream.prototype.fetch = function(n) {
136 | if (this.fetchedEOF) {
137 | return 0;
138 | }
139 | for (var i = 0; i < n; i++) {
140 | var t = this.tokenSource.nextToken();
141 | t.tokenIndex = this.tokens.length;
142 | this.tokens.push(t);
143 | if (t.type === Token.EOF) {
144 | this.fetchedEOF = true;
145 | return i + 1;
146 | }
147 | }
148 | return n;
149 | };
150 |
151 | // Get all tokens from start..stop inclusively///
152 | BufferedTokenStream.prototype.getTokens = function(start, stop, types) {
153 | if (types === undefined) {
154 | types = null;
155 | }
156 | if (start < 0 || stop < 0) {
157 | return null;
158 | }
159 | this.lazyInit();
160 | var subset = [];
161 | if (stop >= this.tokens.length) {
162 | stop = this.tokens.length - 1;
163 | }
164 | for (var i = start; i < stop; i++) {
165 | var t = this.tokens[i];
166 | if (t.type === Token.EOF) {
167 | break;
168 | }
169 | if (types === null || types.contains(t.type)) {
170 | subset.push(t);
171 | }
172 | }
173 | return subset;
174 | };
175 |
176 | BufferedTokenStream.prototype.LA = function(i) {
177 | return this.LT(i).type;
178 | };
179 |
180 | BufferedTokenStream.prototype.LB = function(k) {
181 | if (this.index - k < 0) {
182 | return null;
183 | }
184 | return this.tokens[this.index - k];
185 | };
186 |
187 | BufferedTokenStream.prototype.LT = function(k) {
188 | this.lazyInit();
189 | if (k === 0) {
190 | return null;
191 | }
192 | if (k < 0) {
193 | return this.LB(-k);
194 | }
195 | var i = this.index + k - 1;
196 | this.sync(i);
197 | if (i >= this.tokens.length) { // return EOF token
198 | // EOF must be last token
199 | return this.tokens[this.tokens.length - 1];
200 | }
201 | return this.tokens[i];
202 | };
203 |
204 | // Allowed derived classes to modify the behavior of operations which change
205 | // the current stream position by adjusting the target token index of a seek
206 | // operation. The default implementation simply returns {@code i}. If an
207 | // exception is thrown in this method, the current stream index should not be
208 | // changed.
209 | //
210 | //
79 | // Since tokens on hidden channels (e.g. whitespace or comments) are not 80 | // added to the parse trees, they will not appear in the output of this 81 | // method. 82 | // / 83 | RuleContext.prototype.getText = function() { 84 | if (this.getChildCount() === 0) { 85 | return ""; 86 | } else { 87 | return this.children.map(function(child) { 88 | return child.getText(); 89 | }).join(""); 90 | } 91 | }; 92 | 93 | // For rule associated with this parse tree internal node, return 94 | // the outer alternative number used to match the input. Default 95 | // implementation does not compute nor store this alt num. Create 96 | // a subclass of ParserRuleContext with backing field and set 97 | // option contextSuperClass. 98 | // to set it. 99 | RuleContext.prototype.getAltNumber = function() { return INVALID_ALT_NUMBER; } 100 | 101 | // Set the outer alternative number for this context node. Default 102 | // implementation does nothing to avoid backing field overhead for 103 | // trees that don't need it. Create 104 | // a subclass of ParserRuleContext with backing field and set 105 | // option contextSuperClass. 106 | RuleContext.prototype.setAltNumber = function(altNumber) { } 107 | 108 | RuleContext.prototype.getChild = function(i) { 109 | return null; 110 | }; 111 | 112 | RuleContext.prototype.getChildCount = function() { 113 | return 0; 114 | }; 115 | 116 | RuleContext.prototype.accept = function(visitor) { 117 | return visitor.visitChildren(this); 118 | }; 119 | 120 | //need to manage circular dependencies, so export now 121 | exports.RuleContext = RuleContext; 122 | var Trees = require('./tree/Trees').Trees; 123 | 124 | 125 | // Print out a whole tree, not just a node, in LISP format 126 | // (root child1 .. childN). Print just a node if this is a leaf. 127 | // 128 | 129 | RuleContext.prototype.toStringTree = function(ruleNames, recog) { 130 | return Trees.toStringTree(this, ruleNames, recog); 131 | }; 132 | 133 | RuleContext.prototype.toString = function(ruleNames, stop) { 134 | ruleNames = ruleNames || null; 135 | stop = stop || null; 136 | var p = this; 137 | var s = "["; 138 | while (p !== null && p !== stop) { 139 | if (ruleNames === null) { 140 | if (!p.isEmpty()) { 141 | s += p.invokingState; 142 | } 143 | } else { 144 | var ri = p.ruleIndex; 145 | var ruleName = (ri >= 0 && ri < ruleNames.length) ? ruleNames[ri] 146 | : "" + ri; 147 | s += ruleName; 148 | } 149 | if (p.parentCtx !== null && (ruleNames !== null || !p.parentCtx.isEmpty())) { 150 | s += " "; 151 | } 152 | p = p.parentCtx; 153 | } 154 | s += "]"; 155 | return s; 156 | }; 157 | 158 | -------------------------------------------------------------------------------- /src/antlr4/Token.js: -------------------------------------------------------------------------------- 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 | 7 | // A token has properties: text, type, line, character position in the line 8 | // (so we can ignore tabs), token channel, index, and source from which 9 | // we obtained this token. 10 | 11 | function Token() { 12 | this.source = null; 13 | this.type = null; // token type of the token 14 | this.channel = null; // The parser ignores everything not on DEFAULT_CHANNEL 15 | this.start = null; // optional; return -1 if not implemented. 16 | this.stop = null; // optional; return -1 if not implemented. 17 | this.tokenIndex = null; // from 0..n-1 of the token object in the input stream 18 | this.line = null; // line=1..n of the 1st character 19 | this.column = null; // beginning of the line at which it occurs, 0..n-1 20 | this._text = null; // text of the token. 21 | return this; 22 | } 23 | 24 | Token.INVALID_TYPE = 0; 25 | 26 | // During lookahead operations, this "token" signifies we hit rule end ATN state 27 | // and did not follow it despite needing to. 28 | Token.EPSILON = -2; 29 | 30 | Token.MIN_USER_TOKEN_TYPE = 1; 31 | 32 | Token.EOF = -1; 33 | 34 | // All tokens go to the parser (unless skip() is called in that rule) 35 | // on a particular "channel". The parser tunes to a particular channel 36 | // so that whitespace etc... can go to the parser on a "hidden" channel. 37 | 38 | Token.DEFAULT_CHANNEL = 0; 39 | 40 | // Anything on different channel than DEFAULT_CHANNEL is not parsed 41 | // by parser. 42 | 43 | Token.HIDDEN_CHANNEL = 1; 44 | 45 | // Explicitly set the text for this token. If {code text} is not 46 | // {@code null}, then {@link //getText} will return this value rather than 47 | // extracting the text from the input. 48 | // 49 | // @param text The explicit text of the token, or {@code null} if the text 50 | // should be obtained from the input along with the start and stop indexes 51 | // of the token. 52 | 53 | Object.defineProperty(Token.prototype, "text", { 54 | get : function() { 55 | return this._text; 56 | }, 57 | set : function(text) { 58 | this._text = text; 59 | } 60 | }); 61 | 62 | Token.prototype.getTokenSource = function() { 63 | return this.source[0]; 64 | }; 65 | 66 | Token.prototype.getInputStream = function() { 67 | return this.source[1]; 68 | }; 69 | 70 | function CommonToken(source, type, channel, start, stop) { 71 | Token.call(this); 72 | this.source = source !== undefined ? source : CommonToken.EMPTY_SOURCE; 73 | this.type = type !== undefined ? type : null; 74 | this.channel = channel !== undefined ? channel : Token.DEFAULT_CHANNEL; 75 | this.start = start !== undefined ? start : -1; 76 | this.stop = stop !== undefined ? stop : -1; 77 | this.tokenIndex = -1; 78 | if (this.source[0] !== null) { 79 | this.line = source[0].line; 80 | this.column = source[0].column; 81 | } else { 82 | this.column = -1; 83 | } 84 | return this; 85 | } 86 | 87 | CommonToken.prototype = Object.create(Token.prototype); 88 | CommonToken.prototype.constructor = CommonToken; 89 | 90 | // An empty {@link Pair} which is used as the default value of 91 | // {@link //source} for tokens that do not have a source. 92 | CommonToken.EMPTY_SOURCE = [ null, null ]; 93 | 94 | // Constructs a new {@link CommonToken} as a copy of another {@link Token}. 95 | // 96 | //
97 | // If {@code oldToken} is also a {@link CommonToken} instance, the newly 98 | // constructed token will share a reference to the {@link //text} field and 99 | // the {@link Pair} stored in {@link //source}. Otherwise, {@link //text} will 100 | // be assigned the result of calling {@link //getText}, and {@link //source} 101 | // will be constructed from the result of {@link Token//getTokenSource} and 102 | // {@link Token//getInputStream}.
103 | // 104 | // @param oldToken The token to copy. 105 | // 106 | CommonToken.prototype.clone = function() { 107 | var t = new CommonToken(this.source, this.type, this.channel, this.start, 108 | this.stop); 109 | t.tokenIndex = this.tokenIndex; 110 | t.line = this.line; 111 | t.column = this.column; 112 | t.text = this.text; 113 | return t; 114 | }; 115 | 116 | Object.defineProperty(CommonToken.prototype, "text", { 117 | get : function() { 118 | if (this._text !== null) { 119 | return this._text; 120 | } 121 | var input = this.getInputStream(); 122 | if (input === null) { 123 | return null; 124 | } 125 | var n = input.size; 126 | if (this.start < n && this.stop < n) { 127 | return input.getText(this.start, this.stop); 128 | } else { 129 | return "If {@code context} is {@code null}, it is treated as 104 | // {@link ParserRuleContext//EMPTY}.
105 | // 106 | // @param stateNumber the ATN state number 107 | // @param context the full parse context 108 | // @return The set of potentially valid input symbols which could follow the 109 | // specified state in the specified context. 110 | // @throws IllegalArgumentException if the ATN does not contain a state with 111 | // number {@code stateNumber} 112 | var Token = require('./../Token').Token; 113 | 114 | ATN.prototype.getExpectedTokens = function( stateNumber, ctx ) { 115 | if ( stateNumber < 0 || stateNumber >= this.states.length ) { 116 | throw("Invalid state number."); 117 | } 118 | var s = this.states[stateNumber]; 119 | var following = this.nextTokens(s); 120 | if (!following.contains(Token.EPSILON)) { 121 | return following; 122 | } 123 | var expected = new IntervalSet(); 124 | expected.addSet(following); 125 | expected.removeOne(Token.EPSILON); 126 | while (ctx !== null && ctx.invokingState >= 0 && following.contains(Token.EPSILON)) { 127 | var invokingState = this.states[ctx.invokingState]; 128 | var rt = invokingState.transitions[0]; 129 | following = this.nextTokens(rt.followState); 130 | expected.addSet(following); 131 | expected.removeOne(Token.EPSILON); 132 | ctx = ctx.parentCtx; 133 | } 134 | if (following.contains(Token.EPSILON)) { 135 | expected.addOne(Token.EOF); 136 | } 137 | return expected; 138 | }; 139 | 140 | ATN.INVALID_ALT_NUMBER = 0; 141 | 142 | exports.ATN = ATN; -------------------------------------------------------------------------------- /src/antlr4/atn/ATNConfig.js: -------------------------------------------------------------------------------- 1 | // 2 | /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 | * Use of this file is governed by the BSD 3-clause license that 4 | * can be found in the LICENSE.txt file in the project root. 5 | */ 6 | /// 7 | 8 | // A tuple: (ATN state, predicted alt, syntactic, semantic context). 9 | // The syntactic context is a graph-structured stack node whose 10 | // path(s) to the root is the rule invocation(s) 11 | // chain used to arrive at the state. The semantic context is 12 | // the tree of semantic predicates encountered before reaching 13 | // an ATN state. 14 | /// 15 | 16 | var DecisionState = require('./ATNState').DecisionState; 17 | var SemanticContext = require('./SemanticContext').SemanticContext; 18 | var Hash = require("../Utils").Hash; 19 | 20 | 21 | function checkParams(params, isCfg) { 22 | if(params===null) { 23 | var result = { state:null, alt:null, context:null, semanticContext:null }; 24 | if(isCfg) { 25 | result.reachesIntoOuterContext = 0; 26 | } 27 | return result; 28 | } else { 29 | var props = {}; 30 | props.state = params.state || null; 31 | props.alt = (params.alt === undefined) ? null : params.alt; 32 | props.context = params.context || null; 33 | props.semanticContext = params.semanticContext || null; 34 | if(isCfg) { 35 | props.reachesIntoOuterContext = params.reachesIntoOuterContext || 0; 36 | props.precedenceFilterSuppressed = params.precedenceFilterSuppressed || false; 37 | } 38 | return props; 39 | } 40 | } 41 | 42 | function ATNConfig(params, config) { 43 | this.checkContext(params, config); 44 | params = checkParams(params); 45 | config = checkParams(config, true); 46 | // The ATN state associated with this configuration/// 47 | this.state = params.state!==null ? params.state : config.state; 48 | // What alt (or lexer rule) is predicted by this configuration/// 49 | this.alt = params.alt!==null ? params.alt : config.alt; 50 | // The stack of invoking states leading to the rule/states associated 51 | // with this config. We track only those contexts pushed during 52 | // execution of the ATN simulator. 53 | this.context = params.context!==null ? params.context : config.context; 54 | this.semanticContext = params.semanticContext!==null ? params.semanticContext : 55 | (config.semanticContext!==null ? config.semanticContext : SemanticContext.NONE); 56 | // We cannot execute predicates dependent upon local context unless 57 | // we know for sure we are in the correct context. Because there is 58 | // no way to do this efficiently, we simply cannot evaluate 59 | // dependent predicates unless we are in the rule that initially 60 | // invokes the ATN simulator. 61 | // 62 | // closure() tracks the depth of how far we dip into the 63 | // outer context: depth > 0. Note that it may not be totally 64 | // accurate depth since I don't ever decrement. TODO: make it a boolean then 65 | this.reachesIntoOuterContext = config.reachesIntoOuterContext; 66 | this.precedenceFilterSuppressed = config.precedenceFilterSuppressed; 67 | return this; 68 | } 69 | 70 | ATNConfig.prototype.checkContext = function(params, config) { 71 | if((params.context===null || params.context===undefined) && 72 | (config===null || config.context===null || config.context===undefined)) { 73 | this.context = null; 74 | } 75 | }; 76 | 77 | 78 | ATNConfig.prototype.hashCode = function() { 79 | var hash = new Hash(); 80 | this.updateHashCode(hash); 81 | return hash.finish(); 82 | }; 83 | 84 | 85 | ATNConfig.prototype.updateHashCode = function(hash) { 86 | hash.update(this.state.stateNumber, this.alt, this.context, this.semanticContext); 87 | }; 88 | 89 | // An ATN configuration is equal to another if both have 90 | // the same state, they predict the same alternative, and 91 | // syntactic/semantic contexts are the same. 92 | 93 | ATNConfig.prototype.equals = function(other) { 94 | if (this === other) { 95 | return true; 96 | } else if (! (other instanceof ATNConfig)) { 97 | return false; 98 | } else { 99 | return this.state.stateNumber===other.state.stateNumber && 100 | this.alt===other.alt && 101 | (this.context===null ? other.context===null : this.context.equals(other.context)) && 102 | this.semanticContext.equals(other.semanticContext) && 103 | this.precedenceFilterSuppressed===other.precedenceFilterSuppressed; 104 | } 105 | }; 106 | 107 | 108 | ATNConfig.prototype.hashCodeForConfigSet = function() { 109 | var hash = new Hash(); 110 | hash.update(this.state.stateNumber, this.alt, this.semanticContext); 111 | return hash.finish(); 112 | }; 113 | 114 | 115 | ATNConfig.prototype.equalsForConfigSet = function(other) { 116 | if (this === other) { 117 | return true; 118 | } else if (! (other instanceof ATNConfig)) { 119 | return false; 120 | } else { 121 | return this.state.stateNumber===other.state.stateNumber && 122 | this.alt===other.alt && 123 | this.semanticContext.equals(other.semanticContext); 124 | } 125 | }; 126 | 127 | 128 | ATNConfig.prototype.toString = function() { 129 | return "(" + this.state + "," + this.alt + 130 | (this.context!==null ? ",[" + this.context.toString() + "]" : "") + 131 | (this.semanticContext !== SemanticContext.NONE ? 132 | ("," + this.semanticContext.toString()) 133 | : "") + 134 | (this.reachesIntoOuterContext>0 ? 135 | (",up=" + this.reachesIntoOuterContext) 136 | : "") + ")"; 137 | }; 138 | 139 | 140 | function LexerATNConfig(params, config) { 141 | ATNConfig.call(this, params, config); 142 | 143 | // This is the backing field for {@link //getLexerActionExecutor}. 144 | var lexerActionExecutor = params.lexerActionExecutor || null; 145 | this.lexerActionExecutor = lexerActionExecutor || (config!==null ? config.lexerActionExecutor : null); 146 | this.passedThroughNonGreedyDecision = config!==null ? this.checkNonGreedyDecision(config, this.state) : false; 147 | return this; 148 | } 149 | 150 | LexerATNConfig.prototype = Object.create(ATNConfig.prototype); 151 | LexerATNConfig.prototype.constructor = LexerATNConfig; 152 | 153 | LexerATNConfig.prototype.updateHashCode = function(hash) { 154 | hash.update(this.state.stateNumber, this.alt, this.context, this.semanticContext, this.passedThroughNonGreedyDecision, this.lexerActionExecutor); 155 | }; 156 | 157 | LexerATNConfig.prototype.equals = function(other) { 158 | return this === other || 159 | (other instanceof LexerATNConfig && 160 | this.passedThroughNonGreedyDecision == other.passedThroughNonGreedyDecision && 161 | (this.lexerActionExecutor ? this.lexerActionExecutor.equals(other.lexerActionExecutor) : !other.lexerActionExecutor) && 162 | ATNConfig.prototype.equals.call(this, other)); 163 | }; 164 | 165 | LexerATNConfig.prototype.hashCodeForConfigSet = LexerATNConfig.prototype.hashCode; 166 | 167 | LexerATNConfig.prototype.equalsForConfigSet = LexerATNConfig.prototype.equals; 168 | 169 | 170 | LexerATNConfig.prototype.checkNonGreedyDecision = function(source, target) { 171 | return source.passedThroughNonGreedyDecision || 172 | (target instanceof DecisionState) && target.nonGreedy; 173 | }; 174 | 175 | exports.ATNConfig = ATNConfig; 176 | exports.LexerATNConfig = LexerATNConfig; -------------------------------------------------------------------------------- /src/antlr4/atn/ATNConfigSet.js: -------------------------------------------------------------------------------- 1 | // 2 | /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 | * Use of this file is governed by the BSD 3-clause license that 4 | * can be found in the LICENSE.txt file in the project root. 5 | */ 6 | 7 | // 8 | // Specialized {@link Set}{@code <}{@link ATNConfig}{@code >} that can track 9 | // info about the set, with support for combining similar configurations using a 10 | // graph-structured stack. 11 | /// 12 | 13 | var ATN = require('./ATN').ATN; 14 | var Utils = require('./../Utils'); 15 | var Hash = Utils.Hash; 16 | var Set = Utils.Set; 17 | var SemanticContext = require('./SemanticContext').SemanticContext; 18 | var merge = require('./../PredictionContext').merge; 19 | 20 | function hashATNConfig(c) { 21 | return c.hashCodeForConfigSet(); 22 | } 23 | 24 | function equalATNConfigs(a, b) { 25 | if ( a===b ) { 26 | return true; 27 | } else if ( a===null || b===null ) { 28 | return false; 29 | } else 30 | return a.equalsForConfigSet(b); 31 | } 32 | 33 | 34 | function ATNConfigSet(fullCtx) { 35 | // 36 | // The reason that we need this is because we don't want the hash map to use 37 | // the standard hash code and equals. We need all configurations with the 38 | // same 39 | // {@code (s,i,_,semctx)} to be equal. Unfortunately, this key effectively 40 | // doubles 41 | // the number of objects associated with ATNConfigs. The other solution is 42 | // to 43 | // use a hash table that lets us specify the equals/hashcode operation. 44 | // All configs but hashed by (s, i, _, pi) not including context. Wiped out 45 | // when we go readonly as this set becomes a DFA state. 46 | this.configLookup = new Set(hashATNConfig, equalATNConfigs); 47 | // Indicates that this configuration set is part of a full context 48 | // LL prediction. It will be used to determine how to merge $. With SLL 49 | // it's a wildcard whereas it is not for LL context merge. 50 | this.fullCtx = fullCtx === undefined ? true : fullCtx; 51 | // Indicates that the set of configurations is read-only. Do not 52 | // allow any code to manipulate the set; DFA states will point at 53 | // the sets and they must not change. This does not protect the other 54 | // fields; in particular, conflictingAlts is set after 55 | // we've made this readonly. 56 | this.readOnly = false; 57 | // Track the elements as they are added to the set; supports get(i)/// 58 | this.configs = []; 59 | 60 | // TODO: these fields make me pretty uncomfortable but nice to pack up info 61 | // together, saves recomputation 62 | // TODO: can we track conflicts as they are added to save scanning configs 63 | // later? 64 | this.uniqueAlt = 0; 65 | this.conflictingAlts = null; 66 | 67 | // Used in parser and lexer. In lexer, it indicates we hit a pred 68 | // while computing a closure operation. Don't make a DFA state from this. 69 | this.hasSemanticContext = false; 70 | this.dipsIntoOuterContext = false; 71 | 72 | this.cachedHashCode = -1; 73 | 74 | return this; 75 | } 76 | 77 | // Adding a new config means merging contexts with existing configs for 78 | // {@code (s, i, pi, _)}, where {@code s} is the 79 | // {@link ATNConfig//state}, {@code i} is the {@link ATNConfig//alt}, and 80 | // {@code pi} is the {@link ATNConfig//semanticContext}. We use 81 | // {@code (s,i,pi)} as key. 82 | // 83 | //This method updates {@link //dipsIntoOuterContext} and 84 | // {@link //hasSemanticContext} when necessary.
85 | // / 86 | ATNConfigSet.prototype.add = function(config, mergeCache) { 87 | if (mergeCache === undefined) { 88 | mergeCache = null; 89 | } 90 | if (this.readOnly) { 91 | throw "This set is readonly"; 92 | } 93 | if (config.semanticContext !== SemanticContext.NONE) { 94 | this.hasSemanticContext = true; 95 | } 96 | if (config.reachesIntoOuterContext > 0) { 97 | this.dipsIntoOuterContext = true; 98 | } 99 | var existing = this.configLookup.add(config); 100 | if (existing === config) { 101 | this.cachedHashCode = -1; 102 | this.configs.push(config); // track order here 103 | return true; 104 | } 105 | // a previous (s,i,pi,_), merge with it and save result 106 | var rootIsWildcard = !this.fullCtx; 107 | var merged = merge(existing.context, config.context, rootIsWildcard, mergeCache); 108 | // no need to check for existing.context, config.context in cache 109 | // since only way to create new graphs is "call rule" and here. We 110 | // cache at both places. 111 | existing.reachesIntoOuterContext = Math.max( existing.reachesIntoOuterContext, config.reachesIntoOuterContext); 112 | // make sure to preserve the precedence filter suppression during the merge 113 | if (config.precedenceFilterSuppressed) { 114 | existing.precedenceFilterSuppressed = true; 115 | } 116 | existing.context = merged; // replace context; no need to alt mapping 117 | return true; 118 | }; 119 | 120 | ATNConfigSet.prototype.getStates = function() { 121 | var states = new Set(); 122 | for (var i = 0; i < this.configs.length; i++) { 123 | states.add(this.configs[i].state); 124 | } 125 | return states; 126 | }; 127 | 128 | ATNConfigSet.prototype.getPredicates = function() { 129 | var preds = []; 130 | for (var i = 0; i < this.configs.length; i++) { 131 | var c = this.configs[i].semanticContext; 132 | if (c !== SemanticContext.NONE) { 133 | preds.push(c.semanticContext); 134 | } 135 | } 136 | return preds; 137 | }; 138 | 139 | Object.defineProperty(ATNConfigSet.prototype, "items", { 140 | get : function() { 141 | return this.configs; 142 | } 143 | }); 144 | 145 | ATNConfigSet.prototype.optimizeConfigs = function(interpreter) { 146 | if (this.readOnly) { 147 | throw "This set is readonly"; 148 | } 149 | if (this.configLookup.length === 0) { 150 | return; 151 | } 152 | for (var i = 0; i < this.configs.length; i++) { 153 | var config = this.configs[i]; 154 | config.context = interpreter.getCachedContext(config.context); 155 | } 156 | }; 157 | 158 | ATNConfigSet.prototype.addAll = function(coll) { 159 | for (var i = 0; i < coll.length; i++) { 160 | this.add(coll[i]); 161 | } 162 | return false; 163 | }; 164 | 165 | ATNConfigSet.prototype.equals = function(other) { 166 | return this === other || 167 | (other instanceof ATNConfigSet && 168 | Utils.equalArrays(this.configs, other.configs) && 169 | this.fullCtx === other.fullCtx && 170 | this.uniqueAlt === other.uniqueAlt && 171 | this.conflictingAlts === other.conflictingAlts && 172 | this.hasSemanticContext === other.hasSemanticContext && 173 | this.dipsIntoOuterContext === other.dipsIntoOuterContext); 174 | }; 175 | 176 | ATNConfigSet.prototype.hashCode = function() { 177 | var hash = new Hash(); 178 | this.updateHashCode(hash); 179 | return hash.finish(); 180 | }; 181 | 182 | 183 | ATNConfigSet.prototype.updateHashCode = function(hash) { 184 | if (this.readOnly) { 185 | if (this.cachedHashCode === -1) { 186 | var hash = new Hash(); 187 | hash.update(this.configs); 188 | this.cachedHashCode = hash.finish(); 189 | } 190 | hash.update(this.cachedHashCode); 191 | } else { 192 | hash.update(this.configs); 193 | } 194 | }; 195 | 196 | 197 | Object.defineProperty(ATNConfigSet.prototype, "length", { 198 | get : function() { 199 | return this.configs.length; 200 | } 201 | }); 202 | 203 | ATNConfigSet.prototype.isEmpty = function() { 204 | return this.configs.length === 0; 205 | }; 206 | 207 | ATNConfigSet.prototype.contains = function(item) { 208 | if (this.configLookup === null) { 209 | throw "This method is not implemented for readonly sets."; 210 | } 211 | return this.configLookup.contains(item); 212 | }; 213 | 214 | ATNConfigSet.prototype.containsFast = function(item) { 215 | if (this.configLookup === null) { 216 | throw "This method is not implemented for readonly sets."; 217 | } 218 | return this.configLookup.containsFast(item); 219 | }; 220 | 221 | ATNConfigSet.prototype.clear = function() { 222 | if (this.readOnly) { 223 | throw "This set is readonly"; 224 | } 225 | this.configs = []; 226 | this.cachedHashCode = -1; 227 | this.configLookup = new Set(); 228 | }; 229 | 230 | ATNConfigSet.prototype.setReadonly = function(readOnly) { 231 | this.readOnly = readOnly; 232 | if (readOnly) { 233 | this.configLookup = null; // can't mod, no need for lookup cache 234 | } 235 | }; 236 | 237 | ATNConfigSet.prototype.toString = function() { 238 | return Utils.arrayToString(this.configs) + 239 | (this.hasSemanticContext ? ",hasSemanticContext=" + this.hasSemanticContext : "") + 240 | (this.uniqueAlt !== ATN.INVALID_ALT_NUMBER ? ",uniqueAlt=" + this.uniqueAlt : "") + 241 | (this.conflictingAlts !== null ? ",conflictingAlts=" + this.conflictingAlts : "") + 242 | (this.dipsIntoOuterContext ? ",dipsIntoOuterContext" : ""); 243 | }; 244 | 245 | function OrderedATNConfigSet() { 246 | ATNConfigSet.call(this); 247 | this.configLookup = new Set(); 248 | return this; 249 | } 250 | 251 | OrderedATNConfigSet.prototype = Object.create(ATNConfigSet.prototype); 252 | OrderedATNConfigSet.prototype.constructor = OrderedATNConfigSet; 253 | 254 | exports.ATNConfigSet = ATNConfigSet; 255 | exports.OrderedATNConfigSet = OrderedATNConfigSet; 256 | -------------------------------------------------------------------------------- /src/antlr4/atn/ATNDeserializationOptions.js: -------------------------------------------------------------------------------- 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 | function ATNDeserializationOptions(copyFrom) { 7 | if(copyFrom===undefined) { 8 | copyFrom = null; 9 | } 10 | this.readOnly = false; 11 | this.verifyATN = copyFrom===null ? true : copyFrom.verifyATN; 12 | this.generateRuleBypassTransitions = copyFrom===null ? false : copyFrom.generateRuleBypassTransitions; 13 | 14 | return this; 15 | } 16 | 17 | ATNDeserializationOptions.defaultOptions = new ATNDeserializationOptions(); 18 | ATNDeserializationOptions.defaultOptions.readOnly = true; 19 | 20 | // def __setattr__(self, key, value): 21 | // if key!="readOnly" and self.readOnly: 22 | // raise Exception("The object is read only.") 23 | // super(type(self), self).__setattr__(key,value) 24 | 25 | exports.ATNDeserializationOptions = ATNDeserializationOptions; 26 | -------------------------------------------------------------------------------- /src/antlr4/atn/ATNSimulator.js: -------------------------------------------------------------------------------- 1 | // 2 | /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 | * Use of this file is governed by the BSD 3-clause license that 4 | * can be found in the LICENSE.txt file in the project root. 5 | */ 6 | /// 7 | 8 | var DFAState = require('./../dfa/DFAState').DFAState; 9 | var ATNConfigSet = require('./ATNConfigSet').ATNConfigSet; 10 | var getCachedPredictionContext = require('./../PredictionContext').getCachedPredictionContext; 11 | 12 | function ATNSimulator(atn, sharedContextCache) { 13 | 14 | // The context cache maps all PredictionContext objects that are == 15 | // to a single cached copy. This cache is shared across all contexts 16 | // in all ATNConfigs in all DFA states. We rebuild each ATNConfigSet 17 | // to use only cached nodes/graphs in addDFAState(). We don't want to 18 | // fill this during closure() since there are lots of contexts that 19 | // pop up but are not used ever again. It also greatly slows down closure(). 20 | // 21 | //This cache makes a huge difference in memory and a little bit in speed. 22 | // For the Java grammar on java.*, it dropped the memory requirements 23 | // at the end from 25M to 16M. We don't store any of the full context 24 | // graphs in the DFA because they are limited to local context only, 25 | // but apparently there's a lot of repetition there as well. We optimize 26 | // the config contexts before storing the config set in the DFA states 27 | // by literally rebuilding them with cached subgraphs only.
28 | // 29 | //I tried a cache for use during closure operations, that was 30 | // whacked after each adaptivePredict(). It cost a little bit 31 | // more time I think and doesn't save on the overall footprint 32 | // so it's not worth the complexity.
33 | /// 34 | this.atn = atn; 35 | this.sharedContextCache = sharedContextCache; 36 | return this; 37 | } 38 | 39 | // Must distinguish between missing edge and edge we know leads nowhere/// 40 | ATNSimulator.ERROR = new DFAState(0x7FFFFFFF, new ATNConfigSet()); 41 | 42 | 43 | ATNSimulator.prototype.getCachedContext = function(context) { 44 | if (this.sharedContextCache ===null) { 45 | return context; 46 | } 47 | var visited = {}; 48 | return getCachedPredictionContext(context, this.sharedContextCache, visited); 49 | }; 50 | 51 | exports.ATNSimulator = ATNSimulator; 52 | -------------------------------------------------------------------------------- /src/antlr4/atn/ATNState.js: -------------------------------------------------------------------------------- 1 | // 2 | /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 | * Use of this file is governed by the BSD 3-clause license that 4 | * can be found in the LICENSE.txt file in the project root. 5 | */ 6 | // 7 | 8 | // The following images show the relation of states and 9 | // {@link ATNState//transitions} for various grammar constructs. 10 | // 11 | //The executor tracks position information for position-dependent lexer actions 12 | // efficiently, ensuring that actions appearing only at the end of the rule do 13 | // not cause bloating of the {@link DFA} created for the lexer.
14 | 15 | var hashStuff = require("../Utils").hashStuff; 16 | var LexerIndexedCustomAction = require('./LexerAction').LexerIndexedCustomAction; 17 | 18 | function LexerActionExecutor(lexerActions) { 19 | this.lexerActions = lexerActions === null ? [] : lexerActions; 20 | // Caches the result of {@link //hashCode} since the hash code is an element 21 | // of the performance-critical {@link LexerATNConfig//hashCode} operation. 22 | this.cachedHashCode = hashStuff(lexerActions); // "".join([str(la) for la in 23 | // lexerActions])) 24 | return this; 25 | } 26 | 27 | // Creates a {@link LexerActionExecutor} which executes the actions for 28 | // the input {@code lexerActionExecutor} followed by a specified 29 | // {@code lexerAction}. 30 | // 31 | // @param lexerActionExecutor The executor for actions already traversed by 32 | // the lexer while matching a token within a particular 33 | // {@link LexerATNConfig}. If this is {@code null}, the method behaves as 34 | // though it were an empty executor. 35 | // @param lexerAction The lexer action to execute after the actions 36 | // specified in {@code lexerActionExecutor}. 37 | // 38 | // @return A {@link LexerActionExecutor} for executing the combine actions 39 | // of {@code lexerActionExecutor} and {@code lexerAction}. 40 | LexerActionExecutor.append = function(lexerActionExecutor, lexerAction) { 41 | if (lexerActionExecutor === null) { 42 | return new LexerActionExecutor([ lexerAction ]); 43 | } 44 | var lexerActions = lexerActionExecutor.lexerActions.concat([ lexerAction ]); 45 | return new LexerActionExecutor(lexerActions); 46 | }; 47 | 48 | // Creates a {@link LexerActionExecutor} which encodes the current offset 49 | // for position-dependent lexer actions. 50 | // 51 | //Normally, when the executor encounters lexer actions where 52 | // {@link LexerAction//isPositionDependent} returns {@code true}, it calls 53 | // {@link IntStream//seek} on the input {@link CharStream} to set the input 54 | // position to the end of the current token. This behavior provides 55 | // for efficient DFA representation of lexer actions which appear at the end 56 | // of a lexer rule, even when the lexer rule matches a variable number of 57 | // characters.
58 | // 59 | //Prior to traversing a match transition in the ATN, the current offset 60 | // from the token start index is assigned to all position-dependent lexer 61 | // actions which have not already been assigned a fixed offset. By storing 62 | // the offsets relative to the token start index, the DFA representation of 63 | // lexer actions which appear in the middle of tokens remains efficient due 64 | // to sharing among tokens of the same length, regardless of their absolute 65 | // position in the input stream.
66 | // 67 | //If the current executor already has offsets assigned to all 68 | // position-dependent lexer actions, the method returns {@code this}.
69 | // 70 | // @param offset The current offset to assign to all position-dependent 71 | // lexer actions which do not already have offsets assigned. 72 | // 73 | // @return A {@link LexerActionExecutor} which stores input stream offsets 74 | // for all position-dependent lexer actions. 75 | // / 76 | LexerActionExecutor.prototype.fixOffsetBeforeMatch = function(offset) { 77 | var updatedLexerActions = null; 78 | for (var i = 0; i < this.lexerActions.length; i++) { 79 | if (this.lexerActions[i].isPositionDependent && 80 | !(this.lexerActions[i] instanceof LexerIndexedCustomAction)) { 81 | if (updatedLexerActions === null) { 82 | updatedLexerActions = this.lexerActions.concat([]); 83 | } 84 | updatedLexerActions[i] = new LexerIndexedCustomAction(offset, 85 | this.lexerActions[i]); 86 | } 87 | } 88 | if (updatedLexerActions === null) { 89 | return this; 90 | } else { 91 | return new LexerActionExecutor(updatedLexerActions); 92 | } 93 | }; 94 | 95 | // Execute the actions encapsulated by this executor within the context of a 96 | // particular {@link Lexer}. 97 | // 98 | //This method calls {@link IntStream//seek} to set the position of the 99 | // {@code input} {@link CharStream} prior to calling 100 | // {@link LexerAction//execute} on a position-dependent action. Before the 101 | // method returns, the input position will be restored to the same position 102 | // it was in when the method was invoked.
103 | // 104 | // @param lexer The lexer instance. 105 | // @param input The input stream which is the source for the current token. 106 | // When this method is called, the current {@link IntStream//index} for 107 | // {@code input} should be the start of the following token, i.e. 1 108 | // character past the end of the current token. 109 | // @param startIndex The token start index. This value may be passed to 110 | // {@link IntStream//seek} to set the {@code input} position to the beginning 111 | // of the token. 112 | // / 113 | LexerActionExecutor.prototype.execute = function(lexer, input, startIndex) { 114 | var requiresSeek = false; 115 | var stopIndex = input.index; 116 | try { 117 | for (var i = 0; i < this.lexerActions.length; i++) { 118 | var lexerAction = this.lexerActions[i]; 119 | if (lexerAction instanceof LexerIndexedCustomAction) { 120 | var offset = lexerAction.offset; 121 | input.seek(startIndex + offset); 122 | lexerAction = lexerAction.action; 123 | requiresSeek = (startIndex + offset) !== stopIndex; 124 | } else if (lexerAction.isPositionDependent) { 125 | input.seek(stopIndex); 126 | requiresSeek = false; 127 | } 128 | lexerAction.execute(lexer); 129 | } 130 | } finally { 131 | if (requiresSeek) { 132 | input.seek(stopIndex); 133 | } 134 | } 135 | }; 136 | 137 | LexerActionExecutor.prototype.hashCode = function() { 138 | return this.cachedHashCode; 139 | }; 140 | 141 | LexerActionExecutor.prototype.updateHashCode = function(hash) { 142 | hash.update(this.cachedHashCode); 143 | }; 144 | 145 | 146 | LexerActionExecutor.prototype.equals = function(other) { 147 | if (this === other) { 148 | return true; 149 | } else if (!(other instanceof LexerActionExecutor)) { 150 | return false; 151 | } else if (this.cachedHashCode != other.cachedHashCode) { 152 | return false; 153 | } else if (this.lexerActions.length != other.lexerActions.length) { 154 | return false; 155 | } else { 156 | var numActions = this.lexerActions.length 157 | for (var idx = 0; idx < numActions; ++idx) { 158 | if (!this.lexerActions[idx].equals(other.lexerActions[idx])) { 159 | return false; 160 | } 161 | } 162 | return true; 163 | } 164 | }; 165 | 166 | exports.LexerActionExecutor = LexerActionExecutor; 167 | -------------------------------------------------------------------------------- /src/antlr4/atn/SemanticContext.js: -------------------------------------------------------------------------------- 1 | // 2 | /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 | * Use of this file is governed by the BSD 3-clause license that 4 | * can be found in the LICENSE.txt file in the project root. 5 | */ 6 | // 7 | 8 | // A tree structure used to record the semantic context in which 9 | // an ATN configuration is valid. It's either a single predicate, 10 | // a conjunction {@code p1&&p2}, or a sum of products {@code p1||p2}. 11 | // 12 | //I have scoped the {@link AND}, {@link OR}, and {@link Predicate} subclasses of 13 | // {@link SemanticContext} within the scope of this outer class.
14 | // 15 | 16 | var Set = require('./../Utils').Set; 17 | var Hash = require('./../Utils').Hash; 18 | 19 | function SemanticContext() { 20 | return this; 21 | } 22 | 23 | SemanticContext.prototype.hashCode = function() { 24 | var hash = new Hash(); 25 | this.updateHashCode(hash); 26 | return hash.finish(); 27 | }; 28 | 29 | // For context independent predicates, we evaluate them without a local 30 | // context (i.e., null context). That way, we can evaluate them without 31 | // having to create proper rule-specific context during prediction (as 32 | // opposed to the parser, which creates them naturally). In a practical 33 | // sense, this avoids a cast exception from RuleContext to myruleContext. 34 | // 35 | //For context dependent predicates, we must pass in a local context so that 36 | // references such as $arg evaluate properly as _localctx.arg. We only 37 | // capture context dependent predicates in the context in which we begin 38 | // prediction, so we passed in the outer context here in case of context 39 | // dependent predicate evaluation.
40 | // 41 | SemanticContext.prototype.evaluate = function(parser, outerContext) { 42 | }; 43 | 44 | // 45 | // Evaluate the precedence predicates for the context and reduce the result. 46 | // 47 | // @param parser The parser instance. 48 | // @param outerContext The current parser context object. 49 | // @return The simplified semantic context after precedence predicates are 50 | // evaluated, which will be one of the following values. 51 | //353 | // The evaluation of predicates by this context is short-circuiting, but 354 | // unordered.
355 | // 356 | OR.prototype.evaluate = function(parser, outerContext) { 357 | for (var i = 0; i < this.opnds.length; i++) { 358 | if (this.opnds[i].evaluate(parser, outerContext)) { 359 | return true; 360 | } 361 | } 362 | return false; 363 | }; 364 | 365 | OR.prototype.evalPrecedence = function(parser, outerContext) { 366 | var differs = false; 367 | var operands = []; 368 | for (var i = 0; i < this.opnds.length; i++) { 369 | var context = this.opnds[i]; 370 | var evaluated = context.evalPrecedence(parser, outerContext); 371 | differs |= (evaluated !== context); 372 | if (evaluated === SemanticContext.NONE) { 373 | // The OR context is true if any element is true 374 | return SemanticContext.NONE; 375 | } else if (evaluated !== null) { 376 | // Reduce the result by skipping false elements 377 | operands.push(evaluated); 378 | } 379 | } 380 | if (!differs) { 381 | return this; 382 | } 383 | if (operands.length === 0) { 384 | // all elements were false, so the OR context is false 385 | return null; 386 | } 387 | var result = null; 388 | operands.map(function(o) { 389 | return result === null ? o : SemanticContext.orContext(result, o); 390 | }); 391 | return result; 392 | }; 393 | 394 | OR.prototype.toString = function() { 395 | var s = ""; 396 | this.opnds.map(function(o) { 397 | s += "|| " + o.toString(); 398 | }); 399 | return s.length > 3 ? s.slice(3) : s; 400 | }; 401 | 402 | exports.SemanticContext = SemanticContext; 403 | exports.PrecedencePredicate = PrecedencePredicate; 404 | exports.Predicate = Predicate; 405 | -------------------------------------------------------------------------------- /src/antlr4/atn/Transition.js: -------------------------------------------------------------------------------- 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 | 7 | // An ATN transition between any two ATN states. Subclasses define 8 | // atom, set, epsilon, action, predicate, rule transitions. 9 | // 10 | //This is a one way link. It emanates from a state (usually via a list of 11 | // transitions) and has a target state.
12 | // 13 | //Since we never have to change the ATN transitions once we construct it, 14 | // we can fix these transitions as specific classes. The DFA transitions 15 | // on the other hand need to update the labels as it adds transitions to 16 | // the states. We'll use the term Edge for the DFA to distinguish them from 17 | // ATN transitions.
18 | 19 | var Token = require('./../Token').Token; 20 | var Interval = require('./../IntervalSet').Interval; 21 | var IntervalSet = require('./../IntervalSet').IntervalSet; 22 | var Predicate = require('./SemanticContext').Predicate; 23 | var PrecedencePredicate = require('./SemanticContext').PrecedencePredicate; 24 | 25 | function Transition (target) { 26 | // The target of this transition. 27 | if (target===undefined || target===null) { 28 | throw "target cannot be null."; 29 | } 30 | this.target = target; 31 | // Are we epsilon, action, sempred? 32 | this.isEpsilon = false; 33 | this.label = null; 34 | return this; 35 | } 36 | // constants for serialization 37 | Transition.EPSILON = 1; 38 | Transition.RANGE = 2; 39 | Transition.RULE = 3; 40 | Transition.PREDICATE = 4; // e.g., {isType(input.LT(1))}? 41 | Transition.ATOM = 5; 42 | Transition.ACTION = 6; 43 | Transition.SET = 7; // ~(A|B) or ~atom, wildcard, which convert to next 2 44 | Transition.NOT_SET = 8; 45 | Transition.WILDCARD = 9; 46 | Transition.PRECEDENCE = 10; 47 | 48 | Transition.serializationNames = [ 49 | "INVALID", 50 | "EPSILON", 51 | "RANGE", 52 | "RULE", 53 | "PREDICATE", 54 | "ATOM", 55 | "ACTION", 56 | "SET", 57 | "NOT_SET", 58 | "WILDCARD", 59 | "PRECEDENCE" 60 | ]; 61 | 62 | Transition.serializationTypes = { 63 | EpsilonTransition: Transition.EPSILON, 64 | RangeTransition: Transition.RANGE, 65 | RuleTransition: Transition.RULE, 66 | PredicateTransition: Transition.PREDICATE, 67 | AtomTransition: Transition.ATOM, 68 | ActionTransition: Transition.ACTION, 69 | SetTransition: Transition.SET, 70 | NotSetTransition: Transition.NOT_SET, 71 | WildcardTransition: Transition.WILDCARD, 72 | PrecedencePredicateTransition: Transition.PRECEDENCE 73 | }; 74 | 75 | 76 | // TODO: make all transitions sets? no, should remove set edges 77 | function AtomTransition(target, label) { 78 | Transition.call(this, target); 79 | this.label_ = label; // The token type or character value; or, signifies special label. 80 | this.label = this.makeLabel(); 81 | this.serializationType = Transition.ATOM; 82 | return this; 83 | } 84 | 85 | AtomTransition.prototype = Object.create(Transition.prototype); 86 | AtomTransition.prototype.constructor = AtomTransition; 87 | 88 | AtomTransition.prototype.makeLabel = function() { 89 | var s = new IntervalSet(); 90 | s.addOne(this.label_); 91 | return s; 92 | }; 93 | 94 | AtomTransition.prototype.matches = function( symbol, minVocabSymbol, maxVocabSymbol) { 95 | return this.label_ === symbol; 96 | }; 97 | 98 | AtomTransition.prototype.toString = function() { 99 | return this.label_; 100 | }; 101 | 102 | function RuleTransition(ruleStart, ruleIndex, precedence, followState) { 103 | Transition.call(this, ruleStart); 104 | this.ruleIndex = ruleIndex; // ptr to the rule definition object for this rule ref 105 | this.precedence = precedence; 106 | this.followState = followState; // what node to begin computations following ref to rule 107 | this.serializationType = Transition.RULE; 108 | this.isEpsilon = true; 109 | return this; 110 | } 111 | 112 | RuleTransition.prototype = Object.create(Transition.prototype); 113 | RuleTransition.prototype.constructor = RuleTransition; 114 | 115 | RuleTransition.prototype.matches = function(symbol, minVocabSymbol, maxVocabSymbol) { 116 | return false; 117 | }; 118 | 119 | 120 | function EpsilonTransition(target, outermostPrecedenceReturn) { 121 | Transition.call(this, target); 122 | this.serializationType = Transition.EPSILON; 123 | this.isEpsilon = true; 124 | this.outermostPrecedenceReturn = outermostPrecedenceReturn; 125 | return this; 126 | } 127 | 128 | EpsilonTransition.prototype = Object.create(Transition.prototype); 129 | EpsilonTransition.prototype.constructor = EpsilonTransition; 130 | 131 | EpsilonTransition.prototype.matches = function( symbol, minVocabSymbol, maxVocabSymbol) { 132 | return false; 133 | }; 134 | 135 | EpsilonTransition.prototype.toString = function() { 136 | return "epsilon"; 137 | }; 138 | 139 | function RangeTransition(target, start, stop) { 140 | Transition.call(this, target); 141 | this.serializationType = Transition.RANGE; 142 | this.start = start; 143 | this.stop = stop; 144 | this.label = this.makeLabel(); 145 | return this; 146 | } 147 | 148 | RangeTransition.prototype = Object.create(Transition.prototype); 149 | RangeTransition.prototype.constructor = RangeTransition; 150 | 151 | RangeTransition.prototype.makeLabel = function() { 152 | var s = new IntervalSet(); 153 | s.addRange(this.start, this.stop); 154 | return s; 155 | }; 156 | 157 | RangeTransition.prototype.matches = function(symbol, minVocabSymbol, maxVocabSymbol) { 158 | return symbol >= this.start && symbol <= this.stop; 159 | }; 160 | 161 | RangeTransition.prototype.toString = function() { 162 | return "'" + String.fromCharCode(this.start) + "'..'" + String.fromCharCode(this.stop) + "'"; 163 | }; 164 | 165 | function AbstractPredicateTransition(target) { 166 | Transition.call(this, target); 167 | return this; 168 | } 169 | 170 | AbstractPredicateTransition.prototype = Object.create(Transition.prototype); 171 | AbstractPredicateTransition.prototype.constructor = AbstractPredicateTransition; 172 | 173 | function PredicateTransition(target, ruleIndex, predIndex, isCtxDependent) { 174 | AbstractPredicateTransition.call(this, target); 175 | this.serializationType = Transition.PREDICATE; 176 | this.ruleIndex = ruleIndex; 177 | this.predIndex = predIndex; 178 | this.isCtxDependent = isCtxDependent; // e.g., $i ref in pred 179 | this.isEpsilon = true; 180 | return this; 181 | } 182 | 183 | PredicateTransition.prototype = Object.create(AbstractPredicateTransition.prototype); 184 | PredicateTransition.prototype.constructor = PredicateTransition; 185 | 186 | PredicateTransition.prototype.matches = function(symbol, minVocabSymbol, maxVocabSymbol) { 187 | return false; 188 | }; 189 | 190 | PredicateTransition.prototype.getPredicate = function() { 191 | return new Predicate(this.ruleIndex, this.predIndex, this.isCtxDependent); 192 | }; 193 | 194 | PredicateTransition.prototype.toString = function() { 195 | return "pred_" + this.ruleIndex + ":" + this.predIndex; 196 | }; 197 | 198 | function ActionTransition(target, ruleIndex, actionIndex, isCtxDependent) { 199 | Transition.call(this, target); 200 | this.serializationType = Transition.ACTION; 201 | this.ruleIndex = ruleIndex; 202 | this.actionIndex = actionIndex===undefined ? -1 : actionIndex; 203 | this.isCtxDependent = isCtxDependent===undefined ? false : isCtxDependent; // e.g., $i ref in pred 204 | this.isEpsilon = true; 205 | return this; 206 | } 207 | 208 | ActionTransition.prototype = Object.create(Transition.prototype); 209 | ActionTransition.prototype.constructor = ActionTransition; 210 | 211 | 212 | ActionTransition.prototype.matches = function(symbol, minVocabSymbol, maxVocabSymbol) { 213 | return false; 214 | }; 215 | 216 | ActionTransition.prototype.toString = function() { 217 | return "action_" + this.ruleIndex + ":" + this.actionIndex; 218 | }; 219 | 220 | 221 | // A transition containing a set of values. 222 | function SetTransition(target, set) { 223 | Transition.call(this, target); 224 | this.serializationType = Transition.SET; 225 | if (set !==undefined && set !==null) { 226 | this.label = set; 227 | } else { 228 | this.label = new IntervalSet(); 229 | this.label.addOne(Token.INVALID_TYPE); 230 | } 231 | return this; 232 | } 233 | 234 | SetTransition.prototype = Object.create(Transition.prototype); 235 | SetTransition.prototype.constructor = SetTransition; 236 | 237 | SetTransition.prototype.matches = function(symbol, minVocabSymbol, maxVocabSymbol) { 238 | return this.label.contains(symbol); 239 | }; 240 | 241 | 242 | SetTransition.prototype.toString = function() { 243 | return this.label.toString(); 244 | }; 245 | 246 | function NotSetTransition(target, set) { 247 | SetTransition.call(this, target, set); 248 | this.serializationType = Transition.NOT_SET; 249 | return this; 250 | } 251 | 252 | NotSetTransition.prototype = Object.create(SetTransition.prototype); 253 | NotSetTransition.prototype.constructor = NotSetTransition; 254 | 255 | NotSetTransition.prototype.matches = function(symbol, minVocabSymbol, maxVocabSymbol) { 256 | return symbol >= minVocabSymbol && symbol <= maxVocabSymbol && 257 | !SetTransition.prototype.matches.call(this, symbol, minVocabSymbol, maxVocabSymbol); 258 | }; 259 | 260 | NotSetTransition.prototype.toString = function() { 261 | return '~' + SetTransition.prototype.toString.call(this); 262 | }; 263 | 264 | function WildcardTransition(target) { 265 | Transition.call(this, target); 266 | this.serializationType = Transition.WILDCARD; 267 | return this; 268 | } 269 | 270 | WildcardTransition.prototype = Object.create(Transition.prototype); 271 | WildcardTransition.prototype.constructor = WildcardTransition; 272 | 273 | 274 | WildcardTransition.prototype.matches = function(symbol, minVocabSymbol, maxVocabSymbol) { 275 | return symbol >= minVocabSymbol && symbol <= maxVocabSymbol; 276 | }; 277 | 278 | WildcardTransition.prototype.toString = function() { 279 | return "."; 280 | }; 281 | 282 | function PrecedencePredicateTransition(target, precedence) { 283 | AbstractPredicateTransition.call(this, target); 284 | this.serializationType = Transition.PRECEDENCE; 285 | this.precedence = precedence; 286 | this.isEpsilon = true; 287 | return this; 288 | } 289 | 290 | PrecedencePredicateTransition.prototype = Object.create(AbstractPredicateTransition.prototype); 291 | PrecedencePredicateTransition.prototype.constructor = PrecedencePredicateTransition; 292 | 293 | PrecedencePredicateTransition.prototype.matches = function(symbol, minVocabSymbol, maxVocabSymbol) { 294 | return false; 295 | }; 296 | 297 | PrecedencePredicateTransition.prototype.getPredicate = function() { 298 | return new PrecedencePredicate(this.precedence); 299 | }; 300 | 301 | PrecedencePredicateTransition.prototype.toString = function() { 302 | return this.precedence + " >= _p"; 303 | }; 304 | 305 | exports.Transition = Transition; 306 | exports.AtomTransition = AtomTransition; 307 | exports.SetTransition = SetTransition; 308 | exports.NotSetTransition = NotSetTransition; 309 | exports.RuleTransition = RuleTransition; 310 | exports.ActionTransition = ActionTransition; 311 | exports.EpsilonTransition = EpsilonTransition; 312 | exports.RangeTransition = RangeTransition; 313 | exports.WildcardTransition = WildcardTransition; 314 | exports.PredicateTransition = PredicateTransition; 315 | exports.PrecedencePredicateTransition = PrecedencePredicateTransition; 316 | exports.AbstractPredicateTransition = AbstractPredicateTransition; -------------------------------------------------------------------------------- /src/antlr4/atn/index.js: -------------------------------------------------------------------------------- 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 | exports.ATN = require('./ATN').ATN; 7 | exports.ATNDeserializer = require('./ATNDeserializer').ATNDeserializer; 8 | exports.LexerATNSimulator = require('./LexerATNSimulator').LexerATNSimulator; 9 | exports.ParserATNSimulator = require('./ParserATNSimulator').ParserATNSimulator; 10 | exports.PredictionMode = require('./PredictionMode').PredictionMode; 11 | -------------------------------------------------------------------------------- /src/antlr4/dfa/DFA.js: -------------------------------------------------------------------------------- 1 | // 2 | /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 | * Use of this file is governed by the BSD 3-clause license that 4 | * can be found in the LICENSE.txt file in the project root. 5 | */ 6 | 7 | var Set = require("../Utils").Set; 8 | var DFAState = require('./DFAState').DFAState; 9 | var StarLoopEntryState = require('../atn/ATNState').StarLoopEntryState; 10 | var ATNConfigSet = require('./../atn/ATNConfigSet').ATNConfigSet; 11 | var DFASerializer = require('./DFASerializer').DFASerializer; 12 | var LexerDFASerializer = require('./DFASerializer').LexerDFASerializer; 13 | 14 | 15 | 16 | function DFA(atnStartState, decision) { 17 | if (decision === undefined) { 18 | decision = 0; 19 | } 20 | // From which ATN state did we create this DFA? 21 | this.atnStartState = atnStartState; 22 | this.decision = decision; 23 | // A set of all DFA states. Use {@link Map} so we can get old state back 24 | // ({@link Set} only allows you to see if it's there). 25 | this._states = new Set(); 26 | this.s0 = null; 27 | // {@code true} if this DFA is for a precedence decision; otherwise, 28 | // {@code false}. This is the backing field for {@link //isPrecedenceDfa}, 29 | // {@link //setPrecedenceDfa}. 30 | this.precedenceDfa = false; 31 | if (atnStartState instanceof StarLoopEntryState) 32 | { 33 | if (atnStartState.isPrecedenceDecision) { 34 | this.precedenceDfa = true; 35 | var precedenceState = new DFAState(null, new ATNConfigSet()); 36 | precedenceState.edges = []; 37 | precedenceState.isAcceptState = false; 38 | precedenceState.requiresFullContext = false; 39 | this.s0 = precedenceState; 40 | } 41 | } 42 | return this; 43 | } 44 | 45 | // Get the start state for a specific precedence value. 46 | // 47 | // @param precedence The current precedence. 48 | // @return The start state corresponding to the specified precedence, or 49 | // {@code null} if no start state exists for the specified precedence. 50 | // 51 | // @throws IllegalStateException if this is not a precedence DFA. 52 | // @see //isPrecedenceDfa() 53 | 54 | DFA.prototype.getPrecedenceStartState = function(precedence) { 55 | if (!(this.precedenceDfa)) { 56 | throw ("Only precedence DFAs may contain a precedence start state."); 57 | } 58 | // s0.edges is never null for a precedence DFA 59 | if (precedence < 0 || precedence >= this.s0.edges.length) { 60 | return null; 61 | } 62 | return this.s0.edges[precedence] || null; 63 | }; 64 | 65 | // Set the start state for a specific precedence value. 66 | // 67 | // @param precedence The current precedence. 68 | // @param startState The start state corresponding to the specified 69 | // precedence. 70 | // 71 | // @throws IllegalStateException if this is not a precedence DFA. 72 | // @see //isPrecedenceDfa() 73 | // 74 | DFA.prototype.setPrecedenceStartState = function(precedence, startState) { 75 | if (!(this.precedenceDfa)) { 76 | throw ("Only precedence DFAs may contain a precedence start state."); 77 | } 78 | if (precedence < 0) { 79 | return; 80 | } 81 | 82 | // synchronization on s0 here is ok. when the DFA is turned into a 83 | // precedence DFA, s0 will be initialized once and not updated again 84 | // s0.edges is never null for a precedence DFA 85 | this.s0.edges[precedence] = startState; 86 | }; 87 | 88 | // 89 | // Sets whether this is a precedence DFA. If the specified value differs 90 | // from the current DFA configuration, the following actions are taken; 91 | // otherwise no changes are made to the current DFA. 92 | // 93 | //I use a set of ATNConfig objects not simple states. An ATNConfig 42 | // is both a state (ala normal conversion) and a RuleContext describing 43 | // the chain of rules (if any) followed to arrive at that state.
44 | // 45 | //A DFA state may have multiple references to a particular state, 46 | // but with different ATN contexts (with same or different alts) 47 | // meaning that state was reached via a different set of rule invocations.
48 | // / 49 | 50 | function DFAState(stateNumber, configs) { 51 | if (stateNumber === null) { 52 | stateNumber = -1; 53 | } 54 | if (configs === null) { 55 | configs = new ATNConfigSet(); 56 | } 57 | this.stateNumber = stateNumber; 58 | this.configs = configs; 59 | // {@code edges[symbol]} points to target of symbol. Shift up by 1 so (-1) 60 | // {@link Token//EOF} maps to {@code edges[0]}. 61 | this.edges = null; 62 | this.isAcceptState = false; 63 | // if accept state, what ttype do we match or alt do we predict? 64 | // This is set to {@link ATN//INVALID_ALT_NUMBER} when {@link 65 | // //predicates}{@code !=null} or 66 | // {@link //requiresFullContext}. 67 | this.prediction = 0; 68 | this.lexerActionExecutor = null; 69 | // Indicates that this state was created during SLL prediction that 70 | // discovered a conflict between the configurations in the state. Future 71 | // {@link ParserATNSimulator//execATN} invocations immediately jumped doing 72 | // full context prediction if this field is true. 73 | this.requiresFullContext = false; 74 | // During SLL parsing, this is a list of predicates associated with the 75 | // ATN configurations of the DFA state. When we have predicates, 76 | // {@link //requiresFullContext} is {@code false} since full context 77 | // prediction evaluates predicates 78 | // on-the-fly. If this is not null, then {@link //prediction} is 79 | // {@link ATN//INVALID_ALT_NUMBER}. 80 | // 81 | //We only use these for non-{@link //requiresFullContext} but 82 | // conflicting states. That 83 | // means we know from the context (it's $ or we don't dip into outer 84 | // context) that it's an ambiguity not a conflict.
85 | // 86 | //This list is computed by {@link 87 | // ParserATNSimulator//predicateDFAState}.
88 | this.predicates = null; 89 | return this; 90 | } 91 | 92 | // Get the set of all alts mentioned by all ATN configurations in this 93 | // DFA state. 94 | DFAState.prototype.getAltSet = function() { 95 | var alts = new Set(); 96 | if (this.configs !== null) { 97 | for (var i = 0; i < this.configs.length; i++) { 98 | var c = this.configs[i]; 99 | alts.add(c.alt); 100 | } 101 | } 102 | if (alts.length === 0) { 103 | return null; 104 | } else { 105 | return alts; 106 | } 107 | }; 108 | 109 | // Two {@link DFAState} instances are equal if their ATN configuration sets 110 | // are the same. This method is used to see if a state already exists. 111 | // 112 | //Because the number of alternatives and number of ATN configurations are 113 | // finite, there is a finite number of DFA states that can be processed. 114 | // This is necessary to show that the algorithm terminates.
115 | // 116 | //Cannot test the DFA state numbers here because in 117 | // {@link ParserATNSimulator//addDFAState} we need to know if any other state 118 | // exists that has this exact set of ATN configurations. The 119 | // {@link //stateNumber} is irrelevant.
120 | DFAState.prototype.equals = function(other) { 121 | // compare set of ATN configurations in this set with other 122 | return this === other || 123 | (other instanceof DFAState && 124 | this.configs.equals(other.configs)); 125 | }; 126 | 127 | DFAState.prototype.toString = function() { 128 | var s = "" + this.stateNumber + ":" + this.configs; 129 | if(this.isAcceptState) { 130 | s = s + "=>"; 131 | if (this.predicates !== null) 132 | s = s + this.predicates; 133 | else 134 | s = s + this.prediction; 135 | } 136 | return s; 137 | }; 138 | 139 | DFAState.prototype.hashCode = function() { 140 | var hash = new Hash(); 141 | hash.update(this.configs); 142 | if(this.isAcceptState) { 143 | if (this.predicates !== null) 144 | hash.update(this.predicates); 145 | else 146 | hash.update(this.prediction); 147 | } 148 | return hash.finish(); 149 | }; 150 | 151 | exports.DFAState = DFAState; 152 | exports.PredPrediction = PredPrediction; 153 | -------------------------------------------------------------------------------- /src/antlr4/dfa/index.js: -------------------------------------------------------------------------------- 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 | exports.DFA = require('./DFA').DFA; 7 | exports.DFASerializer = require('./DFASerializer').DFASerializer; 8 | exports.LexerDFASerializer = require('./DFASerializer').LexerDFASerializer; 9 | exports.PredPrediction = require('./DFAState').PredPrediction; 10 | -------------------------------------------------------------------------------- /src/antlr4/error/DiagnosticErrorListener.js: -------------------------------------------------------------------------------- 1 | // 2 | /* Copyright (c) 2012-2017 The ANTLR Project. All rights reserved. 3 | * Use of this file is governed by the BSD 3-clause license that 4 | * can be found in the LICENSE.txt file in the project root. 5 | */ 6 | // 7 | 8 | // 9 | // This implementation of {@link ANTLRErrorListener} can be used to identify 10 | // certain potential correctness and performance problems in grammars. "Reports" 11 | // are made by calling {@link Parser//notifyErrorListeners} with the appropriate 12 | // message. 13 | // 14 | //44 | // This implementation prints messages to {@link System//err} containing the 45 | // values of {@code line}, {@code charPositionInLine}, and {@code msg} using 46 | // the following format.
47 | // 48 | //49 | // line line:charPositionInLine msg 50 | //51 | // 52 | ConsoleErrorListener.prototype.syntaxError = function(recognizer, offendingSymbol, line, column, msg, e) { 53 | console.error("line " + line + ":" + column + " " + msg); 54 | }; 55 | 56 | function ProxyErrorListener(delegates) { 57 | ErrorListener.call(this); 58 | if (delegates===null) { 59 | throw "delegates"; 60 | } 61 | this.delegates = delegates; 62 | return this; 63 | } 64 | 65 | ProxyErrorListener.prototype = Object.create(ErrorListener.prototype); 66 | ProxyErrorListener.prototype.constructor = ProxyErrorListener; 67 | 68 | ProxyErrorListener.prototype.syntaxError = function(recognizer, offendingSymbol, line, column, msg, e) { 69 | this.delegates.map(function(d) { d.syntaxError(recognizer, offendingSymbol, line, column, msg, e); }); 70 | }; 71 | 72 | ProxyErrorListener.prototype.reportAmbiguity = function(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs) { 73 | this.delegates.map(function(d) { d.reportAmbiguity(recognizer, dfa, startIndex, stopIndex, exact, ambigAlts, configs); }); 74 | }; 75 | 76 | ProxyErrorListener.prototype.reportAttemptingFullContext = function(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs) { 77 | this.delegates.map(function(d) { d.reportAttemptingFullContext(recognizer, dfa, startIndex, stopIndex, conflictingAlts, configs); }); 78 | }; 79 | 80 | ProxyErrorListener.prototype.reportContextSensitivity = function(recognizer, dfa, startIndex, stopIndex, prediction, configs) { 81 | this.delegates.map(function(d) { d.reportContextSensitivity(recognizer, dfa, startIndex, stopIndex, prediction, configs); }); 82 | }; 83 | 84 | exports.ErrorListener = ErrorListener; 85 | exports.ConsoleErrorListener = ConsoleErrorListener; 86 | exports.ProxyErrorListener = ProxyErrorListener; 87 | 88 | -------------------------------------------------------------------------------- /src/antlr4/error/Errors.js: -------------------------------------------------------------------------------- 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 | // The root of the ANTLR exception hierarchy. In general, ANTLR tracks just 7 | // 3 kinds of errors: prediction errors, failed predicate errors, and 8 | // mismatched input errors. In each case, the parser knows where it is 9 | // in the input, where it is in the ATN, the rule invocation stack, 10 | // and what kind of problem occurred. 11 | 12 | var PredicateTransition = require('./../atn/Transition').PredicateTransition; 13 | 14 | function RecognitionException(params) { 15 | Error.call(this); 16 | if (!!Error.captureStackTrace) { 17 | Error.captureStackTrace(this, RecognitionException); 18 | } else { 19 | var stack = new Error().stack; 20 | } 21 | this.message = params.message; 22 | this.recognizer = params.recognizer; 23 | this.input = params.input; 24 | this.ctx = params.ctx; 25 | // The current {@link Token} when an error occurred. Since not all streams 26 | // support accessing symbols by index, we have to track the {@link Token} 27 | // instance itself. 28 | this.offendingToken = null; 29 | // Get the ATN state number the parser was in at the time the error 30 | // occurred. For {@link NoViableAltException} and 31 | // {@link LexerNoViableAltException} exceptions, this is the 32 | // {@link DecisionState} number. For others, it is the state whose outgoing 33 | // edge we couldn't match. 34 | this.offendingState = -1; 35 | if (this.recognizer!==null) { 36 | this.offendingState = this.recognizer.state; 37 | } 38 | return this; 39 | } 40 | 41 | RecognitionException.prototype = Object.create(Error.prototype); 42 | RecognitionException.prototype.constructor = RecognitionException; 43 | 44 | //
If the state number is not known, this method returns -1.
45 | 46 | // 47 | // Gets the set of input symbols which could potentially follow the 48 | // previously matched symbol at the time this exception was thrown. 49 | // 50 | //If the set of expected tokens is not known and could not be computed, 51 | // this method returns {@code null}.
52 | // 53 | // @return The set of token types that could potentially follow the current 54 | // state in the ATN, or {@code null} if the information is not available. 55 | // / 56 | RecognitionException.prototype.getExpectedTokens = function() { 57 | if (this.recognizer!==null) { 58 | return this.recognizer.atn.getExpectedTokens(this.offendingState, this.ctx); 59 | } else { 60 | return null; 61 | } 62 | }; 63 | 64 | RecognitionException.prototype.toString = function() { 65 | return this.message; 66 | }; 67 | 68 | function LexerNoViableAltException(lexer, input, startIndex, deadEndConfigs) { 69 | RecognitionException.call(this, {message:"", recognizer:lexer, input:input, ctx:null}); 70 | this.startIndex = startIndex; 71 | this.deadEndConfigs = deadEndConfigs; 72 | return this; 73 | } 74 | 75 | LexerNoViableAltException.prototype = Object.create(RecognitionException.prototype); 76 | LexerNoViableAltException.prototype.constructor = LexerNoViableAltException; 77 | 78 | LexerNoViableAltException.prototype.toString = function() { 79 | var symbol = ""; 80 | if (this.startIndex >= 0 && this.startIndex < this.input.size) { 81 | symbol = this.input.getText((this.startIndex,this.startIndex)); 82 | } 83 | return "LexerNoViableAltException" + symbol; 84 | }; 85 | 86 | // Indicates that the parser could not decide which of two or more paths 87 | // to take based upon the remaining input. It tracks the starting token 88 | // of the offending input and also knows where the parser was 89 | // in the various paths when the error. Reported by reportNoViableAlternative() 90 | // 91 | function NoViableAltException(recognizer, input, startToken, offendingToken, deadEndConfigs, ctx) { 92 | ctx = ctx || recognizer._ctx; 93 | offendingToken = offendingToken || recognizer.getCurrentToken(); 94 | startToken = startToken || recognizer.getCurrentToken(); 95 | input = input || recognizer.getInputStream(); 96 | RecognitionException.call(this, {message:"", recognizer:recognizer, input:input, ctx:ctx}); 97 | // Which configurations did we try at input.index() that couldn't match 98 | // input.LT(1)?// 99 | this.deadEndConfigs = deadEndConfigs; 100 | // The token object at the start index; the input stream might 101 | // not be buffering tokens so get a reference to it. (At the 102 | // time the error occurred, of course the stream needs to keep a 103 | // buffer all of the tokens but later we might not have access to those.) 104 | this.startToken = startToken; 105 | this.offendingToken = offendingToken; 106 | } 107 | 108 | NoViableAltException.prototype = Object.create(RecognitionException.prototype); 109 | NoViableAltException.prototype.constructor = NoViableAltException; 110 | 111 | // This signifies any kind of mismatched input exceptions such as 112 | // when the current input does not match the expected token. 113 | // 114 | function InputMismatchException(recognizer) { 115 | RecognitionException.call(this, {message:"", recognizer:recognizer, input:recognizer.getInputStream(), ctx:recognizer._ctx}); 116 | this.offendingToken = recognizer.getCurrentToken(); 117 | } 118 | 119 | InputMismatchException.prototype = Object.create(RecognitionException.prototype); 120 | InputMismatchException.prototype.constructor = InputMismatchException; 121 | 122 | // A semantic predicate failed during validation. Validation of predicates 123 | // occurs when normally parsing the alternative just like matching a token. 124 | // Disambiguating predicate evaluation occurs when we test a predicate during 125 | // prediction. 126 | 127 | function FailedPredicateException(recognizer, predicate, message) { 128 | RecognitionException.call(this, {message:this.formatMessage(predicate,message || null), recognizer:recognizer, 129 | input:recognizer.getInputStream(), ctx:recognizer._ctx}); 130 | var s = recognizer._interp.atn.states[recognizer.state]; 131 | var trans = s.transitions[0]; 132 | if (trans instanceof PredicateTransition) { 133 | this.ruleIndex = trans.ruleIndex; 134 | this.predicateIndex = trans.predIndex; 135 | } else { 136 | this.ruleIndex = 0; 137 | this.predicateIndex = 0; 138 | } 139 | this.predicate = predicate; 140 | this.offendingToken = recognizer.getCurrentToken(); 141 | return this; 142 | } 143 | 144 | FailedPredicateException.prototype = Object.create(RecognitionException.prototype); 145 | FailedPredicateException.prototype.constructor = FailedPredicateException; 146 | 147 | FailedPredicateException.prototype.formatMessage = function(predicate, message) { 148 | if (message !==null) { 149 | return message; 150 | } else { 151 | return "failed predicate: {" + predicate + "}?"; 152 | } 153 | }; 154 | 155 | function ParseCancellationException() { 156 | Error.call(this); 157 | Error.captureStackTrace(this, ParseCancellationException); 158 | return this; 159 | } 160 | 161 | ParseCancellationException.prototype = Object.create(Error.prototype); 162 | ParseCancellationException.prototype.constructor = ParseCancellationException; 163 | 164 | exports.RecognitionException = RecognitionException; 165 | exports.NoViableAltException = NoViableAltException; 166 | exports.LexerNoViableAltException = LexerNoViableAltException; 167 | exports.InputMismatchException = InputMismatchException; 168 | exports.FailedPredicateException = FailedPredicateException; 169 | exports.ParseCancellationException = ParseCancellationException; 170 | -------------------------------------------------------------------------------- /src/antlr4/error/index.js: -------------------------------------------------------------------------------- 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 | exports.RecognitionException = require('./Errors').RecognitionException; 7 | exports.NoViableAltException = require('./Errors').NoViableAltException; 8 | exports.LexerNoViableAltException = require('./Errors').LexerNoViableAltException; 9 | exports.InputMismatchException = require('./Errors').InputMismatchException; 10 | exports.FailedPredicateException = require('./Errors').FailedPredicateException; 11 | exports.DiagnosticErrorListener = require('./DiagnosticErrorListener').DiagnosticErrorListener; 12 | exports.BailErrorStrategy = require('./ErrorStrategy').BailErrorStrategy; 13 | exports.ErrorListener = require('./ErrorListener').ErrorListener; 14 | -------------------------------------------------------------------------------- /src/antlr4/index.js: -------------------------------------------------------------------------------- 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 | exports.atn = require('./atn/index'); 6 | exports.codepointat = require('./polyfills/codepointat'); 7 | exports.dfa = require('./dfa/index'); 8 | exports.fromcodepoint = require('./polyfills/fromcodepoint'); 9 | exports.tree = require('./tree/index'); 10 | exports.error = require('./error/index'); 11 | exports.Token = require('./Token').Token; 12 | exports.CharStreams = require('./CharStreams').CharStreams; 13 | exports.CommonToken = require('./Token').CommonToken; 14 | exports.InputStream = require('./InputStream').InputStream; 15 | exports.FileStream = require('./FileStream').FileStream; 16 | exports.CommonTokenStream = require('./CommonTokenStream').CommonTokenStream; 17 | exports.Lexer = require('./Lexer').Lexer; 18 | exports.Parser = require('./Parser').Parser; 19 | var pc = require('./PredictionContext'); 20 | exports.PredictionContextCache = pc.PredictionContextCache; 21 | exports.ParserRuleContext = require('./ParserRuleContext').ParserRuleContext; 22 | exports.Interval = require('./IntervalSet').Interval; 23 | exports.Utils = require('./Utils'); 24 | -------------------------------------------------------------------------------- /src/antlr4/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "antlr4", 3 | "version": "4.7.0", 4 | "description": "JavaScript runtime for ANTLR4", 5 | "main": "src/antlr4/index.js", 6 | "repository": "antlr/antlr4.git", 7 | "keywords": [ 8 | "lexer", 9 | "parser", 10 | "antlr", 11 | "antlr4", 12 | "grammar" 13 | ], 14 | "license": "BSD", 15 | "bugs": { 16 | "url": "https://github.com/antlr/antlr4/issues" 17 | }, 18 | "homepage": "https://github.com/antlr/antlr4" 19 | } 20 | -------------------------------------------------------------------------------- /src/antlr4/polyfills/codepointat.js: -------------------------------------------------------------------------------- 1 | /*! https://mths.be/codepointat v0.2.0 by @mathias */ 2 | if (!String.prototype.codePointAt) { 3 | (function() { 4 | 'use strict'; // needed to support `apply`/`call` with `undefined`/`null` 5 | var defineProperty = (function() { 6 | // IE 8 only supports `Object.defineProperty` on DOM elements 7 | try { 8 | var object = {}; 9 | var $defineProperty = Object.defineProperty; 10 | var result = $defineProperty(object, object, object) && $defineProperty; 11 | } catch(error) {} 12 | return result; 13 | }()); 14 | var codePointAt = function(position) { 15 | if (this == null) { 16 | throw TypeError(); 17 | } 18 | var string = String(this); 19 | var size = string.length; 20 | // `ToInteger` 21 | var index = position ? Number(position) : 0; 22 | if (index != index) { // better `isNaN` 23 | index = 0; 24 | } 25 | // Account for out-of-bounds indices: 26 | if (index < 0 || index >= size) { 27 | return undefined; 28 | } 29 | // Get the first code unit 30 | var first = string.charCodeAt(index); 31 | var second; 32 | if ( // check if it’s the start of a surrogate pair 33 | first >= 0xD800 && first <= 0xDBFF && // high surrogate 34 | size > index + 1 // there is a next code unit 35 | ) { 36 | second = string.charCodeAt(index + 1); 37 | if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate 38 | // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae 39 | return (first - 0xD800) * 0x400 + second - 0xDC00 + 0x10000; 40 | } 41 | } 42 | return first; 43 | }; 44 | if (defineProperty) { 45 | defineProperty(String.prototype, 'codePointAt', { 46 | 'value': codePointAt, 47 | 'configurable': true, 48 | 'writable': true 49 | }); 50 | } else { 51 | String.prototype.codePointAt = codePointAt; 52 | } 53 | }()); 54 | } 55 | -------------------------------------------------------------------------------- /src/antlr4/polyfills/fromcodepoint.js: -------------------------------------------------------------------------------- 1 | /*! https://mths.be/fromcodepoint v0.2.1 by @mathias */ 2 | if (!String.fromCodePoint) { 3 | (function() { 4 | var defineProperty = (function() { 5 | // IE 8 only supports `Object.defineProperty` on DOM elements 6 | try { 7 | var object = {}; 8 | var $defineProperty = Object.defineProperty; 9 | var result = $defineProperty(object, object, object) && $defineProperty; 10 | } catch(error) {} 11 | return result; 12 | }()); 13 | var stringFromCharCode = String.fromCharCode; 14 | var floor = Math.floor; 15 | var fromCodePoint = function(_) { 16 | var MAX_SIZE = 0x4000; 17 | var codeUnits = []; 18 | var highSurrogate; 19 | var lowSurrogate; 20 | var index = -1; 21 | var length = arguments.length; 22 | if (!length) { 23 | return ''; 24 | } 25 | var result = ''; 26 | while (++index < length) { 27 | var codePoint = Number(arguments[index]); 28 | if ( 29 | !isFinite(codePoint) || // `NaN`, `+Infinity`, or `-Infinity` 30 | codePoint < 0 || // not a valid Unicode code point 31 | codePoint > 0x10FFFF || // not a valid Unicode code point 32 | floor(codePoint) != codePoint // not an integer 33 | ) { 34 | throw RangeError('Invalid code point: ' + codePoint); 35 | } 36 | if (codePoint <= 0xFFFF) { // BMP code point 37 | codeUnits.push(codePoint); 38 | } else { // Astral code point; split in surrogate halves 39 | // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae 40 | codePoint -= 0x10000; 41 | highSurrogate = (codePoint >> 10) + 0xD800; 42 | lowSurrogate = (codePoint % 0x400) + 0xDC00; 43 | codeUnits.push(highSurrogate, lowSurrogate); 44 | } 45 | if (index + 1 == length || codeUnits.length > MAX_SIZE) { 46 | result += stringFromCharCode.apply(null, codeUnits); 47 | codeUnits.length = 0; 48 | } 49 | } 50 | return result; 51 | }; 52 | if (defineProperty) { 53 | defineProperty(String, 'fromCodePoint', { 54 | 'value': fromCodePoint, 55 | 'configurable': true, 56 | 'writable': true 57 | }); 58 | } else { 59 | String.fromCodePoint = fromCodePoint; 60 | } 61 | }()); 62 | } 63 | -------------------------------------------------------------------------------- /src/antlr4/tree/Tree.js: -------------------------------------------------------------------------------- 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 | 7 | // The basic notion of a tree has a parent, a payload, and a list of children. 8 | // It is the most abstract interface for all the trees used by ANTLR. 9 | /// 10 | 11 | var Token = require('./../Token').Token; 12 | var Interval = require('./../IntervalSet').Interval; 13 | var INVALID_INTERVAL = new Interval(-1, -2); 14 | var Utils = require('../Utils.js'); 15 | 16 | 17 | function Tree() { 18 | return this; 19 | } 20 | 21 | function SyntaxTree() { 22 | Tree.call(this); 23 | return this; 24 | } 25 | 26 | SyntaxTree.prototype = Object.create(Tree.prototype); 27 | SyntaxTree.prototype.constructor = SyntaxTree; 28 | 29 | function ParseTree() { 30 | SyntaxTree.call(this); 31 | return this; 32 | } 33 | 34 | ParseTree.prototype = Object.create(SyntaxTree.prototype); 35 | ParseTree.prototype.constructor = ParseTree; 36 | 37 | function RuleNode() { 38 | ParseTree.call(this); 39 | return this; 40 | } 41 | 42 | RuleNode.prototype = Object.create(ParseTree.prototype); 43 | RuleNode.prototype.constructor = RuleNode; 44 | 45 | function TerminalNode() { 46 | ParseTree.call(this); 47 | return this; 48 | } 49 | 50 | TerminalNode.prototype = Object.create(ParseTree.prototype); 51 | TerminalNode.prototype.constructor = TerminalNode; 52 | 53 | function ErrorNode() { 54 | TerminalNode.call(this); 55 | return this; 56 | } 57 | 58 | ErrorNode.prototype = Object.create(TerminalNode.prototype); 59 | ErrorNode.prototype.constructor = ErrorNode; 60 | 61 | function ParseTreeVisitor() { 62 | return this; 63 | } 64 | 65 | ParseTreeVisitor.prototype.visit = function(ctx) { 66 | if (Array.isArray(ctx)) { 67 | return ctx.map(function(child) { 68 | return child.accept(this); 69 | }, this); 70 | } else { 71 | return ctx.accept(this); 72 | } 73 | }; 74 | 75 | ParseTreeVisitor.prototype.visitChildren = function(ctx) { 76 | return this.visit(ctx.children); 77 | } 78 | 79 | ParseTreeVisitor.prototype.visitTerminal = function(node) { 80 | }; 81 | 82 | ParseTreeVisitor.prototype.visitErrorNode = function(node) { 83 | }; 84 | 85 | 86 | function ParseTreeListener() { 87 | return this; 88 | } 89 | 90 | ParseTreeListener.prototype.visitTerminal = function(node) { 91 | }; 92 | 93 | ParseTreeListener.prototype.visitErrorNode = function(node) { 94 | }; 95 | 96 | ParseTreeListener.prototype.enterEveryRule = function(node) { 97 | }; 98 | 99 | ParseTreeListener.prototype.exitEveryRule = function(node) { 100 | }; 101 | 102 | function TerminalNodeImpl(symbol) { 103 | TerminalNode.call(this); 104 | this.parentCtx = null; 105 | this.symbol = symbol; 106 | return this; 107 | } 108 | 109 | TerminalNodeImpl.prototype = Object.create(TerminalNode.prototype); 110 | TerminalNodeImpl.prototype.constructor = TerminalNodeImpl; 111 | 112 | TerminalNodeImpl.prototype.getChild = function(i) { 113 | return null; 114 | }; 115 | 116 | TerminalNodeImpl.prototype.getSymbol = function() { 117 | return this.symbol; 118 | }; 119 | 120 | TerminalNodeImpl.prototype.getParent = function() { 121 | return this.parentCtx; 122 | }; 123 | 124 | TerminalNodeImpl.prototype.getPayload = function() { 125 | return this.symbol; 126 | }; 127 | 128 | TerminalNodeImpl.prototype.getSourceInterval = function() { 129 | if (this.symbol === null) { 130 | return INVALID_INTERVAL; 131 | } 132 | var tokenIndex = this.symbol.tokenIndex; 133 | return new Interval(tokenIndex, tokenIndex); 134 | }; 135 | 136 | TerminalNodeImpl.prototype.getChildCount = function() { 137 | return 0; 138 | }; 139 | 140 | TerminalNodeImpl.prototype.accept = function(visitor) { 141 | return visitor.visitTerminal(this); 142 | }; 143 | 144 | TerminalNodeImpl.prototype.getText = function() { 145 | return this.symbol.text; 146 | }; 147 | 148 | TerminalNodeImpl.prototype.toString = function() { 149 | if (this.symbol.type === Token.EOF) { 150 | return "