Fixed flowchart parsing (broken tests - grammar changes were not 100% correct)

This commit is contained in:
chris moran
2020-07-28 05:48:26 -04:00
parent 283faf7a2f
commit c9854b35e2

View File

@@ -6,8 +6,6 @@
/* lexical grammar */ /* lexical grammar */
%lex %lex
%options case-insensitive
%x string %x string
%x dir %x dir
%x vertex %x vertex
@@ -20,9 +18,9 @@
\%\%\{ { this.begin('open_directive'); return 'open_directive'; } \%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; } <open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; } <type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\%[^\n]* { this.popState(); this.popState(); return 'close_directive'; } <type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive'; <arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%%(?!\{)[^\n]* /* skip comments */ \%\%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */ [^\}]\%\%[^\n]* /* skip comments */
["] this.begin("string"); ["] this.begin("string");
<string>["] this.popState(); <string>["] this.popState();
@@ -38,7 +36,7 @@
"flowchart" {if(yy.lex.firstGraph()){this.begin("dir");} return 'GRAPH';} "flowchart" {if(yy.lex.firstGraph()){this.begin("dir");} return 'GRAPH';}
"subgraph" return 'subgraph'; "subgraph" return 'subgraph';
"end"\b\s* return 'end'; "end"\b\s* return 'end';
<dir>[^\n\s]* { this.popState(); } <dir>(\r?\n)*\s*\n { this.popState(); return 'NODIR'; }
<dir>\s*"LR" { this.popState(); return 'DIR'; } <dir>\s*"LR" { this.popState(); return 'DIR'; }
<dir>\s*"RL" { this.popState(); return 'DIR'; } <dir>\s*"RL" { this.popState(); return 'DIR'; }
<dir>\s*"TB" { this.popState(); return 'DIR'; } <dir>\s*"TB" { this.popState(); return 'DIR'; }
@@ -203,13 +201,38 @@
%left '^' %left '^'
%start mermaidDoc %start start
%% /* language grammar */ %% /* language grammar */
start
: mermaidDoc
| directive start
;
directive
: openDirective typeDirective closeDirective separator
| openDirective typeDirective ':' argDirective closeDirective separator
;
openDirective
: open_directive { yy.parseDirective('%%{', 'open_directive'); }
;
typeDirective
: type_directive { yy.parseDirective($1, 'type_directive'); }
;
argDirective
: arg_directive { $1 = $1.trim().replace(/'/g, '"'); yy.parseDirective($1, 'arg_directive'); }
;
closeDirective
: close_directive { yy.parseDirective('}%%', 'close_directive', 'flowchart'); }
;
mermaidDoc mermaidDoc
: graphConfig document : graphConfig document
| directive mermaidDoc
; ;
document document
@@ -224,25 +247,21 @@ document
; ;
line line
: statement {$$=$1;} : statement
{$$=$1;}
| SEMI | SEMI
| NEWLINE | NEWLINE
| SPACE | SPACE
| EOF | EOF
; ;
directive
: openDirective typeDirective closeDirective separator
| openDirective typeDirective ':' argDirective closeDirective separator
;
graphConfig graphConfig
: SPACE graphConfig : SPACE graphConfig
| NEWLINE graphConfig | NEWLINE graphConfig
| GRAPH FirstStmtSeperator | GRAPH NODIR
{ console.log('GRAPH FirstStmtSeperator');yy.setDirection('TB');$$ = 'TB';} { yy.setDirection('TB');$$ = 'TB';}
| GRAPH DIR FirstStmtSeperator | GRAPH DIR FirstStmtSeperator
{ console.log('GRAPH DIR FirstStmtSeperator');yy.setDirection($2);$$ = $2;} { yy.setDirection($2);$$ = $2;}
// | GRAPH SPACE TAGEND FirstStmtSeperator // | GRAPH SPACE TAGEND FirstStmtSeperator
// { yy.setDirection("LR");$$ = $3;} // { yy.setDirection("LR");$$ = $3;}
// | GRAPH SPACE TAGSTART FirstStmtSeperator // | GRAPH SPACE TAGSTART FirstStmtSeperator
@@ -297,7 +316,6 @@ statement
// {$$=yy.addSubGraph($3,$5,$3);} // {$$=yy.addSubGraph($3,$5,$3);}
| subgraph separator document end | subgraph separator document end
{$$=yy.addSubGraph(undefined,$3,undefined);} {$$=yy.addSubGraph(undefined,$3,undefined);}
| directive
; ;
separator: NEWLINE | SEMI | EOF ; separator: NEWLINE | SEMI | EOF ;
@@ -322,8 +340,8 @@ verticeStatement: verticeStatement link node
{ /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } } { /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
| verticeStatement link node spaceList | verticeStatement link node spaceList
{ /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } } { /* console.warn('vs',$1.stmt,$3); */ yy.addLink($1.stmt,$3,$2); $$ = { stmt: $3, nodes: $3.concat($1.nodes) } }
| node spaceList {/*console.warn('noda', $1);*/ $$ = {stmt: $1, nodes:$1 }} |node spaceList {/*console.warn('noda', $1);*/ $$ = {stmt: $1, nodes:$1 }}
| node { /*console.warn('noda', $1);*/ $$ = {stmt: $1, nodes:$1 }} |node { /*console.warn('noda', $1);*/ $$ = {stmt: $1, nodes:$1 }}
; ;
node: vertex node: vertex
@@ -370,7 +388,7 @@ vertex: idString SQS text SQE
link: linkStatement arrowText link: linkStatement arrowText
{$1.text = $2;$$ = $1;} {$1.text = $2;$$ = $1;}
| linkStatement STR SPACE | linkStatement TESTSTR SPACE
{$1.text = $2;$$ = $1;} {$1.text = $2;$$ = $1;}
| linkStatement arrowText SPACE | linkStatement arrowText SPACE
{$1.text = $2;$$ = $1;} {$1.text = $2;$$ = $1;}
@@ -389,16 +407,24 @@ arrowText:
{$$ = $2;} {$$ = $2;}
; ;
text: textToken {$$=$1;} text: textToken
| text textToken {$$=$1+''+$2;} {$$=$1;}
| text textToken
{$$=$1+''+$2;}
| STR
{$$=$1;}
; ;
keywords keywords
: STYLE | LINKSTYLE | CLASSDEF | CLASS | CLICK | GRAPH | DIR | subgraph | end | DOWN | UP; : STYLE | LINKSTYLE | CLASSDEF | CLASS | CLICK | GRAPH | DIR | subgraph | end | DOWN | UP;
textNoTags: textNoTagsToken {$$=$1;} textNoTags: textNoTagsToken
| textNoTags textNoTagsToken {$$=$1+''+$2;} {$$=$1;}
| textNoTags textNoTagsToken
{$$=$1+''+$2;}
; ;
@@ -440,42 +466,54 @@ linkStyleStatement
{$$ = $1;yy.updateLinkInterpolate($3,$7);} {$$ = $1;yy.updateLinkInterpolate($3,$7);}
; ;
numList numList: NUM
: NUM {$$ = [$1]} {$$ = [$1]}
| numList COMMA NUM {$1.push($3);$$ = $1;} | numList COMMA NUM
{$1.push($3);$$ = $1;}
; ;
stylesOpt: style {$$ = [$1]} stylesOpt: style
| stylesOpt COMMA style {$1.push($3);$$ = $1;} {$$ = [$1]}
| stylesOpt COMMA style
{$1.push($3);$$ = $1;}
; ;
style: styleComponent style: styleComponent
| style styleComponent {$$ = $1 + $2;} |style styleComponent
{$$ = $1 + $2;}
; ;
styleComponent: ALPHA | COLON | MINUS | NUM | UNIT | SPACE | HEX | BRKT | DOT | STYLE | PCT ; styleComponent: ALPHA | COLON | MINUS | NUM | UNIT | SPACE | HEX | BRKT | DOT | STYLE | PCT ;
/* Token lists */ /* Token lists */
textToken : textNoTagsToken | STR {$$=$1;} | TAGSTART | TAGEND | START_LINK | PCT | DEFAULT; textToken : textNoTagsToken | TAGSTART | TAGEND | START_LINK | PCT | DEFAULT;
textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ; textNoTagsToken: alphaNumToken | SPACE | MINUS | keywords ;
idString idString
: idStringToken {$$=$1} :idStringToken
| idString idStringToken {$$=$1+''+$2} {$$=$1}
| idString idStringToken
{$$=$1+''+$2}
; ;
alphaNum alphaNum
: alphaNumStatement {$$=$1;} : alphaNumStatement
| alphaNum alphaNumStatement {$$=$1+''+$2;} {$$=$1;}
| alphaNum alphaNumStatement
{$$=$1+''+$2;}
; ;
alphaNumStatement alphaNumStatement
: DIR {$$=$1;} : DIR
| alphaNumToken {$$=$1;} {$$=$1;}
| DOWN {$$='v';} | alphaNumToken
| MINUS {$$='-';} {$$=$1;}
| DOWN
{$$='v';}
| MINUS
{$$='-';}
; ;
alphaNumToken : PUNCTUATION | AMP | UNICODE_TEXT | NUM| ALPHA | COLON | COMMA | PLUS | EQUALS | MULT | DOT | BRKT| UNDERSCORE ; alphaNumToken : PUNCTUATION | AMP | UNICODE_TEXT | NUM| ALPHA | COLON | COMMA | PLUS | EQUALS | MULT | DOT | BRKT| UNDERSCORE ;
@@ -483,21 +521,4 @@ alphaNumToken : PUNCTUATION | AMP | UNICODE_TEXT | NUM| ALPHA | COLON | COMMA |
idStringToken : ALPHA|UNDERSCORE |UNICODE_TEXT | NUM| COLON | COMMA | PLUS | MINUS | DOWN |EQUALS | MULT | BRKT | DOT | PUNCTUATION | AMP; idStringToken : ALPHA|UNDERSCORE |UNICODE_TEXT | NUM| COLON | COMMA | PLUS | MINUS | DOWN |EQUALS | MULT | BRKT | DOT | PUNCTUATION | AMP;
graphCodeTokens: STADIUMSTART | STADIUMEND | SUBROUTINESTART | SUBROUTINEEND | CYLINDERSTART | CYLINDEREND | TRAPSTART | TRAPEND | INVTRAPSTART | INVTRAPEND | PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAGSTART | TAGEND | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI; graphCodeTokens: STADIUMSTART | STADIUMEND | SUBROUTINESTART | SUBROUTINEEND | CYLINDERSTART | CYLINDEREND | TRAPSTART | TRAPEND | INVTRAPSTART | INVTRAPEND | PIPE | PS | PE | SQS | SQE | DIAMOND_START | DIAMOND_STOP | TAGSTART | TAGEND | ARROW_CROSS | ARROW_POINT | ARROW_CIRCLE | ARROW_OPEN | QUOTE | SEMI;
openDirective
: open_directive { yy.parseDirective('%%{', 'open_directive'); }
;
typeDirective
: type_directive { yy.parseDirective($1, 'type_directive'); }
;
argDirective
: arg_directive { $1 = $1.trim().replace(/'/g, '"'); yy.parseDirective($1, 'arg_directive'); }
;
closeDirective
: close_directive { yy.parseDirective('}%%', 'close_directive', 'flowchart'); }
;
%% %%