diff --git a/examples/test.txt b/examples/test.txt index 82f991b..89752f0 100644 --- a/examples/test.txt +++ b/examples/test.txt @@ -1,6 +1,5 @@ - - -foo - -bar : Foo Bar; baz +foo -- bar +biz -> baz +biz <-> baz +biz <- baz diff --git a/grammar.js b/grammar.js index 6a514df..6a8a7da 100644 --- a/grammar.js +++ b/grammar.js @@ -1,11 +1,14 @@ +const spaces = repeat(" "); + module.exports = grammar({ name: "d2", - // TODO: handle empty lines extras: ($) => [], word: ($) => $._word, + conflicts: ($) => [[$.identifier], [$.arrow]], + rules: { source_file: ($) => repeat($._definition), @@ -14,8 +17,8 @@ module.exports = grammar({ connection: ($) => seq( - $.identifier, - repeat1(seq($.arrow, $.identifier)), + $._identifier, + repeat1(seq($._arrow, $._identifier)), optional( choice(seq($.dot, $._connection_attribute), seq($._colon, $.label)) ), @@ -24,16 +27,14 @@ module.exports = grammar({ shape: ($) => seq( - $.identifier, - repeat(seq($.dot, $.identifier)), + $._identifier, + repeat(seq($.dot, $._identifier)), optional( choice(seq($.dot, $._shape_attribute), seq($._colon, $.label)) ), $._end ), - identifier: ($) => $._identifier, - label: ($) => choice($.string, $._unquoted_string), attr_value: ($) => choice($.string, $._unquoted_string), @@ -93,36 +94,34 @@ module.exports = grammar({ _connection_attr_key: ($) => choice("source-arrowhead", "target-arrowhead"), - _identifier: ($) => - prec.right( - seq( - repeat(" "), - optional($._dash), - choice( - $._word, - repeat1(seq($._word, choice(repeat(" "), $._dash), $._word)) - ), - optional($._dash), - repeat(" ") - ) + _identifier: ($) => seq(spaces, $.identifier), + + identifier: ($) => + seq( + optional($._dash), + choice( + $._word, + repeat1(seq($._word, choice(spaces, $._dash), $._word)) + ), + optional($._dash) ), - _colon: ($) => seq(repeat(" "), ":", repeat(" ")), + _colon: ($) => seq(spaces, ":", spaces), - _word: ($) => /[\w\d]+/, + _arrow: ($) => seq(spaces, $.arrow), arrow: ($) => - prec.left( - choice( - seq("--", repeat($._dash)), - seq("<-", repeat($._dash)), - seq("<-", repeat($._dash), ">"), - seq(repeat($._dash), "->") - ) + choice( + seq("--", repeat($._dash)), + seq("<-", repeat($._dash)), + seq("<-", repeat($._dash), ">"), + seq(repeat($._dash), "->") ), _dash: ($) => token.immediate("-"), + dot: ($) => token.immediate("."), + _unquoted_string: ($) => token.immediate(/[^'"`\n;{]+/), string: ($) => @@ -132,9 +131,9 @@ module.exports = grammar({ seq("`", repeat(token.immediate(/[^`\n]+/)), "`") ), - _eof: ($) => choice("\n", "\0"), - _end: ($) => seq(repeat(" "), choice(";", $._eof)), + _word: ($) => /[\w\d]+/, - dot: ($) => ".", + _eof: ($) => choice("\n", "\0"), + _end: ($) => seq(spaces, choice(";", $._eof)), }, }); diff --git a/src/grammar.json b/src/grammar.json index 18f3f3f..7aaeacf 100644 --- a/src/grammar.json +++ b/src/grammar.json @@ -35,7 +35,7 @@ "members": [ { "type": "SYMBOL", - "name": "identifier" + "name": "_identifier" }, { "type": "REPEAT1", @@ -44,11 +44,11 @@ "members": [ { "type": "SYMBOL", - "name": "arrow" + "name": "_arrow" }, { "type": "SYMBOL", - "name": "identifier" + "name": "_identifier" } ] } @@ -103,7 +103,7 @@ "members": [ { "type": "SYMBOL", - "name": "identifier" + "name": "_identifier" }, { "type": "REPEAT", @@ -116,7 +116,7 @@ }, { "type": "SYMBOL", - "name": "identifier" + "name": "_identifier" } ] } @@ -166,10 +166,6 @@ } ] }, - "identifier": { - "type": "SYMBOL", - "name": "_identifier" - }, "label": { "type": "CHOICE", "members": [ @@ -414,92 +410,90 @@ ] }, "_identifier": { - "type": "PREC_RIGHT", - "value": 0, - "content": { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "STRING", - "value": " " - } - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_dash" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_word" - }, - { - "type": "REPEAT1", - "content": { - "type": "SEQ", - "members": [ - { - "type": "SYMBOL", - "name": "_word" - }, - { - "type": "CHOICE", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "STRING", - "value": " " - } - }, - { - "type": "SYMBOL", - "name": "_dash" - } - ] - }, - { - "type": "SYMBOL", - "name": "_word" - } - ] - } - } - ] - }, - { - "type": "CHOICE", - "members": [ - { - "type": "SYMBOL", - "name": "_dash" - }, - { - "type": "BLANK" - } - ] - }, - { - "type": "REPEAT", - "content": { - "type": "STRING", - "value": " " - } + "type": "SEQ", + "members": [ + { + "type": "REPEAT", + "content": { + "type": "STRING", + "value": " " } - ] - } + }, + { + "type": "SYMBOL", + "name": "identifier" + } + ] + }, + "identifier": { + "type": "SEQ", + "members": [ + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_dash" + }, + { + "type": "BLANK" + } + ] + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_word" + }, + { + "type": "REPEAT1", + "content": { + "type": "SEQ", + "members": [ + { + "type": "SYMBOL", + "name": "_word" + }, + { + "type": "CHOICE", + "members": [ + { + "type": "REPEAT", + "content": { + "type": "STRING", + "value": " " + } + }, + { + "type": "SYMBOL", + "name": "_dash" + } + ] + }, + { + "type": "SYMBOL", + "name": "_word" + } + ] + } + } + ] + }, + { + "type": "CHOICE", + "members": [ + { + "type": "SYMBOL", + "name": "_dash" + }, + { + "type": "BLANK" + } + ] + } + ] }, "_colon": { "type": "SEQ", @@ -524,86 +518,94 @@ } ] }, - "_word": { - "type": "PATTERN", - "value": "[\\w\\d]+" + "_arrow": { + "type": "SEQ", + "members": [ + { + "type": "REPEAT", + "content": { + "type": "STRING", + "value": " " + } + }, + { + "type": "SYMBOL", + "name": "arrow" + } + ] }, "arrow": { - "type": "PREC_LEFT", - "value": 0, - "content": { - "type": "CHOICE", - "members": [ - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "--" - }, - { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "_dash" - } + "type": "CHOICE", + "members": [ + { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "--" + }, + { + "type": "REPEAT", + "content": { + "type": "SYMBOL", + "name": "_dash" } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "<-" - }, - { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "_dash" - } + } + ] + }, + { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "<-" + }, + { + "type": "REPEAT", + "content": { + "type": "SYMBOL", + "name": "_dash" } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "STRING", - "value": "<-" - }, - { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "_dash" - } - }, - { - "type": "STRING", - "value": ">" + } + ] + }, + { + "type": "SEQ", + "members": [ + { + "type": "STRING", + "value": "<-" + }, + { + "type": "REPEAT", + "content": { + "type": "SYMBOL", + "name": "_dash" } - ] - }, - { - "type": "SEQ", - "members": [ - { - "type": "REPEAT", - "content": { - "type": "SYMBOL", - "name": "_dash" - } - }, - { - "type": "STRING", - "value": "->" + }, + { + "type": "STRING", + "value": ">" + } + ] + }, + { + "type": "SEQ", + "members": [ + { + "type": "REPEAT", + "content": { + "type": "SYMBOL", + "name": "_dash" } - ] - } - ] - } + }, + { + "type": "STRING", + "value": "->" + } + ] + } + ] }, "_dash": { "type": "IMMEDIATE_TOKEN", @@ -612,6 +614,13 @@ "value": "-" } }, + "dot": { + "type": "IMMEDIATE_TOKEN", + "content": { + "type": "STRING", + "value": "." + } + }, "_unquoted_string": { "type": "IMMEDIATE_TOKEN", "content": { @@ -693,6 +702,10 @@ } ] }, + "_word": { + "type": "PATTERN", + "value": "[\\w\\d]+" + }, "_eof": { "type": "CHOICE", "members": [ @@ -730,14 +743,17 @@ ] } ] - }, - "dot": { - "type": "STRING", - "value": "." } }, "extras": [], - "conflicts": [], + "conflicts": [ + [ + "identifier" + ], + [ + "arrow" + ] + ], "precedences": [], "externals": [], "inline": [], diff --git a/src/parser.c b/src/parser.c index f5c642d..e4c3729 100644 Binary files a/src/parser.c and b/src/parser.c differ