Skip to content

Commit

Permalink
Updated readme. Fixes #8. Fixes #11.
Browse files Browse the repository at this point in the history
  • Loading branch information
rbuckton committed Oct 5, 2015
1 parent ca65af6 commit f4f2874
Showing 1 changed file with 98 additions and 13 deletions.
111 changes: 98 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Summary

`grammarkdown` is a markdown-style parser for syntactic grammars, designed to make it easily to rapidly prototype a grammar and statically verify its consistency.
`grammarkdown` is a markdown-style parser for syntactic grammars, designed to make it easily to rapidly prototype a grammar and statically verify its consistency.
The grammar supported by `grammarkdown` is based on the parametric grammar used by ECMA-262 (the JavaScript language standard).

## Usage
Expand All @@ -24,9 +24,11 @@ Options:

## Syntax

A `grammarkdown` grammar file uses significant whitespace in the form of line terminators and indentation. Tab (ASCII 0x9) characters are preferred,
A `grammarkdown` grammar file uses significant whitespace in the form of line terminators and indentation. Tab (ASCII 0x9) characters are preferred,
however using multiple spaces for indentation is supported as long as all nested elements have the same amount of leading whitespace.

#### Productions

A *Production* consists of a left-hand-side *Nonterminal* followed by a colon (`:`) separator and one or more *right-hand-side* sentances consisting of
various forms of *terminal* and *nonterminal* symbols. For example:

Expand Down Expand Up @@ -61,7 +63,24 @@ IdentifierReference[Yield] :
[~Yield] `yield`
```

If a *Nonterminal* on the right-hand-side of a production needs to set a parameter, they supply it in an argument list.
A *Production* may also specify a limited set of terminals, by using the `one of` keyphrase:

```
Keyword :: one of
`break` `do` `in` `typeof`
`case` `else` `instanceof` `var`
`catch` `export` `new` `void`
`class` `extends` `return` `while`
`const` `finally` `super` `with`
`continue` `for` `switch` `yield`
`debugger` `function` `this`
`default` `if` `throw`
`delete` `import` `try`
```

#### Parameters

If a *Nonterminal* on the right-hand-side of a production needs to set a parameter, they supply it in an argument list.
Supplying the name of the argument sets the parameter, prefixing the name with a question mark ('?) passes the current value of the parameter, and eliding the argument clears the parameter:

```
Expand All @@ -71,39 +90,105 @@ Declaration[Yield] :
LexicalDeclaration[In, ?Yield]
```

The right-hand-side of a *Production* consists of one or more *Terminal* or *Nonterminal* symbols, a sentance of *Prose*, or an *Assertion*.
The right-hand-side of a *Production* consists of one or more *Terminal* or *Nonterminal* symbols, a sentance of *Prose*, or an *Assertion*.

#### Terminals

A *Terminal* symbol can be one of the following:

* A literal string of one or more characters enclosed in backticks ('\`'). For example: `` `function` ``
* A sequence of three backtick characters, which denotes a backtick token. For example: `` ``` ``
* A unicode character literal enclosed in a leading less-than ('<') character and a trailing greater-than ('>') character. For example: `<TAB>`

A *Nonterminal* symbol is an identifier, followed by an optional argument list, and an optional question mark ('?'). The question mark changes the cardinality of the *Nonterminal* from "exactly one" to "zero or one".
#### Nonterminals

A *Nonterminal* symbol is an identifier, followed by an optional argument list, and an optional question mark ('?'). The question mark changes the cardinality of the *Nonterminal* from "exactly one" to "zero or one".
The identifier may optionally be enclosed in `|` characters, if it happens to collide with a keyword.

#### Character Literals and Ranges

Character literals may be specified using one of the following forms:

* An abbreviation for a Unicode Code point, of the form `<NBSP>`
* A Unicode code point, of the form `U+00A0`

Character ranges may be specified using the `through` keyword:

