Convert more test grammars from JSON to JS

This commit is contained in:
Max Brunsfeld 2021-11-19 10:35:53 -08:00
parent 67d58d3ca2
commit 52b4b65adc
14 changed files with 135 additions and 323 deletions

View file

@ -0,0 +1,14 @@
module.exports = grammar({
name: "external_extra_tokens",
externals: $ => [
$.comment
],
extras: $ => [/\s/, $.comment],
rules: {
assignment: $ => seq($.variable, '=', $.variable),
variable: $ => /[a-z]+/
}
})

View file

@ -1,25 +0,0 @@
{
"name": "external_extra_tokens",
"externals": [
{"type": "SYMBOL", "name": "comment"}
],
"extras": [
{"type": "PATTERN", "value": "\\s"},
{"type": "SYMBOL", "name": "comment"}
],
"rules": {
"assignment": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "variable"},
{"type": "STRING", "value": "="},
{"type": "SYMBOL", "name": "variable"}
]
},
"variable": {"type": "PATTERN", "value": "[a-z]+"}
}
}

View file

@ -0,0 +1,29 @@
// This grammar uses an external scanner to match special string literals,
// that track the nesting depth of parentheses, similar to Ruby's percent
// string literals.
module.exports = grammar({
name: "external_tokens",
externals: $ => [
$._percent_string,
$._percent_string_start,
$._percent_string_end,
],
extras: $ => [/\s/],
rules: {
expression: $ => choice($.string, $.sum, $.identifier),
sum: $ => prec.left(seq($.expression, '+', $.expression)),
string: $ => choice($._percent_string, seq(
$._percent_string_start,
$.expression,
$._percent_string_end,
)),
identifier: $ => /[a-z]+/
}
})

View file

@ -1,57 +0,0 @@
{
"name": "external_tokens",
"externals": [
{"type": "SYMBOL", "name": "_percent_string"},
{"type": "SYMBOL", "name": "_percent_string_start"},
{"type": "SYMBOL", "name": "_percent_string_end"}
],
"extras": [
{"type": "PATTERN", "value": "\\s"}
],
"rules": {
"expression": {
"type": "CHOICE",
"members": [
{"type": "SYMBOL", "name": "string"},
{"type": "SYMBOL", "name": "sum"},
{"type": "SYMBOL", "name": "identifier"}
]
},
"sum": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "expression"},
{"type": "STRING", "value": "+"},
{"type": "SYMBOL", "name": "expression"}
]
}
},
"string": {
"type": "CHOICE",
"members": [
{"type": "SYMBOL", "name": "_percent_string"},
{
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "_percent_string_start"},
{"type": "SYMBOL", "name": "expression"},
{"type": "SYMBOL", "name": "_percent_string_end"}
]
}
]
},
"identifier": {
"type": "PATTERN",
"value": "[a-z]+"
}
}
}

View file

@ -0,0 +1,15 @@
// This grammar has an "extra" rule, `comment`, that is a non-terminal.
module.exports = grammar({
name: "extra_non_terminals",
extras: $ => [
/\s/,
$.comment,
],
rules: {
module: $ => seq('a', 'b', 'c', 'd'),
comment: $ => seq('(', repeat(/[a-z]+/), ')'),
}
})

View file

@ -1,35 +0,0 @@
{
"name": "extra_non_terminals",
"extras": [
{"type": "PATTERN", "value": "\\s"},
{"type": "SYMBOL", "name": "comment"}
],
"rules": {
"module": {
"type": "SEQ",
"members": [
{"type": "STRING", "value": "a"},
{"type": "STRING", "value": "b"},
{"type": "STRING", "value": "c"},
{"type": "STRING", "value": "d"}
]
},
"comment": {
"type": "SEQ",
"members": [
{"type": "STRING", "value": "("},
{
"type": "REPEAT",
"content": {
"type": "PATTERN",
"value": "[a-z]+"
}
},
{"type": "STRING", "value": ")"}
]
}
}
}

View file

@ -0,0 +1,16 @@
// This grammar has a non-terminal extra rule `macro_statement` that contains
// child rules that are also used elsewhere in the grammar.
module.exports = grammar({
name: "extra_non_terminals_with_shared_rules",
extras: $ => [/\s+/, $.macro_statement],
rules: {
program: $ => repeat($.statement),
statement: $ => seq(repeat($.label_declaration), ';'),
macro_statement: $ => seq('%', $.statement),
label_declaration: $ => seq($.identifier, ':'),
identifier: $ => /[a-zA-Z]+/
}
})

View file

