Clarify details for the execution environment for actions (#531)

* Clarify execution environment of actions and predicates
* Makes a new section for describing the common execution environment
* Add the new section to TOC
* Clarify start/end for predicates
* Clarify the scope of labels
master
felix 7 years ago committed by Futago-za Ryuu
parent ee00a1ae6a
commit 369b8cdcc6

@ -26,6 +26,7 @@ Table of Contents
* [Case-insensitivity](#case-insensitivity) * [Case-insensitivity](#case-insensitivity)
* [Backtracking](#backtracking) * [Backtracking](#backtracking)
* [Parsing Expression Types](#parsing-expression-types) * [Parsing Expression Types](#parsing-expression-types)
* [Action Execution Environment](#action-execution-environment)
- [Error Messages](#error-messages) - [Error Messages](#error-messages)
- [Compatibility](#compatibility) - [Compatibility](#compatibility)
- [Development](#development) - [Development](#development)
@ -430,69 +431,31 @@ Try to match the expression. If the match does not succeed, just return
#### & { *predicate* } #### & { *predicate* }
The predicate is a piece of JavaScript code that is executed as if it was inside This is a positive assertion. No input is consumed.
a function. It gets the match results of labeled expressions in preceding
expression as its arguments. It should return some JavaScript value using the
`return` statement. If the returned value evaluates to `true` in boolean
context, just return `undefined` and do not consume any input; otherwise
consider the match failed.
The code inside the predicate can access all variables and functions defined in
the initializer at the beginning of the grammar.
The code inside the predicate can also access location information using the
`location` function. It returns an object like this:
```javascript
{
start: { offset: 23, line: 5, column: 6 },
end: { offset: 23, line: 5, column: 6 }
}
```
The `start` and `end` properties both refer to the current parse position. The The predicate should be JavaScript code, and it's executed as a
`offset` property contains an offset as a zero-based index and `line` and function. Curly braces in the predicate must be balanced.
`column` properties contain a line and a column as one-based indices.
Line and column are somewhat expensive to compute, so if you just need the The predicate should `return` a boolean value. If the result is
offset, there's also a function `offset` that returns just the start offset, truthy, the match result is `undefined`, otherwise the match is
and a function `range` that returns the array `[start, end]` offsets. considered failed.
The code inside the predicate can also access options passed to the parser using The predicate has access to all variables and functions in the
the `options` variable. [Action Execution Environment](#action-execution-environment).
Note that curly braces in the predicate code must be balanced.
#### ! { *predicate* } #### ! { *predicate* }
The predicate is a piece of JavaScript code that is executed as if it was inside This is a negative assertion. No input is consumed.
a function. It gets the match results of labeled expressions in preceding
expression as its arguments. It should return some JavaScript value using the
`return` statement. If the returned value evaluates to `false` in boolean
context, just return `undefined` and do not consume any input; otherwise
consider the match failed.
The code inside the predicate can access all variables and functions defined in The predicate should be JavaScript code, and it's executed as a
the initializer at the beginning of the grammar. function. Curly braces in the predicate must be balanced.
The code inside the predicate can also access location information using the The predicate should `return` a boolean value. If the result is
`location` function. It returns an object like this: falsy, the match result is `undefined`, otherwise the match is
considered failed.
```javascript The predicate has access to all variables and functions in the
{ [Action Execution Environment](#action-execution-environment).
start: { offset: 23, line: 5, column: 6 },
end: { offset: 23, line: 5, column: 6 }
}
```
The `start` and `end` properties both refer to the current parse position. The
`offset` property contains an offset as a zero-based index and `line` and
`column` properties contain a line and a column as one-based indices.
The code inside the predicate can also access options passed to the parser using
the `options` variable.
Note that curly braces in the predicate code must be balanced.
#### $ *expression* #### $ *expression*
@ -513,60 +476,90 @@ Match a sequence of expressions and return their match results in an array.
#### *expression* { *action* } #### *expression* { *action* }
Match the expression. If the match is successful, run the action, otherwise If the expression matches successfully, run the action, otherwise
consider the match failed. consider the match failed.
The action is a piece of JavaScript code that is executed as if it was inside a The action should be JavaScript code, and it's executed as a
function. It gets the match results of labeled expressions in preceding function. Curly braces in the action must be balanced.
expression as its arguments. The action should return some JavaScript value
using the `return` statement. This value is considered match result of the
preceding expression.
To indicate an error, the code inside the action can invoke the `expected` The action should `return` some value, which will be used as the
function, which makes the parser throw an exception. The function takes two match result of the expression.
parameters — a description of what was expected at the current position and
optional location information (the default is what `location` would return — see
below). The description will be used as part of a message of the thrown
exception.
The code inside an action can also invoke the `error` function, which also makes The action has access to all variables and functions in the
the parser throw an exception. The function takes two parameters — an error [Action Execution Environment](#action-execution-environment).
message and optional location information (the default is what `location` would
return — see below). The message will be used by the thrown exception.
The code inside the action can access all variables and functions defined in the #### *expression<sub>1</sub>* / *expression<sub>2</sub>* / ... / *expression<sub>n</sub>*
initializer at the beginning of the grammar. Curly braces in the action code
must be balanced.
The code inside the action can also access the text matched by the expression Try to match the first expression, if it does not succeed, try the second one,
using the `text` function. etc. Return the match result of the first successfully matched expression. If no
expression matches, consider the match failed.
### Action Execution Environment
The code inside the action can also access location information using the Actions and predicates have these variables and functions
`location` function. It returns an object like this: available to them.
```javascript * All variables and functions defined in the initializer at the
{ beginning of the grammar are available.
* Labels from preceding expressions are available as local
variables, which will have the match result of the labelled
expressions.
A label is only available after its labelled expression is
matched:
```pegjs
rule = A:('a' B:'b' { /* B is available, A is not */ } )
```
A label in a sub-expression is only valid within the
sub-expression:
```pegjs
rule = A:'a' (B: 'b') (C: 'b' { /* A and C are available, B is not */ })
```
* `options` is a variable that contains the parser options.
* `error(message, where)` will report an error and throw an
exception. `where` is optional; the default is the value of
`location()`.
* `expected(message, where)` is similar to `error`, but reports
> Expected _message_ but "_other_" found.
* `location()` returns an object like this:
```javascript
{
start: { offset: 23, line: 5, column: 6 }, start: { offset: 23, line: 5, column: 6 },
end: { offset: 25, line: 5, column: 8 } end: { offset: 25, line: 5, column: 8 }
} }
``` ```
The `start` property refers to the position at the beginning of the expression, For actions, `start` refers to the position at the beginning of
the `end` property refers to position after the end of the expression. The the preceding expression, and `end` refers to the position
`offset` property contains an offset as a zero-based index and `line` and after the end of the preceding expression.
`column` properties contain a line and a column as one-based indices.
The code inside the action can also access options passed to the parser using For predicates, `start` and `end` are the same, the location
the `options` variable. where the predicate is evaluated.
Note that curly braces in the action code must be balanced. `offset` is a 0-based character index within the source text.
`line` and `column` are 1-based indices.
#### *expression<sub>1</sub>* / *expression<sub>2</sub>* / ... / *expression<sub>n</sub>* Note that `line` and `column` are somewhat expensive to
compute, so if you need location frequently, you might want to
use `offset()` or `range()` instead.
Try to match the first expression, if it does not succeed, try the second one, * `offset()` returns the start offset.
etc. Return the match result of the first successfully matched expression. If no
expression matches, consider the match failed. * `range()` returns an array containing the start and end
offsets, such as `[23, 25]`.
* `text()` returns the source text between `start` and `end`
(which will be "" for predicates).
Error Messages Error Messages
-------------- --------------

Loading…
Cancel
Save