```
SourceCharacter but not one of `"` or `\` or U+0000 through U+001F
```

#### Prose

A sentance of *Prose* is a single line with a leading greater-than ('>') character. For example: `> any Unicode code point`

An *Assertion* is a zero-width assertion that must evaluate successfully for the *Production* to be considered.
*Assertions* are enclosed in a leading open bracket ('\[') character and a trailing close-bracket ('\]') character.
#### The `but not` Condition

The `but not` condition allows you to reference a production, excluding some part of that production. For example:

```
MultiLineNotAsteriskChar ::
SourceCharacter but not `*`
```

Here, *MultiLineNotAsteriskChar* may contain any alternative from *SourceCharacter*, except the terminal `` `*` ``.

#### The `one of` Condition

You can exclude multiple alternatives by including a list of symbols to exclude through the use of the `one of` keyphrase.
Each entry in the list is separated by `or`:

```
MultiLineNotForwardSlashOrAsteriskChar ::
SourceCharacter but not one of `/` or `*`
```

#### Assertions

An *Assertion* is a zero-width test that must evaluate successfully for the *Production* to be considered.
*Assertions* are enclosed in a leading open bracket ('\[') character and a trailing close-bracket ('\]') character.

The possible assertions include:

* The *empty assertion*, which matches exactly zero tokens: `[empty]`
* The *lookahead assertion*, which verifies the next tokens in the stream: ``[lookahead != `function`]``
* The *no-symbol-here assertion*, which verifies the next token is not the provided symbol: `[no LineTerminator here]`
* The *lexical-goal assertion*, which states that the current lexical goal is the supplied *Nonterminal*: `[lexical goal InputElementRegExp]`
* The *parameter assertion*, which states the supplied parameter to the current production is either set (using the plus ('+') character), or cleared (using the tilde ('~') character): `` [~Yield] `yield` ``
* The *parameter assertion*, which states the supplied parameter to the current production is either set (using the plus ('+') character), or cleared (using the tilde ('~') character): `` [~Yield] `yield` ``

A *lookahead assertion* has the following operators:

* The `!=` operator states the lookahead phrase is not matched: ``[lookahead != `function`]``
* The `==` operator states the lookahead phrase is matched: ``[lookahead == `class`]``
* The `<!` operator states that any matching phrase in the provided set is not matched: ``[lookahead <! { `{`, `function` }]``
* The `<!` operator states that any matching phrase in the provided set is not matched: ``[lookahead <! { `{`, `function` }]``
* The `<=` operator states that any matching phrase in the provided set is matched: ``[lookahead <- { `public`, `private` }]``

#### Linking

During emit, `grammarkdown` implicitly adds a generated name for each *Production* and *Right-hand side* that can be used to
link directly to the production using a URI fragment. You can explicitly set the name for a production by tagging it with a custom link name:

```
Declaration[Yield] :
HoistableDeclaration[?Yield] #declaration-hoistable
ClassDeclaration[?Yield] #declaration-class
LexicalDeclaration[In, ?Yield] #declaration-lexical
```

#### Comments

You can also annotate your grammar with C-style single-line and multi-line comments.

For a comprehensive example of `grammarkdown` syntax, you can brows the [full grammar for ECMA-262 version 2015 (ES6)](https://github.com/rbuckton/grammarkdown/blob/master/spec/es6.grammar).
#### Examples

For comprehensive examples of `grammarkdown` syntax and output, you can review the following samples:

* ECMA-262 version 2015 (ES6) Grammar
* [Plain-text](https://github.com/rbuckton/grammarkdown/blob/master/spec/es6.grammar)
* [HTML](https://rbuckton.github.io/grammarkdown/es6.html)
* TypeScript 1.5 Supplemental Grammar
* [Plain-text](https://github.com/rbuckton/grammarkdown/blob/master/spec/typescript.grammar)
* [HTML](https://rbuckton.github.io/grammarkdown/typescript.html)

## API

Expand All @@ -113,15 +198,15 @@ For a comprehensive example of `grammarkdown` syntax, you can brows the [full gr
var grammarkdown = require("grammarkdown")
, Grammar = grammarkdown.Grammar
, EmitFormat = grammarkdown.EmitFormat

var filename = "...";
var source = "...";
var output;

// parse
var grammar = new Grammar(
[filename],
{ format: EmitFormat.markdown },
[filename],
{ format: EmitFormat.markdown },
function () { return source; });

// bind (optional, bind happens automatically during check)
Expand Down

0 comments on commit f4f2874

Please sign in to comment.