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.

269 lines
10 KiB

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