283 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			283 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Acorn
 | ||
| 
 | ||
| A tiny, fast JavaScript parser written in JavaScript.
 | ||
| 
 | ||
| ## Community
 | ||
| 
 | ||
| Acorn is open source software released under an
 | ||
| [MIT license](https://github.com/acornjs/acorn/blob/master/acorn/LICENSE).
 | ||
| 
 | ||
| You are welcome to
 | ||
| [report bugs](https://github.com/acornjs/acorn/issues) or create pull
 | ||
| requests on [github](https://github.com/acornjs/acorn).
 | ||
| 
 | ||
| ## Installation
 | ||
| 
 | ||
| The easiest way to install acorn is from [`npm`](https://www.npmjs.com/):
 | ||
| 
 | ||
| ```sh
 | ||
| npm install acorn
 | ||
| ```
 | ||
| 
 | ||
| Alternately, you can download the source and build acorn yourself:
 | ||
| 
 | ||
| ```sh
 | ||
| git clone https://github.com/acornjs/acorn.git
 | ||
| cd acorn
 | ||
| npm install
 | ||
| ```
 | ||
| 
 | ||
| ## Interface
 | ||
| 
 | ||
| **parse**`(input, options)` is the main interface to the library. The
 | ||
| `input` parameter is a string, `options` must be an object setting
 | ||
| some of the options listed below. The return value will be an abstract
 | ||
| syntax tree object as specified by the [ESTree
 | ||
| spec](https://github.com/estree/estree).
 | ||
| 
 | ||
| ```javascript
 | ||
| let acorn = require("acorn");
 | ||
| console.log(acorn.parse("1 + 1", {ecmaVersion: 2020}));
 | ||
| ```
 | ||
| 
 | ||
| When encountering a syntax error, the parser will raise a
 | ||
| `SyntaxError` object with a meaningful message. The error object will
 | ||
| have a `pos` property that indicates the string offset at which the
 | ||
| error occurred, and a `loc` object that contains a `{line, column}`
 | ||
| object referring to that same position.
 | ||
| 
 | ||
| Options are provided by in a second argument, which should be an
 | ||
| object containing any of these fields (only `ecmaVersion` is
 | ||
| required):
 | ||
| 
 | ||
| - **ecmaVersion**: Indicates the ECMAScript version to parse. Can be a
 | ||
|   number, either in year (`2022`) or plain version number (`6`) form,
 | ||
|   or `"latest"` (the latest the library supports). This influences
 | ||
|   support for strict mode, the set of reserved words, and support for
 | ||
|   new syntax features.
 | ||
| 
 | ||
|   **NOTE**: Only 'stage 4' (finalized) ECMAScript features are being
 | ||
|   implemented by Acorn. Other proposed new features must be
 | ||
|   implemented through plugins.
 | ||
| 
 | ||
| - **sourceType**: Indicate the mode the code should be parsed in. Can be
 | ||
|   either `"script"` or `"module"`. This influences global strict mode
 | ||
|   and parsing of `import` and `export` declarations.
 | ||
| 
 | ||
|   **NOTE**: If set to `"module"`, then static `import` / `export` syntax
 | ||
|   will be valid, even if `ecmaVersion` is less than 6.
 | ||
| 
 | ||
| - **onInsertedSemicolon**: If given a callback, that callback will be
 | ||
|   called whenever a missing semicolon is inserted by the parser. The
 | ||
|   callback will be given the character offset of the point where the
 | ||
|   semicolon is inserted as argument, and if `locations` is on, also a
 | ||
|   `{line, column}` object representing this position.
 | ||
| 
 | ||
| - **onTrailingComma**: Like `onInsertedSemicolon`, but for trailing
 | ||
|   commas.
 | ||
| 
 | ||
| - **allowReserved**: If `false`, using a reserved word will generate
 | ||
|   an error. Defaults to `true` for `ecmaVersion` 3, `false` for higher
 | ||
|   versions. When given the value `"never"`, reserved words and
 | ||
|   keywords can also not be used as property names (as in Internet
 | ||
|   Explorer's old parser).
 | ||
| 
 | ||
| - **allowReturnOutsideFunction**: By default, a return statement at
 | ||
|   the top level raises an error. Set this to `true` to accept such
 | ||
|   code.
 | ||
| 
 | ||
| - **allowImportExportEverywhere**: By default, `import` and `export`
 | ||
|   declarations can only appear at a program's top level. Setting this
 | ||
|   option to `true` allows them anywhere where a statement is allowed,
 | ||
|   and also allows `import.meta` expressions to appear in scripts
 | ||
|   (when `sourceType` is not `"module"`).
 | ||
| 
 | ||
| - **allowAwaitOutsideFunction**: If `false`, `await` expressions can
 | ||
|   only appear inside `async` functions. Defaults to `true` in modules
 | ||
|   for `ecmaVersion` 2022 and later, `false` for lower versions.
 | ||
|   Setting this option to `true` allows to have top-level `await`
 | ||
|   expressions. They are still not allowed in non-`async` functions,
 | ||
|   though.
 | ||
| 
 | ||
| - **allowSuperOutsideMethod**: By default, `super` outside a method
 | ||
|   raises an error. Set this to `true` to accept such code.
 | ||
| 
 | ||
| - **allowHashBang**: When this is enabled, if the code starts with the
 | ||
|   characters `#!` (as in a shellscript), the first line will be
 | ||
|   treated as a comment. Defaults to true when `ecmaVersion` >= 2023.
 | ||
| 
 | ||
| - **checkPrivateFields**: By default, the parser will verify that
 | ||
|   private properties are only used in places where they are valid and
 | ||
|   have been declared. Set this to false to turn such checks off.
 | ||
| 
 | ||
| - **locations**: When `true`, each node has a `loc` object attached
 | ||
|   with `start` and `end` subobjects, each of which contains the
 | ||
|   one-based line and zero-based column numbers in `{line, column}`
 | ||
|   form. Default is `false`.
 | ||
| 
 | ||
| - **onToken**: If a function is passed for this option, each found
 | ||
|   token will be passed in same format as tokens returned from
 | ||
|   `tokenizer().getToken()`.
 | ||
| 
 | ||
|   If array is passed, each found token is pushed to it.
 | ||
| 
 | ||
|   Note that you are not allowed to call the parser from the
 | ||
|   callback—that will corrupt its internal state.
 | ||
| 
 | ||
| - **onComment**: If a function is passed for this option, whenever a
 | ||
|   comment is encountered the function will be called with the
 | ||
|   following parameters:
 | ||
| 
 | ||
|   - `block`: `true` if the comment is a block comment, false if it
 | ||
|     is a line comment.
 | ||
|   - `text`: The content of the comment.
 | ||
|   - `start`: Character offset of the start of the comment.
 | ||
|   - `end`: Character offset of the end of the comment.
 | ||
| 
 | ||
|   When the `locations` options is on, the `{line, column}` locations
 | ||
|   of the comment’s start and end are passed as two additional
 | ||
|   parameters.
 | ||
| 
 | ||
|   If array is passed for this option, each found comment is pushed
 | ||
|   to it as object in Esprima format:
 | ||
| 
 | ||
|   ```javascript
 | ||
|   {
 | ||
|     "type": "Line" | "Block",
 | ||
|     "value": "comment text",
 | ||
|     "start": Number,
 | ||
|     "end": Number,
 | ||
|     // If `locations` option is on:
 | ||
|     "loc": {
 | ||
|       "start": {line: Number, column: Number}
 | ||
|       "end": {line: Number, column: Number}
 | ||
|     },
 | ||
|     // If `ranges` option is on:
 | ||
|     "range": [Number, Number]
 | ||
|   }
 | ||
|   ```
 | ||
| 
 | ||
|   Note that you are not allowed to call the parser from the
 | ||
|   callback—that will corrupt its internal state.
 | ||
| 
 | ||
| - **ranges**: Nodes have their start and end characters offsets
 | ||
|   recorded in `start` and `end` properties (directly on the node,
 | ||
|   rather than the `loc` object, which holds line/column data. To also
 | ||
|   add a
 | ||
|   [semi-standardized](https://bugzilla.mozilla.org/show_bug.cgi?id=745678)
 | ||
|   `range` property holding a `[start, end]` array with the same
 | ||
|   numbers, set the `ranges` option to `true`.
 | ||
| 
 | ||
| - **program**: It is possible to parse multiple files into a single
 | ||
|   AST by passing the tree produced by parsing the first file as the
 | ||
|   `program` option in subsequent parses. This will add the toplevel
 | ||
|   forms of the parsed file to the "Program" (top) node of an existing
 | ||
|   parse tree.
 | ||
| 
 | ||
| - **sourceFile**: When the `locations` option is `true`, you can pass
 | ||
|   this option to add a `source` attribute in every node’s `loc`
 | ||
|   object. Note that the contents of this option are not examined or
 | ||
|   processed in any way; you are free to use whatever format you
 | ||
|   choose.
 | ||
| 
 | ||
| - **directSourceFile**: Like `sourceFile`, but a `sourceFile` property
 | ||
|   will be added (regardless of the `location` option) directly to the
 | ||
|   nodes, rather than the `loc` object.
 | ||
| 
 | ||
| - **preserveParens**: If this option is `true`, parenthesized expressions
 | ||
|   are represented by (non-standard) `ParenthesizedExpression` nodes
 | ||
|   that have a single `expression` property containing the expression
 | ||
|   inside parentheses.
 | ||
| 
 | ||
| **parseExpressionAt**`(input, offset, options)` will parse a single
 | ||
| expression in a string, and return its AST. It will not complain if
 | ||
| there is more of the string left after the expression.
 | ||
| 
 | ||
| **tokenizer**`(input, options)` returns an object with a `getToken`
 | ||
| method that can be called repeatedly to get the next token, a `{start,
 | ||
| end, type, value}` object (with added `loc` property when the
 | ||
| `locations` option is enabled and `range` property when the `ranges`
 | ||
| option is enabled). When the token's type is `tokTypes.eof`, you
 | ||
| should stop calling the method, since it will keep returning that same
 | ||
| token forever.
 | ||
| 
 | ||
| Note that tokenizing JavaScript without parsing it is, in modern
 | ||
| versions of the language, not really possible due to the way syntax is
 | ||
| overloaded in ways that can only be disambiguated by the parse
 | ||
| context. This package applies a bunch of heuristics to try and do a
 | ||
| reasonable job, but you are advised to use `parse` with the `onToken`
 | ||
| option instead of this.
 | ||
| 
 | ||
| In ES6 environment, returned result can be used as any other
 | ||
| protocol-compliant iterable:
 | ||
| 
 | ||
| ```javascript
 | ||
| for (let token of acorn.tokenizer(str)) {
 | ||
|   // iterate over the tokens
 | ||
| }
 | ||
| 
 | ||
| // transform code to array of tokens:
 | ||
| var tokens = [...acorn.tokenizer(str)];
 | ||
| ```
 | ||
| 
 | ||
| **tokTypes** holds an object mapping names to the token type objects
 | ||
| that end up in the `type` properties of tokens.
 | ||
| 
 | ||
| **getLineInfo**`(input, offset)` can be used to get a `{line,
 | ||
| column}` object for a given program string and offset.
 | ||
| 
 | ||
| ### The `Parser` class
 | ||
| 
 | ||
| Instances of the **`Parser`** class contain all the state and logic
 | ||
| that drives a parse. It has static methods `parse`,
 | ||
| `parseExpressionAt`, and `tokenizer` that match the top-level
 | ||
| functions by the same name.
 | ||
| 
 | ||
| When extending the parser with plugins, you need to call these methods
 | ||
| on the extended version of the class. To extend a parser with plugins,
 | ||
| you can use its static `extend` method.
 | ||
| 
 | ||
| ```javascript
 | ||
| var acorn = require("acorn");
 | ||
| var jsx = require("acorn-jsx");
 | ||
| var JSXParser = acorn.Parser.extend(jsx());
 | ||
| JSXParser.parse("foo(<bar/>)", {ecmaVersion: 2020});
 | ||
| ```
 | ||
| 
 | ||
| The `extend` method takes any number of plugin values, and returns a
 | ||
| new `Parser` class that includes the extra parser logic provided by
 | ||
| the plugins.
 | ||
| 
 | ||
| ## Command line interface
 | ||
| 
 | ||
| The `bin/acorn` utility can be used to parse a file from the command
 | ||
| line. It accepts as arguments its input file and the following
 | ||
| options:
 | ||
| 
 | ||
| - `--ecma3|--ecma5|--ecma6|--ecma7|--ecma8|--ecma9|--ecma10`: Sets the ECMAScript version
 | ||
|   to parse. Default is version 9.
 | ||
| 
 | ||
| - `--module`: Sets the parsing mode to `"module"`. Is set to `"script"` otherwise.
 | ||
| 
 | ||
| - `--locations`: Attaches a "loc" object to each node with "start" and
 | ||
|   "end" subobjects, each of which contains the one-based line and
 | ||
|   zero-based column numbers in `{line, column}` form.
 | ||
| 
 | ||
| - `--allow-hash-bang`: If the code starts with the characters #! (as
 | ||
|   in a shellscript), the first line will be treated as a comment.
 | ||
| 
 | ||
| - `--allow-await-outside-function`: Allows top-level `await` expressions.
 | ||
|   See the `allowAwaitOutsideFunction` option for more information.
 | ||
| 
 | ||
| - `--compact`: No whitespace is used in the AST output.
 | ||
| 
 | ||
| - `--silent`: Do not output the AST, just return the exit status.
 | ||
| 
 | ||
| - `--help`: Print the usage information and quit.
 | ||
| 
 | ||
| The utility spits out the syntax tree as JSON data.
 | ||
| 
 | ||
| ## Existing plugins
 | ||
| 
 | ||
|  - [`acorn-jsx`](https://github.com/RReverser/acorn-jsx): Parse [Facebook JSX syntax extensions](https://github.com/facebook/jsx)
 |