@jorgsowa/php-parser 3.2.5-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +27 -0
- package/README.md +108 -0
- package/dist/@jorgsowa/php-parser.js +11239 -0
- package/dist/@jorgsowa/php-parser.min.js +2 -0
- package/dist/@jorgsowa/php-parser.min.js.LICENSE.txt +10 -0
- package/package.json +86 -0
- package/src/ast/array.js +44 -0
- package/src/ast/arrowfunc.js +43 -0
- package/src/ast/assign.js +28 -0
- package/src/ast/assignref.js +27 -0
- package/src/ast/attrgroup.js +21 -0
- package/src/ast/attribute.js +26 -0
- package/src/ast/bin.js +27 -0
- package/src/ast/block.js +24 -0
- package/src/ast/boolean.js +23 -0
- package/src/ast/break.js +21 -0
- package/src/ast/byref.js +21 -0
- package/src/ast/call.js +26 -0
- package/src/ast/case.js +26 -0
- package/src/ast/cast.js +28 -0
- package/src/ast/catch.js +29 -0
- package/src/ast/class.js +36 -0
- package/src/ast/classconstant.js +71 -0
- package/src/ast/clone.js +21 -0
- package/src/ast/closure.js +47 -0
- package/src/ast/comment.js +23 -0
- package/src/ast/commentblock.js +22 -0
- package/src/ast/commentline.js +22 -0
- package/src/ast/constant.js +26 -0
- package/src/ast/constantstatement.js +24 -0
- package/src/ast/continue.js +24 -0
- package/src/ast/declaration.js +60 -0
- package/src/ast/declare.js +71 -0
- package/src/ast/declaredirective.js +26 -0
- package/src/ast/do.js +26 -0
- package/src/ast/echo.js +26 -0
- package/src/ast/empty.js +23 -0
- package/src/ast/encapsed.js +75 -0
- package/src/ast/encapsedpart.js +28 -0
- package/src/ast/entry.js +30 -0
- package/src/ast/enum.js +30 -0
- package/src/ast/enumcase.js +26 -0
- package/src/ast/error.js +30 -0
- package/src/ast/eval.js +24 -0
- package/src/ast/exit.js +26 -0
- package/src/ast/expression.js +20 -0
- package/src/ast/expressionstatement.js +24 -0
- package/src/ast/for.js +33 -0
- package/src/ast/foreach.js +33 -0
- package/src/ast/function.js +34 -0
- package/src/ast/global.js +24 -0
- package/src/ast/goto.js +22 -0
- package/src/ast/halt.js +22 -0
- package/src/ast/identifier.js +26 -0
- package/src/ast/if.js +30 -0
- package/src/ast/include.js +28 -0
- package/src/ast/inline.js +23 -0
- package/src/ast/interface.js +28 -0
- package/src/ast/intersectiontype.js +24 -0
- package/src/ast/isset.js +23 -0
- package/src/ast/label.js +21 -0
- package/src/ast/list.js +26 -0
- package/src/ast/literal.js +28 -0
- package/src/ast/location.js +22 -0
- package/src/ast/lookup.js +26 -0
- package/src/ast/magic.js +22 -0
- package/src/ast/match.js +26 -0
- package/src/ast/matcharm.js +26 -0
- package/src/ast/method.js +24 -0
- package/src/ast/name.js +55 -0
- package/src/ast/namedargument.js +27 -0
- package/src/ast/namespace.js +26 -0
- package/src/ast/new.js +26 -0
- package/src/ast/node.js +111 -0
- package/src/ast/noop.js +20 -0
- package/src/ast/nowdoc.js +26 -0
- package/src/ast/nullkeyword.js +20 -0
- package/src/ast/nullsafepropertylookup.js +22 -0
- package/src/ast/number.js +23 -0
- package/src/ast/offsetlookup.js +22 -0
- package/src/ast/operation.js +19 -0
- package/src/ast/parameter.js +61 -0
- package/src/ast/parentreference.js +24 -0
- package/src/ast/position.js +22 -0
- package/src/ast/post.js +26 -0
- package/src/ast/pre.js +26 -0
- package/src/ast/print.js +23 -0
- package/src/ast/program.js +32 -0
- package/src/ast/property.js +46 -0
- package/src/ast/propertyhook.js +33 -0
- package/src/ast/propertylookup.js +22 -0
- package/src/ast/propertystatement.js +59 -0
- package/src/ast/reference.js +21 -0
- package/src/ast/retif.js +28 -0
- package/src/ast/return.js +21 -0
- package/src/ast/selfreference.js +24 -0
- package/src/ast/silent.js +24 -0
- package/src/ast/statement.js +19 -0
- package/src/ast/static.js +24 -0
- package/src/ast/staticlookup.js +22 -0
- package/src/ast/staticreference.js +24 -0
- package/src/ast/staticvariable.js +26 -0
- package/src/ast/string.js +28 -0
- package/src/ast/switch.js +28 -0
- package/src/ast/throw.js +21 -0
- package/src/ast/trait.js +24 -0
- package/src/ast/traitalias.js +44 -0
- package/src/ast/traitprecedence.js +28 -0
- package/src/ast/traituse.js +26 -0
- package/src/ast/try.js +28 -0
- package/src/ast/typereference.js +40 -0
- package/src/ast/unary.js +26 -0
- package/src/ast/uniontype.js +24 -0
- package/src/ast/unset.js +23 -0
- package/src/ast/usegroup.js +30 -0
- package/src/ast/useitem.js +45 -0
- package/src/ast/variable.js +36 -0
- package/src/ast/variadic.js +25 -0
- package/src/ast/variadicplaceholder.js +24 -0
- package/src/ast/while.js +28 -0
- package/src/ast/yield.js +27 -0
- package/src/ast/yieldfrom.js +25 -0
- package/src/ast.js +593 -0
- package/src/index.js +239 -0
- package/src/lexer/attribute.js +85 -0
- package/src/lexer/comments.js +63 -0
- package/src/lexer/initial.js +64 -0
- package/src/lexer/numbers.js +171 -0
- package/src/lexer/property.js +96 -0
- package/src/lexer/scripting.js +114 -0
- package/src/lexer/strings.js +524 -0
- package/src/lexer/tokens.js +356 -0
- package/src/lexer/utils.js +112 -0
- package/src/lexer.js +561 -0
- package/src/parser/array.js +113 -0
- package/src/parser/class.js +718 -0
- package/src/parser/comment.js +52 -0
- package/src/parser/enum.js +56 -0
- package/src/parser/expr.js +848 -0
- package/src/parser/function.js +507 -0
- package/src/parser/if.js +94 -0
- package/src/parser/loops.js +168 -0
- package/src/parser/main.js +21 -0
- package/src/parser/namespace.js +231 -0
- package/src/parser/scalar.js +492 -0
- package/src/parser/statement.js +444 -0
- package/src/parser/switch.js +99 -0
- package/src/parser/try.js +43 -0
- package/src/parser/utils.js +203 -0
- package/src/parser/variable.js +363 -0
- package/src/parser.js +748 -0
- package/src/tokens.js +177 -0
- package/types.d.ts +1457 -0
package/src/index.js
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2020 Glayzzle (BSD3 License)
|
|
3
|
+
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
|
|
4
|
+
* @url http://glayzzle.com
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
const lexer = require("./lexer");
|
|
9
|
+
const parser = require("./parser");
|
|
10
|
+
const tokens = require("./tokens");
|
|
11
|
+
const AST = require("./ast");
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
function combine(src, to) {
|
|
17
|
+
const keys = Object.keys(src);
|
|
18
|
+
let i = keys.length;
|
|
19
|
+
while (i--) {
|
|
20
|
+
const k = keys[i];
|
|
21
|
+
const val = src[k];
|
|
22
|
+
if (val === null) {
|
|
23
|
+
delete to[k];
|
|
24
|
+
} else if (typeof val === "function") {
|
|
25
|
+
to[k] = val.bind(to);
|
|
26
|
+
} else if (Array.isArray(val)) {
|
|
27
|
+
to[k] = Array.isArray(to[k]) ? to[k].concat(val) : val;
|
|
28
|
+
} else if (typeof val === "object") {
|
|
29
|
+
to[k] = typeof to[k] === "object" ? combine(val, to[k]) : val;
|
|
30
|
+
} else {
|
|
31
|
+
to[k] = val;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return to;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Initialise a new parser instance with the specified options
|
|
39
|
+
*
|
|
40
|
+
* @class
|
|
41
|
+
* @memberOf module:php-parser
|
|
42
|
+
* @tutorial Engine
|
|
43
|
+
* @example
|
|
44
|
+
* var parser = require('php-parser');
|
|
45
|
+
* var instance = new parser({
|
|
46
|
+
* parser: {
|
|
47
|
+
* extractDoc: true,
|
|
48
|
+
* suppressErrors: true,
|
|
49
|
+
* version: 704 // or '7.4'
|
|
50
|
+
* },
|
|
51
|
+
* ast: {
|
|
52
|
+
* withPositions: true
|
|
53
|
+
* },
|
|
54
|
+
* lexer: {
|
|
55
|
+
* short_tags: true,
|
|
56
|
+
* asp_tags: true
|
|
57
|
+
* }
|
|
58
|
+
* });
|
|
59
|
+
*
|
|
60
|
+
* var evalAST = instance.parseEval('some php code');
|
|
61
|
+
* var codeAST = instance.parseCode('<?php some php code', 'foo.php');
|
|
62
|
+
* var tokens = instance.tokenGetAll('<?php some php code');
|
|
63
|
+
*
|
|
64
|
+
* @param {Object} options - List of options
|
|
65
|
+
* @property {Lexer} lexer
|
|
66
|
+
* @property {Parser} parser
|
|
67
|
+
* @property {AST} ast
|
|
68
|
+
* @property {Object} tokens
|
|
69
|
+
*/
|
|
70
|
+
const Engine = function (options) {
|
|
71
|
+
if (typeof this === "function") {
|
|
72
|
+
return new this(options);
|
|
73
|
+
}
|
|
74
|
+
this.tokens = tokens;
|
|
75
|
+
this.lexer = new lexer(this);
|
|
76
|
+
this.ast = new AST();
|
|
77
|
+
this.parser = new parser(this.lexer, this.ast);
|
|
78
|
+
if (options && typeof options === "object") {
|
|
79
|
+
// disable php7 from lexer if already disabled from parser
|
|
80
|
+
if (options.parser) {
|
|
81
|
+
if (!options.lexer) {
|
|
82
|
+
options.lexer = {};
|
|
83
|
+
}
|
|
84
|
+
if (options.parser.version) {
|
|
85
|
+
if (typeof options.parser.version === "string") {
|
|
86
|
+
let version = options.parser.version.split(".");
|
|
87
|
+
version = parseInt(version[0]) * 100 + parseInt(version[1]);
|
|
88
|
+
if (isNaN(version)) {
|
|
89
|
+
throw new Error("Bad version number : " + options.parser.version);
|
|
90
|
+
} else {
|
|
91
|
+
options.parser.version = version;
|
|
92
|
+
}
|
|
93
|
+
} else if (typeof options.parser.version !== "number") {
|
|
94
|
+
throw new Error("Expecting a number for version");
|
|
95
|
+
}
|
|
96
|
+
if (options.parser.version < 500 || options.parser.version > 900) {
|
|
97
|
+
throw new Error("Can only handle versions between 5.x to 8.x");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
combine(options, this);
|
|
102
|
+
|
|
103
|
+
// same version flags based on parser options
|
|
104
|
+
this.lexer.version = this.parser.version;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Check if the inpyt is a buffer or a string
|
|
110
|
+
* @private
|
|
111
|
+
* @param {Buffer|String} buffer Input value that can be either a buffer or a string
|
|
112
|
+
* @return {String} Returns the string from input
|
|
113
|
+
*/
|
|
114
|
+
const getStringBuffer = function (buffer) {
|
|
115
|
+
return typeof buffer.write === "function" ? buffer.toString() : buffer;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Creates a new instance (Helper)
|
|
120
|
+
* @param {Object} options
|
|
121
|
+
* @return {Engine}
|
|
122
|
+
* @private
|
|
123
|
+
*/
|
|
124
|
+
Engine.create = function (options) {
|
|
125
|
+
return new Engine(options);
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Evaluate the buffer
|
|
130
|
+
* @private
|
|
131
|
+
*/
|
|
132
|
+
Engine.parseEval = function (buffer, options) {
|
|
133
|
+
const self = new Engine(options);
|
|
134
|
+
return self.parseEval(buffer);
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Parse an evaluating mode string (no need to open php tags)
|
|
139
|
+
* @param {String} buffer
|
|
140
|
+
* @return {Program}
|
|
141
|
+
*/
|
|
142
|
+
Engine.prototype.parseEval = function (buffer) {
|
|
143
|
+
this.lexer.mode_eval = true;
|
|
144
|
+
this.lexer.all_tokens = false;
|
|
145
|
+
buffer = getStringBuffer(buffer);
|
|
146
|
+
return this.parser.parse(buffer, "eval");
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Static function that parse a php code with open/close tags
|
|
151
|
+
* @private
|
|
152
|
+
*/
|
|
153
|
+
Engine.parseCode = function (buffer, filename, options) {
|
|
154
|
+
if (typeof filename === "object" && !options) {
|
|
155
|
+
// retro-compatibility
|
|
156
|
+
options = filename;
|
|
157
|
+
filename = "unknown";
|
|
158
|
+
}
|
|
159
|
+
const self = new Engine(options);
|
|
160
|
+
return self.parseCode(buffer, filename);
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Function that parse a php code with open/close tags
|
|
165
|
+
*
|
|
166
|
+
* Sample code :
|
|
167
|
+
* ```php
|
|
168
|
+
* <?php $x = 1;
|
|
169
|
+
* ```
|
|
170
|
+
*
|
|
171
|
+
* Usage :
|
|
172
|
+
* ```js
|
|
173
|
+
* var parser = require('php-parser');
|
|
174
|
+
* var phpParser = new parser({
|
|
175
|
+
* // some options
|
|
176
|
+
* });
|
|
177
|
+
* var ast = phpParser.parseCode('...php code...', 'foo.php');
|
|
178
|
+
* ```
|
|
179
|
+
* @param {String} buffer - The code to be parsed
|
|
180
|
+
* @param {String} filename - Filename
|
|
181
|
+
* @return {Program}
|
|
182
|
+
*/
|
|
183
|
+
Engine.prototype.parseCode = function (buffer, filename) {
|
|
184
|
+
this.lexer.mode_eval = false;
|
|
185
|
+
this.lexer.all_tokens = false;
|
|
186
|
+
buffer = getStringBuffer(buffer);
|
|
187
|
+
return this.parser.parse(buffer, filename);
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Split the buffer into tokens
|
|
192
|
+
* @private
|
|
193
|
+
*/
|
|
194
|
+
Engine.tokenGetAll = function (buffer, options) {
|
|
195
|
+
const self = new Engine(options);
|
|
196
|
+
return self.tokenGetAll(buffer);
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Extract tokens from the specified buffer.
|
|
201
|
+
* > Note that the output tokens are *STRICLY* similar to PHP function `token_get_all`
|
|
202
|
+
* @param {string} buffer
|
|
203
|
+
* @return {Array<string|string[]>} - Each item can be a string or an array with following informations [token_name, text, line_number]
|
|
204
|
+
*/
|
|
205
|
+
Engine.prototype.tokenGetAll = function (buffer) {
|
|
206
|
+
this.lexer.mode_eval = false;
|
|
207
|
+
this.lexer.all_tokens = true;
|
|
208
|
+
buffer = getStringBuffer(buffer);
|
|
209
|
+
const EOF = this.lexer.EOF;
|
|
210
|
+
const names = this.tokens.values;
|
|
211
|
+
this.lexer.setInput(buffer);
|
|
212
|
+
let token = this.lexer.lex() || EOF;
|
|
213
|
+
const result = [];
|
|
214
|
+
while (token != EOF) {
|
|
215
|
+
let entry = this.lexer.yytext;
|
|
216
|
+
if (Object.prototype.hasOwnProperty.call(names, token)) {
|
|
217
|
+
entry = [names[token], entry, this.lexer.yylloc.first_line];
|
|
218
|
+
}
|
|
219
|
+
result.push(entry);
|
|
220
|
+
token = this.lexer.lex() || EOF;
|
|
221
|
+
}
|
|
222
|
+
return result;
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
/** @module php-parser */
|
|
226
|
+
|
|
227
|
+
// exports the function
|
|
228
|
+
module.exports = Engine;
|
|
229
|
+
|
|
230
|
+
// makes libraries public
|
|
231
|
+
module.exports.tokens = tokens;
|
|
232
|
+
module.exports.lexer = lexer;
|
|
233
|
+
module.exports.AST = AST;
|
|
234
|
+
module.exports.parser = parser;
|
|
235
|
+
module.exports.combine = combine;
|
|
236
|
+
module.exports.Engine = Engine;
|
|
237
|
+
|
|
238
|
+
// allow the default export in index.d.ts
|
|
239
|
+
module.exports.default = Engine;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2018 Glayzzle (BSD3 License)
|
|
3
|
+
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
|
|
4
|
+
* @url http://glayzzle.com
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
attributeIndex: 0,
|
|
10
|
+
attributeListDepth: {},
|
|
11
|
+
matchST_ATTRIBUTE() {
|
|
12
|
+
let ch = this.input();
|
|
13
|
+
if (this.is_WHITESPACE()) {
|
|
14
|
+
do {
|
|
15
|
+
ch = this.input();
|
|
16
|
+
} while (this.is_WHITESPACE());
|
|
17
|
+
this.unput(1);
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
switch (ch) {
|
|
21
|
+
case "]":
|
|
22
|
+
if (this.attributeListDepth[this.attributeIndex] === 0) {
|
|
23
|
+
delete this.attributeListDepth[this.attributeIndex];
|
|
24
|
+
this.attributeIndex--;
|
|
25
|
+
this.popState();
|
|
26
|
+
} else {
|
|
27
|
+
/* istanbul ignore next */
|
|
28
|
+
this.attributeListDepth[this.attributeIndex]--;
|
|
29
|
+
}
|
|
30
|
+
return "]";
|
|
31
|
+
case "(":
|
|
32
|
+
case ")":
|
|
33
|
+
case ":":
|
|
34
|
+
case "=":
|
|
35
|
+
case "|":
|
|
36
|
+
case "&":
|
|
37
|
+
case "^":
|
|
38
|
+
case "-":
|
|
39
|
+
case "+":
|
|
40
|
+
case "*":
|
|
41
|
+
case "%":
|
|
42
|
+
case "~":
|
|
43
|
+
case "<":
|
|
44
|
+
case ">":
|
|
45
|
+
case "!":
|
|
46
|
+
case ".":
|
|
47
|
+
return this.consume_TOKEN();
|
|
48
|
+
case "[":
|
|
49
|
+
this.attributeListDepth[this.attributeIndex]++;
|
|
50
|
+
return "[";
|
|
51
|
+
case ",":
|
|
52
|
+
return ",";
|
|
53
|
+
case '"':
|
|
54
|
+
return this.ST_DOUBLE_QUOTES();
|
|
55
|
+
case "'":
|
|
56
|
+
return this.T_CONSTANT_ENCAPSED_STRING();
|
|
57
|
+
case "/":
|
|
58
|
+
if (this._input[this.offset] === "/") {
|
|
59
|
+
return this.T_COMMENT();
|
|
60
|
+
} else if (this._input[this.offset] === "*") {
|
|
61
|
+
this.input();
|
|
62
|
+
return this.T_DOC_COMMENT();
|
|
63
|
+
} else {
|
|
64
|
+
return this.consume_TOKEN();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (this.is_LABEL_START() || ch === "\\") {
|
|
68
|
+
while (this.offset < this.size) {
|
|
69
|
+
const ch = this.input();
|
|
70
|
+
if (!(this.is_LABEL() || ch === "\\")) {
|
|
71
|
+
if (ch) this.unput(1);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return this.T_STRING();
|
|
76
|
+
} else if (this.is_NUM()) {
|
|
77
|
+
return this.consume_NUM();
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* istanbul ignore next */
|
|
81
|
+
throw new Error(
|
|
82
|
+
`Bad terminal sequence "${ch}" at line ${this.yylineno} (offset ${this.offset})`,
|
|
83
|
+
);
|
|
84
|
+
},
|
|
85
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2018 Glayzzle (BSD3 License)
|
|
3
|
+
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
|
|
4
|
+
* @url http://glayzzle.com
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
/*
|
|
10
|
+
* Reads a single line comment
|
|
11
|
+
*/
|
|
12
|
+
T_COMMENT() {
|
|
13
|
+
while (this.offset < this.size) {
|
|
14
|
+
const ch = this.input();
|
|
15
|
+
if (ch === "\n" || ch === "\r") {
|
|
16
|
+
return this.tok.T_COMMENT;
|
|
17
|
+
} else if (
|
|
18
|
+
ch === "?" &&
|
|
19
|
+
!this.aspTagMode &&
|
|
20
|
+
this._input[this.offset] === ">"
|
|
21
|
+
) {
|
|
22
|
+
this.unput(1);
|
|
23
|
+
return this.tok.T_COMMENT;
|
|
24
|
+
} else if (
|
|
25
|
+
ch === "%" &&
|
|
26
|
+
this.aspTagMode &&
|
|
27
|
+
this._input[this.offset] === ">"
|
|
28
|
+
) {
|
|
29
|
+
this.unput(1);
|
|
30
|
+
return this.tok.T_COMMENT;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return this.tok.T_COMMENT;
|
|
34
|
+
},
|
|
35
|
+
/*
|
|
36
|
+
* Behaviour : https://github.com/php/php-src/blob/master/Zend/zend_language_scanner.l#L1927
|
|
37
|
+
*/
|
|
38
|
+
T_DOC_COMMENT() {
|
|
39
|
+
let ch = this.input();
|
|
40
|
+
let token = this.tok.T_COMMENT;
|
|
41
|
+
if (ch === "*") {
|
|
42
|
+
// started with '/*' , check is next is '*'
|
|
43
|
+
ch = this.input();
|
|
44
|
+
if (this.is_WHITESPACE()) {
|
|
45
|
+
// check if next is WHITESPACE
|
|
46
|
+
token = this.tok.T_DOC_COMMENT;
|
|
47
|
+
}
|
|
48
|
+
if (ch === "/") {
|
|
49
|
+
return token;
|
|
50
|
+
} else {
|
|
51
|
+
this.unput(1); // reset
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
while (this.offset < this.size) {
|
|
55
|
+
ch = this.input();
|
|
56
|
+
if (ch === "*" && this._input[this.offset] === "/") {
|
|
57
|
+
this.input();
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return token;
|
|
62
|
+
},
|
|
63
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2018 Glayzzle (BSD3 License)
|
|
3
|
+
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
|
|
4
|
+
* @url http://glayzzle.com
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
module.exports = {
|
|
9
|
+
nextINITIAL() {
|
|
10
|
+
if (
|
|
11
|
+
this.conditionStack.length > 1 &&
|
|
12
|
+
this.conditionStack[this.conditionStack.length - 1] === "INITIAL"
|
|
13
|
+
) {
|
|
14
|
+
// Return to HEREDOC/ST_DOUBLE_QUOTES mode
|
|
15
|
+
this.popState();
|
|
16
|
+
} else {
|
|
17
|
+
this.begin("ST_IN_SCRIPTING");
|
|
18
|
+
}
|
|
19
|
+
return this;
|
|
20
|
+
},
|
|
21
|
+
matchINITIAL() {
|
|
22
|
+
while (this.offset < this.size) {
|
|
23
|
+
let ch = this.input();
|
|
24
|
+
if (ch == "<") {
|
|
25
|
+
ch = this.ahead(1);
|
|
26
|
+
if (ch == "?") {
|
|
27
|
+
if (this.tryMatch("?=")) {
|
|
28
|
+
this.unput(1)
|
|
29
|
+
.appendToken(this.tok.T_OPEN_TAG_WITH_ECHO, 3)
|
|
30
|
+
.nextINITIAL();
|
|
31
|
+
break;
|
|
32
|
+
} else if (this.tryMatchCaseless("?php")) {
|
|
33
|
+
ch = this._input[this.offset + 4];
|
|
34
|
+
if (ch === " " || ch === "\t" || ch === "\n" || ch === "\r") {
|
|
35
|
+
this.unput(1).appendToken(this.tok.T_OPEN_TAG, 6).nextINITIAL();
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
if (this.short_tags) {
|
|
40
|
+
this.unput(1).appendToken(this.tok.T_OPEN_TAG, 2).nextINITIAL();
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
} else if (this.asp_tags && ch == "%") {
|
|
44
|
+
if (this.tryMatch("%=")) {
|
|
45
|
+
this.aspTagMode = true;
|
|
46
|
+
this.unput(1)
|
|
47
|
+
.appendToken(this.tok.T_OPEN_TAG_WITH_ECHO, 3)
|
|
48
|
+
.nextINITIAL();
|
|
49
|
+
break;
|
|
50
|
+
} else {
|
|
51
|
+
this.aspTagMode = true;
|
|
52
|
+
this.unput(1).appendToken(this.tok.T_OPEN_TAG, 2).nextINITIAL();
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (this.yytext.length > 0) {
|
|
59
|
+
return this.tok.T_INLINE_HTML;
|
|
60
|
+
} else {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
};
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2018 Glayzzle (BSD3 License)
|
|
3
|
+
* @authors https://github.com/glayzzle/php-parser/graphs/contributors
|
|
4
|
+
* @url http://glayzzle.com
|
|
5
|
+
*/
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
/* istanbul ignore else */
|
|
9
|
+
let MAX_LENGTH_OF_LONG = 10;
|
|
10
|
+
let long_min_digits = "2147483648";
|
|
11
|
+
if (process.arch == "x64") {
|
|
12
|
+
MAX_LENGTH_OF_LONG = 19;
|
|
13
|
+
long_min_digits = "9223372036854775808";
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
module.exports = {
|
|
17
|
+
consume_NUM() {
|
|
18
|
+
let ch = this.yytext[0];
|
|
19
|
+
let hasPoint = ch === ".";
|
|
20
|
+
if (ch === "0") {
|
|
21
|
+
ch = this.input();
|
|
22
|
+
// check if hexa
|
|
23
|
+
if (ch === "x" || ch === "X") {
|
|
24
|
+
ch = this.input();
|
|
25
|
+
if (ch !== "_" && this.is_HEX()) {
|
|
26
|
+
return this.consume_HNUM();
|
|
27
|
+
} else {
|
|
28
|
+
this.unput(ch ? 2 : 1);
|
|
29
|
+
}
|
|
30
|
+
// check binary notation
|
|
31
|
+
} else if (ch === "b" || ch === "B") {
|
|
32
|
+
ch = this.input();
|
|
33
|
+
if ((ch !== "_" && ch === "0") || ch === "1") {
|
|
34
|
+
return this.consume_BNUM();
|
|
35
|
+
} else {
|
|
36
|
+
this.unput(ch ? 2 : 1);
|
|
37
|
+
}
|
|
38
|
+
} else if (ch === "o" || ch === "O") {
|
|
39
|
+
ch = this.input();
|
|
40
|
+
if (ch !== "_" && this.is_OCTAL()) {
|
|
41
|
+
return this.consume_ONUM();
|
|
42
|
+
} else {
|
|
43
|
+
this.unput(ch ? 2 : 1);
|
|
44
|
+
}
|
|
45
|
+
} else if (!this.is_NUM()) {
|
|
46
|
+
if (ch) this.unput(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
while (this.offset < this.size) {
|
|
51
|
+
const prev = ch;
|
|
52
|
+
ch = this.input();
|
|
53
|
+
|
|
54
|
+
if (ch === "_") {
|
|
55
|
+
if (prev === "_") {
|
|
56
|
+
// restriction : next to underscore / 1__1;
|
|
57
|
+
this.unput(2); // keep 1
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
if (prev === ".") {
|
|
61
|
+
// next to decimal point "1._0"
|
|
62
|
+
this.unput(1); // keep 1.
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
if (prev === "e" || prev === "E") {
|
|
66
|
+
// next to e "1e_10"
|
|
67
|
+
this.unput(2); // keep 1
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
} else if (ch === ".") {
|
|
71
|
+
if (hasPoint) {
|
|
72
|
+
// no multiple points "1.0.5"
|
|
73
|
+
this.unput(1); // keep 1.0
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
if (prev === "_") {
|
|
77
|
+
// next to decimal point "1_.0"
|
|
78
|
+
this.unput(2); // keep 1
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
hasPoint = true;
|
|
82
|
+
continue;
|
|
83
|
+
} else if (ch === "e" || ch === "E") {
|
|
84
|
+
if (prev === "_") {
|
|
85
|
+
// next to e "1_e10"
|
|
86
|
+
this.unput(1);
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
let undo = 2;
|
|
90
|
+
ch = this.input();
|
|
91
|
+
if (ch === "+" || ch === "-") {
|
|
92
|
+
// 1e-5
|
|
93
|
+
undo = 3;
|
|
94
|
+
ch = this.input();
|
|
95
|
+
}
|
|
96
|
+
if (this.is_NUM_START()) {
|
|
97
|
+
this.consume_LNUM();
|
|
98
|
+
return this.tok.T_DNUMBER;
|
|
99
|
+
}
|
|
100
|
+
this.unput(ch ? undo : undo - 1); // keep only 1
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!this.is_NUM()) {
|
|
105
|
+
// example : 10.0a
|
|
106
|
+
if (ch) this.unput(1); // keep 10.0
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (hasPoint) {
|
|
112
|
+
return this.tok.T_DNUMBER;
|
|
113
|
+
} else if (this.yytext.length < MAX_LENGTH_OF_LONG - 1) {
|
|
114
|
+
return this.tok.T_LNUMBER;
|
|
115
|
+
} else {
|
|
116
|
+
if (
|
|
117
|
+
this.yytext.length < MAX_LENGTH_OF_LONG ||
|
|
118
|
+
(this.yytext.length == MAX_LENGTH_OF_LONG &&
|
|
119
|
+
this.yytext < long_min_digits)
|
|
120
|
+
) {
|
|
121
|
+
return this.tok.T_LNUMBER;
|
|
122
|
+
}
|
|
123
|
+
return this.tok.T_DNUMBER;
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
// read hexa
|
|
127
|
+
consume_HNUM() {
|
|
128
|
+
while (this.offset < this.size) {
|
|
129
|
+
const ch = this.input();
|
|
130
|
+
if (!this.is_HEX()) {
|
|
131
|
+
if (ch) this.unput(1);
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return this.tok.T_LNUMBER;
|
|
136
|
+
},
|
|
137
|
+
// read a generic number
|
|
138
|
+
consume_LNUM() {
|
|
139
|
+
while (this.offset < this.size) {
|
|
140
|
+
const ch = this.input();
|
|
141
|
+
if (!this.is_NUM()) {
|
|
142
|
+
if (ch) this.unput(1);
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return this.tok.T_LNUMBER;
|
|
147
|
+
},
|
|
148
|
+
// read binary
|
|
149
|
+
consume_BNUM() {
|
|
150
|
+
let ch;
|
|
151
|
+
while (this.offset < this.size) {
|
|
152
|
+
ch = this.input();
|
|
153
|
+
if (ch !== "0" && ch !== "1" && ch !== "_") {
|
|
154
|
+
if (ch) this.unput(1);
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return this.tok.T_LNUMBER;
|
|
159
|
+
},
|
|
160
|
+
// read an octal number
|
|
161
|
+
consume_ONUM() {
|
|
162
|
+
while (this.offset < this.size) {
|
|
163
|
+
const ch = this.input();
|
|
164
|
+
if (!this.is_OCTAL()) {
|
|
165
|
+
if (ch) this.unput(1);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return this.tok.T_LNUMBER;
|
|
170
|
+
},
|
|
171
|
+
};
|