Skip to content

Commit

Permalink
Add JSON Schema for describing AST, generated by the parser
Browse files Browse the repository at this point in the history
  • Loading branch information
Mingun committed Jul 8, 2017
1 parent 1afe682 commit a54b949
Show file tree
Hide file tree
Showing 3 changed files with 281 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
"babelify": "7.3.0",
"browserify": "13.1.0",
"chai": "3.5.0",
"chai-json-schema": "^1.4.0",
"del": "2.2.2",
"eslint-config-dmajda": "1.0.0",
"express": "4.14.0",
Expand Down
276 changes: 276 additions & 0 deletions src/ast.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,276 @@
{
"$schema": "http://json-schema.org/draft-04/schema#",

"type": "object",
"properties": {
"type": { "enum": ["grammar"] },
"location": { "$ref": "#/definitions/location" },
"initializer": {
"oneOf": [
{ "$ref": "#/definitions/initializer" },
{ "type": "null" }
]
},
"rules": {
"type": "array",
"items": { "$ref": "#/definitions/rule" }
}
},
"required": ["type", "rules"],

"definitions": {
"position": {
"type": "object",
"properties": {
"offset": { "type": "integer", "minimum": 0 },
"line": { "type": "integer", "minimum": 1 },
"column": { "type": "integer", "minimum": 1 }
},
"required": ["offset", "line", "column"]
},
"location": {
"type": "object",
"properties": {
"start": { "$ref": "#/definitions/position" },
"end": { "$ref": "#/definitions/position" }
},
"required": ["start", "end"]
},

"char": { "type": "string", "minLength": 1, "maxLength": 1 },
"chars": { "type": "array", "items": { "$ref": "#/definitions/char" } },

"expression": {
"oneOf": [
{ "$ref": "#/definitions/choice" },
{ "$ref": "#/definitions/action" },
{ "$ref": "#/definitions/sequence" },
{ "$ref": "#/definitions/labeled" },
{ "$ref": "#/definitions/text" },
{ "$ref": "#/definitions/simple_and" },
{ "$ref": "#/definitions/simple_not" },
{ "$ref": "#/definitions/optional" },
{ "$ref": "#/definitions/zero_or_more" },
{ "$ref": "#/definitions/one_or_more" },
{ "$ref": "#/definitions/group" },
{ "$ref": "#/definitions/semantic_and" },
{ "$ref": "#/definitions/semantic_not" },
{ "$ref": "#/definitions/rule_ref" },
{ "$ref": "#/definitions/literal" },
{ "$ref": "#/definitions/class" },
{ "$ref": "#/definitions/any" }
]
},

"initializer": {
"type": "object",
"properties": {
"type": { "enum": ["initializer"] },
"location": { "$ref": "#/definitions/location" },
"code": { "type": "string" }
},
"required": ["type", "code"]
},
"rule": {
"type": "object",
"properties": {
"type": { "enum": ["rule"] },
"location": { "$ref": "#/definitions/location" },
"name": { "type": "string" },
"expression": {
"oneOf": [
{ "$ref": "#/definitions/named" },
{ "$ref": "#/definitions/expression" }
]
}
},
"required": ["type", "name", "expression"]
},
"named": {
"type": "object",
"properties": {
"type": { "enum": ["named"] },
"location": { "$ref": "#/definitions/location" },
"name": { "type": "string" },
"expression": { "$ref": "#/definitions/expression" }
},
"required": ["type", "name", "expression"]
},

"choice": {
"type": "object",
"properties": {
"type": { "enum": ["choice"] },
"location": { "$ref": "#/definitions/location" },
"alternatives": {
"type": "array",
"title": "Варианты разбора",
"items": { "$ref": "#/definitions/expression" }
}
},
"required": ["type", "alternatives"]
},
"action": {
"type": "object",
"properties": {
"type": { "enum": ["action"] },
"location": { "$ref": "#/definitions/location" },
"expression": { "$ref": "#/definitions/expression" },
"code": { "type": "string" }
},
"required": ["type", "expression", "code"]
},
"sequence": {
"type": "object",
"properties": {
"type": { "enum": ["sequence"] },
"location": { "$ref": "#/definitions/location" },
"elements": {
"type": "array",
"title": "Варианты разбора",
"items": { "$ref": "#/definitions/expression" }
}
},
"required": ["type", "elements"]
},
"labeled": {
"type": "object",
"properties": {
"type": { "enum": ["labeled"] },
"location": { "$ref": "#/definitions/location" },
"expression": { "$ref": "#/definitions/expression" },
"label": { "type": "string" }
},
"required": ["type", "expression", "label"]
},
"text": {
"type": "object",
"properties": {
"type": { "enum": ["text"] },
"location": { "$ref": "#/definitions/location" },
"expression": { "$ref": "#/definitions/expression" }
},
"required": ["type", "expression"]
},
"simple_and": {
"type": "object",
"properties": {
"type": { "enum": ["simple_and"] },
"location": { "$ref": "#/definitions/location" },
"expression": { "$ref": "#/definitions/expression" }
},
"required": ["type", "expression"]
},
"simple_not": {
"type": "object",
"properties": {
"type": { "enum": ["simple_not"] },
"location": { "$ref": "#/definitions/location" },
"expression": { "$ref": "#/definitions/expression" }
},
"required": ["type", "expression"]
},
"optional": {
"type": "object",
"properties": {
"type": { "enum": ["optional"] },
"location": { "$ref": "#/definitions/location" },
"expression": { "$ref": "#/definitions/expression" }
},
"required": ["type", "expression"]
},
"zero_or_more": {
"type": "object",
"properties": {
"type": { "enum": ["zero_or_more"] },
"location": { "$ref": "#/definitions/location" },
"expression": { "$ref": "#/definitions/expression" }
},
"required": ["type", "expression"]
},
"one_or_more": {
"type": "object",
"properties": {
"type": { "enum": ["one_or_more"] },
"location": { "$ref": "#/definitions/location" },
"expression": { "$ref": "#/definitions/expression" }
},
"required": ["type", "expression"]
},
"group": {
"type": "object",
"properties": {
"type": { "enum": ["group"] },
"location": { "$ref": "#/definitions/location" },
"expression": { "$ref": "#/definitions/expression" }
},
"required": ["type", "expression"]
},
"semantic_and": {
"type": "object",
"properties": {
"type": { "enum": ["semantic_and"] },
"location": { "$ref": "#/definitions/location" },
"code": { "type": "string" }
},
"required": ["type", "code"]
},
"semantic_not": {
"type": "object",
"properties": {
"type": { "enum": ["semantic_not"] },
"location": { "$ref": "#/definitions/location" },
"code": { "type": "string" }
},
"required": ["type", "code"]
},
"rule_ref": {
"type": "object",
"properties": {
"type": { "enum": ["rule_ref"] },
"location": { "$ref": "#/definitions/location" },
"name": { "type": "string" }
},
"required": ["type", "name"]
},
"literal": {
"type": "object",
"properties": {
"type": { "enum": ["literal"] },
"location": { "$ref": "#/definitions/location" },
"value": { "type": "string" },
"ignoreCase": { "type": "boolean" },
"rawText": { "type": "string" }
},
"required": ["type", "value"]
},
"class": {
"type": "object",
"properties": {
"type": { "enum": ["class"] },
"location": { "$ref": "#/definitions/location" },
"parts": {
"type": "array",
"items": {
"oneOf": [
{ "$ref": "#/definitions/char" },
{ "$ref": "#/definitions/chars" }
]
}
},
"inverted": { "type": "boolean" },
"ignoreCase": { "type": "boolean" },
"rawText": { "type": "string" }
},
"required": ["type", "parts"]
},
"any": {
"type": "object",
"properties": {
"type": { "enum": ["any"] },
"location": { "$ref": "#/definitions/location" }
},
"required": ["type"]
}
}
}
4 changes: 4 additions & 0 deletions test/unit/parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

let chai = require("chai");
let parser = require("../../lib/parser");
let schema = require("../../src/ast.schema.json");

let expect = chai.expect;

Expand Down Expand Up @@ -172,6 +173,8 @@ describe("PEG.js grammar parser", function() {
Assertion.addMethod("parseAs", function(expected) {
let result = parser.parse(utils.flag(this, "object"));

new Assertion(result).to.be.jsonSchema(schema);

stripLocation(result);

this.assert(
Expand Down Expand Up @@ -221,6 +224,7 @@ describe("PEG.js grammar parser", function() {
// test/behavior/generated-parser-behavior.spec.js.
beforeEach(function() {
chai.use(helpers);
chai.use(require("chai-json-schema"));
});

// Canonical Grammar is "a = 'abcd'; b = 'efgh'; c = 'ijkl';".
Expand Down

1 comment on commit a54b949

@hildjj
Copy link

@hildjj hildjj commented on a54b949 Oct 4, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you're done with this, I can add --format json to the command line, if you like.

Please sign in to comment.