You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

270 lines
10 KiB

4 years ago
  1. # Acorn
  2. A tiny, fast JavaScript parser written in JavaScript.
  3. ## Community
  4. Acorn is open source software released under an
  5. [MIT license](https://github.com/acornjs/acorn/blob/master/acorn/LICENSE).
  6. You are welcome to
  7. [report bugs](https://github.com/acornjs/acorn/issues) or create pull
  8. requests on [github](https://github.com/acornjs/acorn). For questions
  9. and discussion, please use the
  10. [Tern discussion forum](https://discuss.ternjs.net).
  11. ## Installation
  12. The easiest way to install acorn is from [`npm`](https://www.npmjs.com/):
  13. ```sh
  14. npm install acorn
  15. ```
  16. Alternately, you can download the source and build acorn yourself:
  17. ```sh
  18. git clone https://github.com/acornjs/acorn.git
  19. cd acorn
  20. npm install
  21. ```
  22. ## Interface
  23. **parse**`(input, options)` is the main interface to the library. The
  24. `input` parameter is a string, `options` can be undefined or an object
  25. setting some of the options listed below. The return value will be an
  26. abstract syntax tree object as specified by the [ESTree
  27. spec](https://github.com/estree/estree).
  28. ```javascript
  29. let acorn = require("acorn");
  30. console.log(acorn.parse("1 + 1"));
  31. ```
  32. When encountering a syntax error, the parser will raise a
  33. `SyntaxError` object with a meaningful message. The error object will
  34. have a `pos` property that indicates the string offset at which the
  35. error occurred, and a `loc` object that contains a `{line, column}`
  36. object referring to that same position.
  37. Options can be provided by passing a second argument, which should be
  38. an object containing any of these fields:
  39. - **ecmaVersion**: Indicates the ECMAScript version to parse. Must be
  40. either 3, 5, 6 (2015), 7 (2016), 8 (2017), 9 (2018), 10 (2019) or 11
  41. (2020, partial support). This influences support for strict mode,
  42. the set of reserved words, and support for new syntax features.
  43. Default is 10.
  44. **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being
  45. implemented by Acorn. Other proposed new features can be implemented
  46. through plugins.
  47. - **sourceType**: Indicate the mode the code should be parsed in. Can be
  48. either `"script"` or `"module"`. This influences global strict mode
  49. and parsing of `import` and `export` declarations.
  50. **NOTE**: If set to `"module"`, then static `import` / `export` syntax
  51. will be valid, even if `ecmaVersion` is less than 6.
  52. - **onInsertedSemicolon**: If given a callback, that callback will be
  53. called whenever a missing semicolon is inserted by the parser. The
  54. callback will be given the character offset of the point where the
  55. semicolon is inserted as argument, and if `locations` is on, also a
  56. `{line, column}` object representing this position.
  57. - **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing
  58. commas.
  59. - **allowReserved**: If `false`, using a reserved word will generate
  60. an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher
  61. versions. When given the value `"never"`, reserved words and
  62. keywords can also not be used as property names (as in Internet
  63. Explorer's old parser).
  64. - **allowReturnOutsideFunction**: By default, a return statement at
  65. the top level raises an error. Set this to `true` to accept such
  66. code.
  67. - **allowImportExportEverywhere**: By default, `import` and `export`
  68. declarations can only appear at a program's top level. Setting this
  69. option to `true` allows them anywhere where a statement is allowed.
  70. - **allowAwaitOutsideFunction**: By default, `await` expressions can
  71. only appear inside `async` functions. Setting this option to
  72. `true` allows to have top-level `await` expressions. They are
  73. still not allowed in non-`async` functions, though.
  74. - **allowHashBang**: When this is enabled (off by default), if the
  75. code starts with the characters `#!` (as in a shellscript), the
  76. first line will be treated as a comment.
  77. - **locations**: When `true`, each node has a `loc` object attached
  78. with `start` and `end` subobjects, each of which contains the
  79. one-based line and zero-based column numbers in `{line, column}`
  80. form. Default is `false`.
  81. - **onToken**: If a function is passed for this option, each found
  82. token will be passed in same format as tokens returned from
  83. `tokenizer().getToken()`.
  84. If array is passed, each found token is pushed to it.
  85. Note that you are not allowed to call the parser from the
  86. callback—that will corrupt its internal state.
  87. - **onComment**: If a function is passed for this option, whenever a
  88. comment is encountered the function will be called with the
  89. following parameters:
  90. - `block`: `true` if the comment is a block comment, false if it
  91. is a line comment.
  92. - `text`: The content of the comment.
  93. - `start`: Character offset of the start of the comment.
  94. - `end`: Character offset of the end of the comment.
  95. When the `locations` options is on, the `{line, column}` locations
  96. of the comment’s start and end are passed as two additional
  97. parameters.
  98. If array is passed for this option, each found comment is pushed
  99. to it as object in Esprima format:
  100. ```javascript
  101. {
  102. "type": "Line" | "Block",
  103. "value": "comment text",
  104. "start": Number,
  105. "end": Number,
  106. // If `locations` option is on:
  107. "loc": {
  108. "start": {line: Number, column: Number}
  109. "end": {line: Number, column: Number}
  110. },
  111. // If `ranges` option is on:
  112. "range": [Number, Number]
  113. }
  114. ```
  115. Note that you are not allowed to call the parser from the
  116. callback—that will corrupt its internal state.
  117. - **ranges**: Nodes have their start and end characters offsets
  118. recorded in `start` and `end` properties (directly on the node,
  119. rather than the `loc` object, which holds line/column data. To also
  120. add a
  121. [semi-standardized](https://bugzilla.mozilla.org/show_bug.cgi?id=745678)
  122. `range` property holding a `[start, end]` array with the same
  123. numbers, set the `ranges` option to `true`.
  124. - **program**: It is possible to parse multiple files into a single
  125. AST by passing the tree produced by parsing the first file as the
  126. `program` option in subsequent parses. This will add the toplevel
  127. forms of the parsed file to the "Program" (top) node of an existing
  128. parse tree.
  129. - **sourceFile**: When the `locations` option is `true`, you can pass
  130. this option to add a `source` attribute in every node’s `loc`
  131. object. Note that the contents of this option are not examined or
  132. processed in any way; you are free to use whatever format you
  133. choose.
  134. - **directSourceFile**: Like `sourceFile`, but a `sourceFile` property
  135. will be added (regardless of the `location` option) directly to the
  136. nodes, rather than the `loc` object.
  137. - **preserveParens**: If this option is `true`, parenthesized expressions
  138. are represented by (non-standard) `ParenthesizedExpression` nodes
  139. that have a single `expression` property containing the expression
  140. inside parentheses.
  141. **parseExpressionAt**`(input, offset, options)` will parse a single
  142. expression in a string, and return its AST. It will not complain if
  143. there is more of the string left after the expression.
  144. **tokenizer**`(input, options)` returns an object with a `getToken`
  145. method that can be called repeatedly to get the next token, a `{start,
  146. end, type, value}` object (with added `loc` property when the
  147. `locations` option is enabled and `range` property when the `ranges`
  148. option is enabled). When the token's type is `tokTypes.eof`, you
  149. should stop calling the method, since it will keep returning that same
  150. token forever.
  151. In ES6 environment, returned result can be used as any other
  152. protocol-compliant iterable:
  153. ```javascript
  154. for (let token of acorn.tokenizer(str)) {
  155. // iterate over the tokens
  156. }
  157. // transform code to array of tokens:
  158. var tokens = [...acorn.tokenizer(str)];
  159. ```
  160. **tokTypes** holds an object mapping names to the token type objects
  161. that end up in the `type` properties of tokens.
  162. **getLineInfo**`(input, offset)` can be used to get a `{line,
  163. column}` object for a given program string and offset.
  164. ### The `Parser` class
  165. Instances of the **`Parser`** class contain all the state and logic
  166. that drives a parse. It has static methods `parse`,
  167. `parseExpressionAt`, and `tokenizer` that match the top-level
  168. functions by the same name.
  169. When extending the parser with plugins, you need to call these methods
  170. on the extended version of the class. To extend a parser with plugins,
  171. you can use its static `extend` method.
  172. ```javascript
  173. var acorn = require("acorn");
  174. var jsx = require("acorn-jsx");
  175. var JSXParser = acorn.Parser.extend(jsx());
  176. JSXParser.parse("foo(<bar/>)");
  177. ```
  178. The `extend` method takes any number of plugin values, and returns a
  179. new `Parser` class that includes the extra parser logic provided by
  180. the plugins.
  181. ## Command line interface
  182. The `bin/acorn` utility can be used to parse a file from the command
  183. line. It accepts as arguments its input file and the following
  184. options:
  185. - `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|--ecma10`: Sets the ECMAScript version
  186. to parse. Default is version 9.
  187. - `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise.
  188. - `--locations`: Attaches a "loc" object to each node with "start" and
  189. "end" subobjects, each of which contains the one-based line and
  190. zero-based column numbers in `{line, column}` form.
  191. - `--allow-hash-bang`: If the code starts with the characters #! (as
  192. in a shellscript), the first line will be treated as a comment.
  193. - `--compact`: No whitespace is used in the AST output.
  194. - `--silent`: Do not output the AST, just return the exit status.
  195. - `--help`: Print the usage information and quit.
  196. The utility spits out the syntax tree as JSON data.
  197. ## Existing plugins
  198. - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx)
  199. Plugins for ECMAScript proposals:
  200. - [`acorn-stage3`](https://github.com/acornjs/acorn-stage3): Parse most stage 3 proposals, bundling:
  201. - [`acorn-class-fields`](https://github.com/acornjs/acorn-class-fields): Parse [class fields proposal](https://github.com/tc39/proposal-class-fields)
  202. - [`acorn-import-meta`](https://github.com/acornjs/acorn-import-meta): Parse [import.meta proposal](https://github.com/tc39/proposal-import-meta)
  203. - [`acorn-numeric-separator`](https://github.com/acornjs/acorn-numeric-separator): Parse [numeric separator proposal](https://github.com/tc39/proposal-numeric-separator)
  204. - [`acorn-private-methods`](https://github.com/acornjs/acorn-private-methods): parse [private methods, getters and setters proposal](https://github.com/tc39/proposal-private-methods)n