From 9795b6e089c6dfeadfaccd2453a0659f77292b88 Mon Sep 17 00:00:00 2001 From: Thomas Di Cizerone Date: Sun, 23 Mar 2025 22:12:35 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=96=8B=EF=B8=8F=20Refactor=20common=20gra?= =?UTF-8?q?mmar=20to=20avoid=20unwanted=20greedy=20terminals?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/language/architecture/arch.langium | 2 + .../architecture/architecture.langium | 21 ++++---- .../parser/src/language/common/common.langium | 33 +++++++++---- .../src/language/gitGraph/gitGraph.langium | 49 ++++--------------- .../src/language/gitGraph/reference.langium | 4 ++ packages/parser/src/language/index.ts | 1 - .../parser/src/language/packet/packet.langium | 13 ++--- packages/parser/src/language/pie/pie.langium | 13 ++--- .../parser/src/language/radar/radar.langium | 40 ++------------- 9 files changed, 60 insertions(+), 116 deletions(-) create mode 100644 packages/parser/src/language/architecture/arch.langium create mode 100644 packages/parser/src/language/gitGraph/reference.langium diff --git a/packages/parser/src/language/architecture/arch.langium b/packages/parser/src/language/architecture/arch.langium new file mode 100644 index 000000000..7b3a2fe22 --- /dev/null +++ b/packages/parser/src/language/architecture/arch.langium @@ -0,0 +1,2 @@ +terminal ARCH_ICON: /\([\w-:]+\)/; +terminal ARCH_TITLE: /\[[\w ]+\]/; \ No newline at end of file diff --git a/packages/parser/src/language/architecture/architecture.langium b/packages/parser/src/language/architecture/architecture.langium index 11af26243..2e97372bd 100644 --- a/packages/parser/src/language/architecture/architecture.langium +++ b/packages/parser/src/language/architecture/architecture.langium @@ -1,14 +1,15 @@ grammar Architecture import "../common/common"; +import "arch"; entry Architecture: NEWLINE* "architecture-beta" ( - NEWLINE* TitleAndAccessibilities - | NEWLINE* Statement* - | NEWLINE* - ) + NEWLINE + | TitleAndAccessibilities + | Statement + )* ; fragment Statement: @@ -31,25 +32,21 @@ fragment Arrow: ; Group: - 'group' id=ARCH_ID icon=ARCH_ICON? title=ARCH_TITLE? ('in' in=ARCH_ID)? EOL + 'group' id=ID icon=ARCH_ICON? title=ARCH_TITLE? ('in' in=ID)? EOL ; Service: - 'service' id=ARCH_ID (iconText=ARCH_TEXT_ICON | icon=ARCH_ICON)? title=ARCH_TITLE? ('in' in=ARCH_ID)? EOL + 'service' id=ID (iconText=STRING | icon=ARCH_ICON)? title=ARCH_TITLE? ('in' in=ID)? EOL ; Junction: - 'junction' id=ARCH_ID ('in' in=ARCH_ID)? EOL + 'junction' id=ID ('in' in=ID)? EOL ; Edge: - lhsId=ARCH_ID lhsGroup?=ARROW_GROUP? Arrow rhsId=ARCH_ID rhsGroup?=ARROW_GROUP? EOL + lhsId=ID lhsGroup?=ARROW_GROUP? Arrow rhsId=ID rhsGroup?=ARROW_GROUP? EOL ; terminal ARROW_DIRECTION: 'L' | 'R' | 'T' | 'B'; -terminal ARCH_ID: /[\w]+/; -terminal ARCH_TEXT_ICON: /\("[^"]+"\)/; -terminal ARCH_ICON: /\([\w-:]+\)/; -terminal ARCH_TITLE: /\[[\w ]+\]/; terminal ARROW_GROUP: /\{group\}/; terminal ARROW_INTO: /<|>/; diff --git a/packages/parser/src/language/common/common.langium b/packages/parser/src/language/common/common.langium index 7989de193..e86fbadfe 100644 --- a/packages/parser/src/language/common/common.langium +++ b/packages/parser/src/language/common/common.langium @@ -1,22 +1,35 @@ -interface Common { - accDescr?: string; - accTitle?: string; - title?: string; -} - -fragment TitleAndAccessibilities: - ((accDescr=ACC_DESCR | accTitle=ACC_TITLE | title=TITLE) EOL)+ -; +// Base terminals and fragments for common language constructs +// Terminal Precedence: Lazy to Greedy +// When imported, the terminals are considered after the terminals in the importing grammar +// Note: Hence, to add a terminal greedier than the common terminals, import the common grammar first fragment EOL returns string: NEWLINE+ | EOF ; -terminal NEWLINE: /\r?\n/; +fragment TitleAndAccessibilities: + ((accDescr=ACC_DESCR | accTitle=ACC_TITLE | title=TITLE) EOL)+ +; + +terminal BOOLEAN returns boolean: 'true' | 'false'; + terminal ACC_DESCR: /[\t ]*accDescr(?:[\t ]*:([^\n\r]*?(?=%%)|[^\n\r]*)|\s*{([^}]*)})/; terminal ACC_TITLE: /[\t ]*accTitle[\t ]*:(?:[^\n\r]*?(?=%%)|[^\n\r]*)/; terminal TITLE: /[\t ]*title(?:[\t ][^\n\r]*?(?=%%)|[\t ][^\n\r]*|)/; +terminal FLOAT returns number: /[0-9]+\.[0-9]+(?!\.)/; +terminal INT returns number: /0|[1-9][0-9]*(?!\.)/; +terminal NUMBER returns number: FLOAT | INT; + +terminal STRING returns string: /"([^"\\]|\\.)*"|'([^'\\]|\\.)*'/; + +// Alphanumerics with underscores and dashes +// Must start with an alphanumeric or an underscore +// Cant end with a dash +terminal ID returns string: /[\w]([-\w]*\w)?/; + +terminal NEWLINE: /\r?\n/; + hidden terminal WHITESPACE: /[\t ]+/; hidden terminal YAML: /---[\t ]*\r?\n(?:[\S\s]*?\r?\n)?---(?:\r?\n|(?!\S))/; hidden terminal DIRECTIVE: /[\t ]*%%{[\S\s]*?}%%(?:\r?\n|(?!\S))/; diff --git a/packages/parser/src/language/gitGraph/gitGraph.langium b/packages/parser/src/language/gitGraph/gitGraph.langium index 1571ebba8..5a4b0596c 100644 --- a/packages/parser/src/language/gitGraph/gitGraph.langium +++ b/packages/parser/src/language/gitGraph/gitGraph.langium @@ -1,39 +1,15 @@ grammar GitGraph - -interface Common { - accDescr?: string; - accTitle?: string; - title?: string; -} - -fragment TitleAndAccessibilities: - ((accDescr=ACC_DESCR | accTitle=ACC_TITLE | title=TITLE) EOL)+ -; - -fragment EOL returns string: - NEWLINE+ | EOF -; - -terminal NEWLINE: /\r?\n/; -terminal ACC_DESCR: /[\t ]*accDescr(?:[\t ]*:([^\n\r]*?(?=%%)|[^\n\r]*)|\s*{([^}]*)})/; -terminal ACC_TITLE: /[\t ]*accTitle[\t ]*:(?:[^\n\r]*?(?=%%)|[^\n\r]*)/; -terminal TITLE: /[\t ]*title(?:[\t ][^\n\r]*?(?=%%)|[\t ][^\n\r]*|)/; - -hidden terminal WHITESPACE: /[\t ]+/; -hidden terminal YAML: /---[\t ]*\r?\n(?:[\S\s]*?\r?\n)?---(?:\r?\n|(?!\S))/; -hidden terminal DIRECTIVE: /[\t ]*%%{[\S\s]*?}%%(?:\r?\n|(?!\S))/; -hidden terminal SINGLE_LINE_COMMENT: /[\t ]*%%[^\n\r]*/; +import "../common/common"; +import "reference"; entry GitGraph: NEWLINE* ('gitGraph' | 'gitGraph' ':' | 'gitGraph:' | ('gitGraph' Direction ':')) - NEWLINE* ( - NEWLINE* - (TitleAndAccessibilities | - statements+=Statement | - NEWLINE)* - ) + NEWLINE + | TitleAndAccessibilities + | statements+=Statement + )* ; Statement @@ -56,12 +32,12 @@ Commit: |'type:' type=('NORMAL' | 'REVERSE' | 'HIGHLIGHT') )* EOL; Branch: - 'branch' name=(ID|STRING) + 'branch' name=(REFERENCE|STRING) ('order:' order=INT)? EOL; Merge: - 'merge' branch=(ID|STRING) + 'merge' branch=(REFERENCE|STRING) ( 'id:' id=STRING |'tag:' tags+=STRING @@ -69,7 +45,7 @@ Merge: )* EOL; Checkout: - ('checkout'|'switch') branch=(ID|STRING) EOL; + ('checkout'|'switch') branch=(REFERENCE|STRING) EOL; CherryPicking: 'cherry-pick' @@ -78,10 +54,3 @@ CherryPicking: |'tag:' tags+=STRING |'parent:' parent=STRING )* EOL; - - - -terminal INT returns number: /[0-9]+(?=\s)/; -terminal ID returns string: /\w([-\./\w]*[-\w])?/; -terminal STRING: /"[^"]*"|'[^']*'/; - diff --git a/packages/parser/src/language/gitGraph/reference.langium b/packages/parser/src/language/gitGraph/reference.langium new file mode 100644 index 000000000..6e1af5863 --- /dev/null +++ b/packages/parser/src/language/gitGraph/reference.langium @@ -0,0 +1,4 @@ +// Alphanumerics with underscores, dashes, slashes, and dots +// Must start with an alphanumeric or an underscore +// Cant end with a dash, slash, or dot +terminal REFERENCE returns string: /\w([-\./\w]*[-\w])?/; \ No newline at end of file diff --git a/packages/parser/src/language/index.ts b/packages/parser/src/language/index.ts index e3aa5c68c..aa0c0f703 100644 --- a/packages/parser/src/language/index.ts +++ b/packages/parser/src/language/index.ts @@ -12,7 +12,6 @@ export { Commit, Merge, Statement, - isCommon, isInfo, isPacket, isPacketBlock, diff --git a/packages/parser/src/language/packet/packet.langium b/packages/parser/src/language/packet/packet.langium index ad30f8df2..91d6501ed 100644 --- a/packages/parser/src/language/packet/packet.langium +++ b/packages/parser/src/language/packet/packet.langium @@ -5,15 +5,12 @@ entry Packet: NEWLINE* "packet-beta" ( - NEWLINE* TitleAndAccessibilities blocks+=PacketBlock* - | NEWLINE+ blocks+=PacketBlock+ - | NEWLINE* - ) + TitleAndAccessibilities + | blocks+=PacketBlock + | NEWLINE + )* ; PacketBlock: start=INT('-' end=INT)? ':' label=STRING EOL -; - -terminal INT returns number: /0|[1-9][0-9]*/; -terminal STRING: /"[^"]*"|'[^']*'/; +; \ No newline at end of file diff --git a/packages/parser/src/language/pie/pie.langium b/packages/parser/src/language/pie/pie.langium index 2bbf967e1..a80caa81f 100644 --- a/packages/parser/src/language/pie/pie.langium +++ b/packages/parser/src/language/pie/pie.langium @@ -5,15 +5,12 @@ entry Pie: NEWLINE* "pie" showData?="showData"? ( - NEWLINE* TitleAndAccessibilities sections+=PieSection* - | NEWLINE+ sections+=PieSection+ - | NEWLINE* - ) + TitleAndAccessibilities + | sections+=PieSection + | NEWLINE + )* ; PieSection: - label=PIE_SECTION_LABEL ":" value=PIE_SECTION_VALUE EOL + label=STRING ":" value=NUMBER EOL ; - -terminal PIE_SECTION_LABEL: /"[^"]+"/; -terminal PIE_SECTION_VALUE returns number: /(0|[1-9][0-9]*)(\.[0-9]+)?/; diff --git a/packages/parser/src/language/radar/radar.langium b/packages/parser/src/language/radar/radar.langium index f0ecd13cd..8aa9cb0ff 100644 --- a/packages/parser/src/language/radar/radar.langium +++ b/packages/parser/src/language/radar/radar.langium @@ -1,31 +1,5 @@ grammar Radar -// import "../common/common"; -// Note: The import statement breaks TitleAndAccessibilities probably because of terminal order definition -// TODO: May need to change the common.langium to fix this - -interface Common { - accDescr?: string; - accTitle?: string; - title?: string; -} - -fragment TitleAndAccessibilities: - ((accDescr=ACC_DESCR | accTitle=ACC_TITLE | title=TITLE) EOL)+ -; - -fragment EOL returns string: - NEWLINE+ | EOF -; - -terminal NEWLINE: /\r?\n/; -terminal ACC_DESCR: /[\t ]*accDescr(?:[\t ]*:([^\n\r]*?(?=%%)|[^\n\r]*)|\s*{([^}]*)})/; -terminal ACC_TITLE: /[\t ]*accTitle[\t ]*:(?:[^\n\r]*?(?=%%)|[^\n\r]*)/; -terminal TITLE: /[\t ]*title(?:[\t ][^\n\r]*?(?=%%)|[\t ][^\n\r]*|)/; - -hidden terminal WHITESPACE: /[\t ]+/; -hidden terminal YAML: /---[\t ]*\r?\n(?:[\S\s]*?\r?\n)?---(?:\r?\n|(?!\S))/; -hidden terminal DIRECTIVE: /[\t ]*%%{[\S\s]*?}%%(?:\r?\n|(?!\S))/; -hidden terminal SINGLE_LINE_COMMENT: /[\t ]*%%[^\n\r]*/; +import "../common/common"; entry Radar: NEWLINE* @@ -76,14 +50,6 @@ Option: | name='min' value=NUMBER | name='graticule' value=GRATICULE ) -; +; - -terminal NUMBER returns number: /(0|[1-9][0-9]*)(\.[0-9]+)?/; - -terminal BOOLEAN returns boolean: 'true' | 'false'; - -terminal GRATICULE returns string: 'circle' | 'polygon'; - -terminal ID returns string: /[a-zA-Z_][a-zA-Z0-9\-_]*/; -terminal STRING: /"[^"]*"|'[^']*'/; \ No newline at end of file +terminal GRATICULE returns string: 'circle' | 'polygon'; \ No newline at end of file