-
Notifications
You must be signed in to change notification settings - Fork 202
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A template html to generate diagrams for grammars.
See included diagrams/readme.md for details. fixes #138
- Loading branch information
Shahar Soel
committed
Mar 12, 2016
1 parent
8bea15d
commit 0c9817a
Showing
13 changed files
with
1,397 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,7 @@ | |
"ignore": [ | ||
"**/*", | ||
"!release/*.*", | ||
"!diagrams/*.*", | ||
"!readme.md", | ||
"!LICENSE.txt" | ||
], | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
svg.railroad-diagram path { | ||
stroke-width: 3; | ||
stroke: black; | ||
fill: rgba(0, 0, 0, 0); | ||
} | ||
|
||
svg.railroad-diagram text { | ||
font: bold 14px monospace; | ||
text-anchor: middle; | ||
} | ||
|
||
svg.railroad-diagram text.label { | ||
text-anchor: start; | ||
} | ||
|
||
svg.railroad-diagram text.comment { | ||
font: italic 12px monospace; | ||
} | ||
|
||
svg.railroad-diagram g.non-terminal rect { | ||
fill: hsl(223, 100%, 83%); | ||
} | ||
|
||
svg.railroad-diagram rect { | ||
stroke-width: 3; | ||
stroke: black; | ||
fill: hsl(190, 100%, 83%); | ||
} | ||
|
||
.diagramHeader { | ||
display: inline-block; | ||
-webkit-touch-callout: default; | ||
-webkit-user-select: text; | ||
-khtml-user-select: text; | ||
-moz-user-select: text; | ||
-ms-user-select: text; | ||
user-select: text; | ||
font-weight: bold; | ||
font-family: monospace; | ||
font-size: 18px; | ||
margin-bottom: -8px; | ||
text-align: center; | ||
} | ||
|
||
.diagramHeaderDef { | ||
background-color: lightgreen; | ||
} | ||
|
||
svg.railroad-diagram text { | ||
-webkit-touch-callout: default; | ||
-webkit-user-select: text; | ||
-khtml-user-select: text; | ||
-moz-user-select: text; | ||
-ms-user-select: text; | ||
user-select: text; | ||
} | ||
|
||
svg.railroad-diagram g.non-terminal rect.diagramRectUsage { | ||
color: green; | ||
fill: yellow; | ||
stroke: 5; | ||
} | ||
|
||
svg.railroad-diagram g.terminal rect.diagramRectUsage { | ||
color: green; | ||
fill: yellow; | ||
stroke: 5; | ||
} | ||
|
||
div { | ||
-webkit-touch-callout: none; | ||
-webkit-user-select: none; | ||
-khtml-user-select: none; | ||
-moz-user-select: none; | ||
-ms-user-select: none; | ||
user-select: none; | ||
} | ||
|
||
svg { | ||
width: 100%; | ||
} | ||
|
||
svg.railroad-diagram g.non-terminal text { | ||
cursor: pointer; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<!DOCTYPE html> | ||
<meta charset="utf-8"> | ||
<style> | ||
body { | ||
background-color: hsl(30, 20%, 95%) | ||
} | ||
</style> | ||
|
||
<!-- references when running the sample html directly--> | ||
<link rel='stylesheet' href='diagrams.css'> | ||
<script src='vendor/railroad-diagrams.js'></script> | ||
<script src='../bin/chevrotain.js'></script> | ||
<script src='src/diagrams_builder.js'></script> | ||
<script src='src/diagrams_behavior.js'></script> | ||
<script src='src/main.js'></script> | ||
|
||
|
||
<!-- references when using npm and chevrotain is installed node_modules/chevrotain--> | ||
<!--<link rel='stylesheet' href='node_modules/chevrotain/diagrams/diagrams.css'>--> | ||
<!--<script src='node_modules/chevrotain/diagrams/vendor/railroad-diagrams.js'></script>--> | ||
<!--<script src='node_modules/chevrotain/bin/chevrotain.js'></script>--> | ||
<!--<script src='node_modules/chevrotain/diagrams/src/diagrams_builder.js'></script>--> | ||
<!--<script src='node_modules/chevrotain/diagrams/src/diagrams_behavior.js'></script>--> | ||
<!--<script src='node_modules/chevrotain/diagrams/src/main.js'></script>--> | ||
|
||
|
||
<!-- references when using bower and chevrotain is installed in bower_components/chevrotain--> | ||
<!--<link rel='stylesheet' href='bower_components/chevrotain/diagrams/diagrams.css'>--> | ||
<!--<script src='bower_components/chevrotain/diagrams/vendor/railroad-diagrams.js'></script>--> | ||
<!--<script src='bower_components/chevrotain/release/chevrotain.js'></script>--> | ||
<!--<script src='bower_components/chevrotain/diagrams/src/diagrams_builder.js'></script>--> | ||
<!--<script src='bower_components/chevrotain/diagrams/src/diagrams_behavior.js'></script>--> | ||
<!--<script src='bower_components/chevrotain/diagrams/src/main.js'></script>--> | ||
|
||
<body> | ||
<div id="diagrams" align="center"></div> | ||
|
||
<!-- TODO: The DUMMY_SAMPLE script should be replaced with your custom grammar script.--> | ||
<script src='sample/DUMMY_SAMPLE.js'></script> | ||
|
||
<script> | ||
// TODO: replace DUMMY_SAMPLE_PARSER initialization with your parser implementation | ||
var parserInstanceToDraw = new DUMMY_SAMPLE_PARSER([]); | ||
|
||
var diagramsDiv = document.getElementById("diagrams"); | ||
|
||
main.drawDiagramsFromParserInstance(parserInstanceToDraw, diagramsDiv) | ||
</script> | ||
</body> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
## Template for Generating Syntax Diagrams for a Grammar. | ||
|
||
It is often useful to visually inspect a grammar's syntax diagrams during development | ||
or for documentation purposes. | ||
|
||
This folder contains a template which can be easily modified to render and display | ||
A grammar as railroad syntax diagrams using the [railroad-diagrams](https://github.com/tabatkins/railroad-diagrams) | ||
library by @tabatkins. | ||
|
||
An example of the railroad diagrams can be found on the chevrotain [Playground](http://sap.github.io/chevrotain/playground/). | ||
|
||
|
||
### Features: | ||
* Highlight usages and definitions on mouse hover. | ||
* Scroll to definition of non-terminal on mouse click. | ||
|
||
|
||
### Usage Instructions: | ||
The template will runs as is, but it will render a sample grammar instead of your custom grammar. | ||
|
||
There are **only** three steps needed to render a custom grammar: | ||
1. Copy diagrams.html into a source controlled folder (root of your project is recommended). | ||
2. Modify the references to the resources in **root/diagrams.html** so they will still be valid. | ||
* For example, assuming chevrotain is installed to **node_modules/chevrotain**: | ||
```<script src='src/diagrams_builder.js'></script>``` should be change to: | ||
```<script src='node_modules/chevrotain/diagrams/src/diagrams_builder.js'></script>``` | ||
* For convenience the diagrams.html contains three blocks of references, comment/uncomment the relevant one for your needs. | ||
* Modifying the references is not mandatory, instead the whole diagrams directory may be copied. | ||
However this will automatic updates to those resources(npm update/bower update) | ||
3. Replace the two references to **DUMMY_SAMPLE** with script tags/logic that will load and initialize an instance of | ||
the custom Parser whose grammar should be rendered. | ||
|
||
[Example](https://github.com/SAP/chevrotain/blob/master/examples/typescript_ecma5/ecma5_diagrams.html) of a modified html with a custom grammar. | ||
Setup instructions to run that example can be found [here](https://github.com/SAP/chevrotain/blob/master/examples/typescript_ecma5/README.md). | ||
|
||
|
||
#### What about grammars written with commonjs (node.js) modules. | ||
Because The diagrams are rendered in a browser, it's implementation must be runnable in a browser. | ||
This means the commonjs code must be wrapped / transformed to be browser compatible. | ||
Some options to accomplish this: | ||
* [UMD](https://github.com/umdjs/umd) | ||
* [browserify](http://browserify.org/) | ||
* [webpack](https://webpack.github.io/) | ||
* [systemjs](https://github.com/systemjs/systemjs) | ||
|
||
|
||
#### What about grammars written with AMD (require.js) modules. | ||
All the sources used in the template are wrapped using the [UMD](https://github.com/umdjs/umd) pattern. | ||
Thus they are compatible with AMD modules. In such a case the html can be modified to load require.js and perform | ||
the grammar rendering in the require.js **data-main** script. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
// TODO: umd ? | ||
|
||
// ----------------- lexer ----------------- | ||
var extendToken = chevrotain.extendToken; | ||
var Lexer = chevrotain.Lexer; | ||
var Parser = chevrotain.Parser; | ||
|
||
// In ES6, custom inheritance implementation (such as 'extendToken(...)') can be replaced with simple "class X extends Y"... | ||
var True = extendToken("True", /true/); | ||
var False = extendToken("False", /false/); | ||
var Null = extendToken("Null", /null/); | ||
var LCurly = extendToken("LCurly", /{/); | ||
var RCurly = extendToken("RCurly", /}/); | ||
var LSquare = extendToken("LSquare", /\[/); | ||
var RSquare = extendToken("RSquare", /]/); | ||
var Comma = extendToken("Comma", /,/); | ||
var Colon = extendToken("Colon", /:/); | ||
var StringLiteral = extendToken("StringLiteral", /"(?:[^\\"]+|\\(?:[bfnrtv"\\/]|u[0-9a-fA-F]{4}))*"/); | ||
var NumberLiteral = extendToken("NumberLiteral", /-?(0|[1-9]\d*)(\.\d+)?([eE][+-]?\d+)?/); | ||
var WhiteSpace = extendToken("WhiteSpace", /\s+/); | ||
WhiteSpace.GROUP = Lexer.SKIPPED; // marking WhiteSpace as 'SKIPPED' makes the lexer skip it. | ||
|
||
var allTokens = [WhiteSpace, NumberLiteral, StringLiteral, LCurly, RCurly, LSquare, RSquare, Comma, Colon, True, False, Null]; | ||
var JsonLexer = new Lexer(allTokens); | ||
|
||
|
||
// ----------------- parser ----------------- | ||
|
||
function DUMMY_SAMPLE_PARSER(input) { | ||
// invoke super constructor | ||
Parser.call(this, input, allTokens); | ||
|
||
// not mandatory, using <$> (or any other sign) to reduce verbosity (this. this. this. this. .......) | ||
var $ = this; | ||
|
||
this.json = this.RULE("json", function () { | ||
// @formatter:off | ||
$.OR([ | ||
{ ALT: function () { $.SUBRULE($.object) }}, | ||
{ ALT: function () { $.SUBRULE($.array) }} | ||
]); | ||
// @formatter:on | ||
}); | ||
|
||
this.object = this.RULE("object", function () { | ||
$.CONSUME(LCurly); | ||
$.OPTION(function () { | ||
$.SUBRULE($.objectItem); | ||
$.MANY(function () { | ||
$.CONSUME(Comma); | ||
$.SUBRULE2($.objectItem); | ||
}); | ||
}); | ||
$.CONSUME(RCurly); | ||
}); | ||
|
||
this.objectItem = this.RULE("objectItem", function () { | ||
$.CONSUME(StringLiteral); | ||
$.CONSUME(Colon); | ||
$.SUBRULE($.value); | ||
}); | ||
|
||
this.array = this.RULE("array", function () { | ||
$.CONSUME(LSquare); | ||
$.OPTION(function () { | ||
$.SUBRULE($.value); | ||
$.MANY(function () { | ||
$.CONSUME(Comma); | ||
$.SUBRULE2($.value); | ||
}); | ||
}); | ||
$.CONSUME(RSquare); | ||
}); | ||
|
||
// @formatter:off | ||
this.value = this.RULE("value", function () { | ||
$.OR([ | ||
{ ALT: function () { $.CONSUME(StringLiteral) }}, | ||
{ ALT: function () { $.CONSUME(NumberLiteral) }}, | ||
{ ALT: function () { $.SUBRULE($.object) }}, | ||
{ ALT: function () { $.SUBRULE($.array) }}, | ||
{ ALT: function () { $.CONSUME(True) }}, | ||
{ ALT: function () { $.CONSUME(False) }}, | ||
{ ALT: function () { $.CONSUME(Null) }} | ||
], "a value"); | ||
}); | ||
// @formatter:on | ||
|
||
// very important to call this after all the rules have been defined. | ||
// otherwise the parser may not work correctly as it will lack information | ||
// derived during the self analysis phase. | ||
Parser.performSelfAnalysis(this); | ||
} | ||
|
||
// inheritance as implemented in javascript in the previous decade... :( | ||
DUMMY_SAMPLE_PARSER.prototype = Object.create(Parser.prototype); | ||
DUMMY_SAMPLE_PARSER.prototype.constructor = DUMMY_SAMPLE_PARSER; | ||
|
Oops, something went wrong.