@ -1,68 +0,0 @@
{
"name": "extra_non_terminals_with_shared_rules",
"extras": [
{ "type": "PATTERN", "value": "\\s+" },
{ "type": "SYMBOL", "name": "macro_statement" }
],
"rules": {
"program": {
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "statement"
}
},
"statement": {
"type": "SEQ",
"members": [
{
"type": "REPEAT",
"content": {
"type": "SYMBOL",
"name": "label_declaration"
}
},
{
"type": "STRING",
"value": ";"
}
]
},
"macro_statement": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "%"
},
{
"type": "SYMBOL",
"name": "statement"
}
]
},
"label_declaration": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "identifier"
},
{
"type": "STRING",
"value": ":"
}
]
},
"identifier": {
"type": "PATTERN",
"value": "[a-zA-Z]+"
}
},
"conflicts": [],
"externals": [],
"inline": [],
"supertypes": []
}

View file

@ -0,0 +1,39 @@
// This grammar demonstrates the usage of the IMMEDIATE_TOKEN rule. It allows the parser to produce
// a different token based on whether or not there are `extras` preceding the token's main content.
// When there are *no* leading `extras`, an immediate token is preferred over a normal token which
// would otherwise match.
module.exports = grammar({
name: "immediate_tokens",
extras: $ => [/\s/],
rules: {
program: $ => $._expression,
_expression: $ => choice(
$.call,
$.infix,
$.prefix,
$.identifier,
),
call: $ => prec.left(-1, seq(
$._expression,
$._expression,
)),
prefix: $ => seq(
'::',
$.identifier,
),
infix: $ => seq(
$._expression,
token.immediate('::'),
$.identifier,
),
identifier: $ => /[a-z]+/
}
})

View file

@ -1,61 +0,0 @@
{
"name": "immediate_tokens",
"extras": [
{
"type": "PATTERN",
"value": "\\s"
}
],
"rules": {
"program": {"type": "SYMBOL", "name": "_expression"},
"_expression": {
"type": "CHOICE",
"members": [
{"type": "SYMBOL", "name": "call"},
{"type": "SYMBOL", "name": "infix"},
{"type": "SYMBOL", "name": "prefix"},
{"type": "SYMBOL", "name": "identifier"}
]
},
"call": {
"type": "PREC_LEFT",
"value": -1,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "_expression"},
{"type": "SYMBOL", "name": "_expression"}
]
}
},
"prefix": {
"type": "SEQ",
"members": [
{"type": "STRING", "value": "::"},
{"type": "SYMBOL", "name": "identifier"}
]
},
"infix": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "_expression"},
{
"type": "IMMEDIATE_TOKEN",
"content": {"type": "STRING", "value": "::"}
},
{"type": "SYMBOL", "name": "identifier"}
]
},
"identifier": {
"type": "PATTERN",
"value": "[a-z]+"
}
}
}

View file

@ -1 +0,0 @@
This grammar demonstrates the usage of the IMMEDIATE_TOKEN rule. It allows the parser to produce a different token based on whether or not there are `extras` preceding the token's main content. When there are *no* leading `extras`, an immediate token is preferred over a normal token which would otherwise match.

View file

@ -0,0 +1,22 @@
module.exports = grammar({
name: "inline_rules",
extras: $ => [/\s/],
inline: $ => [$.expression],
rules: {
program: $ => repeat1($.statement),
statement: $ => seq($.expression, ";"),
expression: $ => choice(
$.sum,
$.product,
$.number,
$.parenthesized_expression,
),
parenthesized_expression: $ => seq("(", $.expression, ")"),
sum: $ => prec.left(seq($.expression, "+", $.expression)),
product: $ => prec.left(2, seq($.expression, "*", $.expression)),
number: $ => /\d+/,
}
})

View file

@ -1,76 +0,0 @@
{
"name": "inline_rules",
"extras": [
{"type": "PATTERN", "value": "\\s"}
],
"inline": [
"expression"
],
"rules": {
"program": {
"type": "REPEAT1",
"content": {
"type": "SYMBOL",
"name": "statement"
}
},
"statement": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "expression"},
{"type": "STRING", "value": ";"}
]
},
"expression": {
"type": "CHOICE",
"members": [
{"type": "SYMBOL", "name": "sum"},
{"type": "SYMBOL", "name": "product"},
{"type": "SYMBOL", "name": "number"},
{"type": "SYMBOL", "name": "parenthesized_expression"}
]
},
"parenthesized_expression": {
"type": "SEQ",
"members": [
{"type": "STRING", "value": "("},
{"type": "SYMBOL", "name": "expression"},
{"type": "STRING", "value": ")"}
]
},
"sum": {
"type": "PREC_LEFT",
"value": 0,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "expression"},
{"type": "STRING", "value": "+"},
{"type": "SYMBOL", "name": "expression"}
]
}
},
"product": {
"type": "PREC_LEFT",
"value": 2,
"content": {
"type": "SEQ",
"members": [
{"type": "SYMBOL", "name": "expression"},
{"type": "STRING", "value": "*"},
{"type": "SYMBOL", "name": "expression"}
]
}
},
"number": {"type": "PATTERN", "value": "\\d+"}
}
}