refactor: Remove directives from grammar

This commit is contained in:
Sidharth Vinod 2023-08-25 12:55:58 +05:30
parent f0883be0e3
commit 1e0918c2ff
No known key found for this signature in database
GPG Key ID: FB5CCD378D3907CD
14 changed files with 8 additions and 690 deletions

View File

@ -72,25 +72,16 @@
%x string_kv_key %x string_kv_key
%x string_kv_value %x string_kv_value
%x open_directive
%x type_directive
%x arg_directive
%x close_directive
%x acc_title %x acc_title
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
.*direction\s+TB[^\n]* return 'direction_tb'; .*direction\s+TB[^\n]* return 'direction_tb';
.*direction\s+BT[^\n]* return 'direction_bt'; .*direction\s+BT[^\n]* return 'direction_bt';
.*direction\s+RL[^\n]* return 'direction_rl'; .*direction\s+RL[^\n]* return 'direction_rl';
.*direction\s+LR[^\n]* return 'direction_lr'; .*direction\s+LR[^\n]* return 'direction_lr';
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
"title"\s[^#\n;]+ return 'title'; "title"\s[^#\n;]+ return 'title';
@ -207,7 +198,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
start start
: mermaidDoc : mermaidDoc
| direction | direction
| directive start
; ;
direction direction
@ -225,26 +215,6 @@ mermaidDoc
: graphConfig : graphConfig
; ;
directive
: openDirective typeDirective closeDirective NEWLINE
| openDirective typeDirective ':' argDirective closeDirective NEWLINE
;
openDirective
: open_directive { yy.parseDirective('%%{', 'open_directive'); }
;
typeDirective
: type_directive { }
;
argDirective
: arg_directive { $1 = $1.trim().replace(/'/g, '"'); yy.parseDirective($1, 'arg_directive'); }
;
closeDirective
: close_directive { yy.parseDirective('}%%', 'close_directive', 'c4Context'); }
;
graphConfig graphConfig
: C4_CONTEXT NEWLINE statements EOF {yy.setC4Type($1)} : C4_CONTEXT NEWLINE statements EOF {yy.setC4Type($1)}

View File

@ -13,9 +13,6 @@
%x href %x href
%x callback_name %x callback_name
%x callback_args %x callback_args
%x open_directive
%x type_directive
%x arg_directive
%x acc_title %x acc_title
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
@ -24,15 +21,10 @@
%x namespace %x namespace
%x namespace-body %x namespace-body
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
.*direction\s+TB[^\n]* return 'direction_tb'; .*direction\s+TB[^\n]* return 'direction_tb';
.*direction\s+BT[^\n]* return 'direction_bt'; .*direction\s+BT[^\n]* return 'direction_bt';
.*direction\s+RL[^\n]* return 'direction_rl'; .*direction\s+RL[^\n]* return 'direction_rl';
.*direction\s+LR[^\n]* return 'direction_lr'; .*direction\s+LR[^\n]* return 'direction_lr';
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%\%(?!\{)*[^\n]*(\r?\n?)+ /* skip comments */ \%\%(?!\{)*[^\n]*(\r?\n?)+ /* skip comments */
\%\%[^\n]*(\r?\n)* /* skip comments */ \%\%[^\n]*(\r?\n)* /* skip comments */
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; } accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
@ -220,7 +212,6 @@ line was introduced with 'click'.
start start
: mermaidDoc : mermaidDoc
| directive start
| statements | statements
; ;
@ -239,27 +230,6 @@ mermaidDoc
: graphConfig : graphConfig
; ;
directive
: openDirective typeDirective closeDirective NEWLINE
| openDirective typeDirective ':' argDirective closeDirective NEWLINE
;
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', 'class'); }
;
graphConfig graphConfig
: CLASS_DIAGRAM NEWLINE statements EOF : CLASS_DIAGRAM NEWLINE statements EOF
; ;

View File

@ -1,7 +1,7 @@
%lex %lex
%options case-insensitive %options case-insensitive
%x open_directive type_directive arg_directive block %x block
%x acc_title %x acc_title
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
@ -14,11 +14,6 @@ accDescr\s*":"\s* { this.begin("ac
accDescr\s*"{"\s* { this.begin("acc_descr_multiline");} accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
<acc_descr_multiline>[\}] { this.popState(); } <acc_descr_multiline>[\}] { this.popState(); }
<acc_descr_multiline>[^\}]* return "acc_descr_multiline_value"; <acc_descr_multiline>[^\}]* return "acc_descr_multiline_value";
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
[\n]+ return 'NEWLINE'; [\n]+ return 'NEWLINE';
\s+ /* skip whitespace */ \s+ /* skip whitespace */
[\s]+ return 'SPACE'; [\s]+ return 'SPACE';
@ -75,7 +70,6 @@ o\{ return 'ZERO_OR_MORE';
start start
: 'ER_DIAGRAM' document 'EOF' { /*console.log('finished parsing');*/ } : 'ER_DIAGRAM' document 'EOF' { /*console.log('finished parsing');*/ }
| directive start
; ;
document document
@ -90,14 +84,9 @@ line
| EOF { $$=[];} | EOF { $$=[];}
; ;
directive
: openDirective typeDirective closeDirective 'NEWLINE'
| openDirective typeDirective ':' argDirective closeDirective 'NEWLINE'
;
statement statement
: directive : entityName relSpec entityName ':' role
| entityName relSpec entityName ':' role
{ {
yy.addEntity($1); yy.addEntity($1);
yy.addEntity($3); yy.addEntity($3);
@ -185,20 +174,4 @@ role
| 'ALPHANUM' { $$ = $1; } | 'ALPHANUM' { $$ = $1; }
; ;
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', 'er'); }
;
%% %%

View File

@ -23,17 +23,8 @@
%x href %x href
%x callbackname %x callbackname
%x callbackargs %x callbackargs
%x open_directive
%x type_directive
%x arg_directive
%x close_directive
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; } accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; } <acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; } accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
@ -272,35 +263,10 @@ that id.
%% /* language grammar */ %% /* language grammar */
start 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($type_directive, 'type_directive'); }
;
argDirective
: arg_directive { $arg_directive = $arg_directive.trim().replace(/'/g, '"'); yy.parseDirective($arg_directive, 'arg_directive'); }
;
closeDirective
: close_directive { yy.parseDirective('}%%', 'close_directive', 'flowchart'); }
;
mermaidDoc
: graphConfig document : graphConfig document
; ;
document document
: /* empty */ : /* empty */
{ $$ = [];} { $$ = [];}

View File

@ -11,19 +11,11 @@
%x href %x href
%x callbackname %x callbackname
%x callbackargs %x callbackargs
%x open_directive
%x type_directive
%x arg_directive
%x close_directive
%x acc_title %x acc_title
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; } \%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; } accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; } <acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
@ -112,8 +104,7 @@ weekday\s+sunday return 'weekday_sunday'
%% /* language grammar */ %% /* language grammar */
start start
: directive start : gantt document 'EOF' { return $2; }
| gantt document 'EOF' { return $2; }
; ;
document document
@ -155,13 +146,8 @@ statement
| section { yy.addSection($1.substr(8));$$=$1.substr(8); } | section { yy.addSection($1.substr(8));$$=$1.substr(8); }
| clickStatement | clickStatement
| taskTxt taskData {yy.addTask($1,$2);$$='task';} | taskTxt taskData {yy.addTask($1,$2);$$='task';}
| directive
; ;
directive
: openDirective typeDirective closeDirective 'NL'
| openDirective typeDirective ':' argDirective closeDirective 'NL'
;
/* /*
click allows any combination of href and call. click allows any combination of href and call.
@ -192,20 +178,4 @@ clickStatementDebug
| click href {$$=$1 + ' ' + $2;} | click href {$$=$1 + ' ' + $2;}
; ;
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', 'gantt'); }
;
%% %%

View File

@ -1,288 +0,0 @@
// Todo reintroduce without cryptoRandomString
import gitGraphAst from './gitGraphAst';
import { parser } from './parser/gitGraph';
import randomString from 'crypto-random-string';
import cryptoRandomString from 'crypto-random-string';
jest.mock('crypto-random-string');
describe('when parsing a gitGraph', function() {
let randomNumber;
beforeEach(function() {
parser.yy = gitGraphAst;
parser.yy.clear();
randomNumber = 0;
cryptoRandomString.mockImplementation(() => {
randomNumber = randomNumber + 1;
return String(randomNumber);
});
});
afterEach(function() {
cryptoRandomString.mockReset();
});
it('should handle a gitGraph definition', function() {
const str = 'gitGraph:\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('master');
expect(parser.yy.getDirection()).toBe('LR');
expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
});
it('should handle a gitGraph definition with empty options', function() {
const str = 'gitGraph:\n' + 'options\n' + 'end\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(parser.yy.getOptions()).toEqual({});
expect(Object.keys(commits).length).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('master');
expect(parser.yy.getDirection()).toBe('LR');
expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
});
it('should handle a gitGraph definition with valid options', function() {
const str = 'gitGraph:\n' + 'options\n' + '{"key": "value"}\n' + 'end\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(parser.yy.getOptions()['key']).toBe('value');
expect(Object.keys(commits).length).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('master');
expect(parser.yy.getDirection()).toBe('LR');
expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
});
it('should not fail on a gitGraph with malformed json', function() {
const str = 'gitGraph:\n' + 'options\n' + '{"key": "value"\n' + 'end\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('master');
expect(parser.yy.getDirection()).toBe('LR');
expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
});
it('should handle set direction', function() {
const str = 'gitGraph BT:\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(1);
expect(parser.yy.getCurrentBranch()).toBe('master');
expect(parser.yy.getDirection()).toBe('BT');
expect(Object.keys(parser.yy.getBranches()).length).toBe(1);
});
it('should checkout a branch', function() {
const str = 'gitGraph:\n' + 'branch new\n' + 'checkout new\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(0);
expect(parser.yy.getCurrentBranch()).toBe('new');
});
it('should add commits to checked out branch', function() {
const str = 'gitGraph:\n' + 'branch new\n' + 'checkout new\n' + 'commit\n' + 'commit\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(2);
expect(parser.yy.getCurrentBranch()).toBe('new');
const branchCommit = parser.yy.getBranches()['new'];
expect(branchCommit).not.toBeNull();
expect(commits[branchCommit].parent).not.toBeNull();
});
it('should handle commit with args', function() {
const str = 'gitGraph:\n' + 'commit "a commit"\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(1);
const key = Object.keys(commits)[0];
expect(commits[key].message).toBe('a commit');
expect(parser.yy.getCurrentBranch()).toBe('master');
});
it('should reset a branch', function() {
const str =
'gitGraph:\n' +
'commit\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'reset master\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(3);
expect(parser.yy.getCurrentBranch()).toBe('newbranch');
expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master']);
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch']);
});
it('reset can take an argument', function() {
const str =
'gitGraph:\n' +
'commit\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'reset master^\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(3);
expect(parser.yy.getCurrentBranch()).toBe('newbranch');
const master = commits[parser.yy.getBranches()['master']];
expect(parser.yy.getHead().id).toEqual(master.parent);
});
it('should handle fast forwardable merges', function() {
const str =
'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'merge newbranch\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(3);
expect(parser.yy.getCurrentBranch()).toBe('master');
expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master']);
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch']);
});
it('should handle cases when merge is a noop', function() {
const str =
'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'merge master\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(3);
expect(parser.yy.getCurrentBranch()).toBe('newbranch');
expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master']);
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['newbranch']);
});
it('should handle merge with 2 parents', function() {
const str =
'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'commit\n' +
'merge newbranch\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(5);
expect(parser.yy.getCurrentBranch()).toBe('master');
expect(parser.yy.getBranches()['newbranch']).not.toEqual(parser.yy.getBranches()['master']);
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master']);
});
it('should handle ff merge when history walk has two parents (merge commit)', function() {
const str =
'gitGraph:\n' +
'commit\n' +
'branch newbranch\n' +
'checkout newbranch\n' +
'commit\n' +
'commit\n' +
'checkout master\n' +
'commit\n' +
'merge newbranch\n' +
'commit\n' +
'checkout newbranch\n' +
'merge master\n';
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits).length).toBe(6);
expect(parser.yy.getCurrentBranch()).toBe('newbranch');
expect(parser.yy.getBranches()['newbranch']).toEqual(parser.yy.getBranches()['master']);
expect(parser.yy.getHead().id).toEqual(parser.yy.getBranches()['master']);
parser.yy.prettyPrint();
});
it('should generate a secure random ID for commits', function() {
const str = 'gitGraph:\n' + 'commit\n' + 'commit\n';
const EXPECTED_LENGTH = 7;
const EXPECTED_CHARACTERS = '0123456789abcdef';
let idCount = 0;
randomString.mockImplementation(options => {
if (
options.length === EXPECTED_LENGTH &&
options.characters === EXPECTED_CHARACTERS &&
Object.keys(options).length === 2
) {
const id = `abcdef${idCount}`;
idCount += 1;
return id;
}
return 'unexpected-ID';
});
parser.parse(str);
const commits = parser.yy.getCommits();
expect(Object.keys(commits)).toEqual(['abcdef0', 'abcdef1']);
Object.keys(commits).forEach(key => {
expect(commits[key].id).toEqual(key);
});
});
it('should generate an array of known branches', function() {
const str =
'gitGraph:\n' +
'commit\n' +
'branch b1\n' +
'checkout b1\n' +
'commit\n' +
'commit\n' +
'branch b2\n';
parser.parse(str);
const branches = gitGraphAst.getBranchesAsObjArray();
expect(branches).toHaveLength(3);
expect(branches[0]).toHaveProperty('name', 'master');
expect(branches[1]).toHaveProperty('name', 'b1');
expect(branches[2]).toHaveProperty('name', 'b2');
});
});

View File

@ -9,10 +9,6 @@
%x string %x string
%x options %x options
%x open_directive
%x type_directive
%x arg_directive
%x close_directive
%x acc_title %x acc_title
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
@ -20,11 +16,6 @@
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; } accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
<acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; } <acc_title>(?!\n|;|#)*[^\n]* { this.popState(); return "acc_title_value"; }
accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; } accDescr\s*":"\s* { this.begin("acc_descr");return 'acc_descr'; }
@ -76,7 +67,6 @@ checkout(?=\s|$) return 'CHECKOUT';
start start
: eol start : eol start
| directive start
| GG document EOF{ return $3; } | GG document EOF{ return $3; }
| GG ':' document EOF{ return $3; } | GG ':' document EOF{ return $3; }
| GG DIR ':' document EOF {yy.setDirection($2); return $4;} | GG DIR ':' document EOF {yy.setDirection($2); return $4;}
@ -240,27 +230,6 @@ commitType
| HIGHLIGHT { $$=yy.commitType.HIGHLIGHT;} | HIGHLIGHT { $$=yy.commitType.HIGHLIGHT;}
; ;
directive
: openDirective typeDirective closeDirective
| openDirective typeDirective ':' argDirective closeDirective
;
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', 'gitGraph'); }
;
ref ref
: ID : ID
| STR | STR

View File

@ -8,19 +8,10 @@
%x string %x string
%x title %x title
%x open_directive
%x type_directive
%x arg_directive
%x close_directive
%x acc_title %x acc_title
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%\%(?!\{)[^\n]* /* skip comments */ \%\%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */{ /*console.log('');*/ } [^\}]\%\%[^\n]* /* skip comments */{ /*console.log('');*/ }
[\n\r]+ return 'NEWLINE'; [\n\r]+ return 'NEWLINE';
@ -52,7 +43,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
start start
: eol start : eol start
| directive start
| PIE document | PIE document
| PIE showData document {yy.setShowData(true);} | PIE showData document {yy.setShowData(true);}
; ;
@ -73,12 +63,6 @@ statement
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); } | acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | section {yy.addSection($1.substr(8));$$=$1.substr(8);} | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | section {yy.addSection($1.substr(8));$$=$1.substr(8);}
| directive
;
directive
: openDirective typeDirective closeDirective
| openDirective typeDirective ':' argDirective closeDirective
; ;
eol eol
@ -87,20 +71,4 @@ eol
| EOF | EOF
; ;
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', 'pie'); }
;
%% %%

View File

@ -5,10 +5,6 @@
%x string %x string
%x md_string %x md_string
%x title %x title
%x open_directive
%x type_directive
%x arg_directive
%x close_directive
%x acc_title %x acc_title
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
@ -16,11 +12,6 @@
%x point_x %x point_x
%x point_y %x point_y
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%\%(?!\{)[^\n]* /* skip comments */ \%\%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */ [^\}]\%\%[^\n]* /* skip comments */
[\n\r]+ return 'NEWLINE'; [\n\r]+ return 'NEWLINE';
@ -87,7 +78,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multiline");}
start start
: eol start : eol start
| SPACE start | SPACE start
| directive start
| QUADRANT document | QUADRANT document
; ;
@ -110,7 +100,6 @@ statement
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); } | acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | section {yy.addSection($1.substr(8));$$=$1.substr(8);} | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | section {yy.addSection($1.substr(8));$$=$1.substr(8);}
| directive
; ;
points points
@ -133,33 +122,12 @@ quadrantDetails
| QUADRANT_4 text {yy.setQuadrant4Text($2)} | QUADRANT_4 text {yy.setQuadrant4Text($2)}
; ;
directive
: openDirective typeDirective closeDirective
| openDirective typeDirective ':' argDirective closeDirective
;
eol eol
: NEWLINE : NEWLINE
| SEMI | SEMI
| EOF | EOF
; ;
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', 'quadrantChart'); }
;
text: alphaNumToken text: alphaNumToken
{ $$={text:$1, type: 'text'};} { $$={text:$1, type: 'text'};}
| text textNoTagsToken | text textNoTagsToken

View File

@ -9,19 +9,10 @@
%x string %x string
%x token %x token
%x unqString %x unqString
%x open_directive
%x type_directive
%x arg_directive
%x close_directive
%x acc_title %x acc_title
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
"title"\s[^#\n;]+ return 'title'; "title"\s[^#\n;]+ return 'title';
accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; } accTitle\s*":"\s* { this.begin("acc_title");return 'acc_title'; }
@ -99,23 +90,10 @@ start
| RD NEWLINE diagram EOF; | RD NEWLINE diagram EOF;
directive directive
: openDirective typeDirective closeDirective : acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
| openDirective typeDirective ':' argDirective closeDirective
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
; ;
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', 'pie'); };
diagram diagram
: /* empty */ { $$ = [] } : /* empty */ { $$ = [] }

View File

@ -16,22 +16,15 @@
// A special state for grabbing text up to the first comment/newline // A special state for grabbing text up to the first comment/newline
%x ID ALIAS LINE %x ID ALIAS LINE
// Directive states
%x open_directive type_directive arg_directive
%x acc_title %x acc_title
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
[\n]+ return 'NEWLINE'; [\n]+ return 'NEWLINE';
\s+ /* skip all whitespace */ \s+ /* skip all whitespace */
<ID,ALIAS,LINE>((?!\n)\s)+ /* skip same-line whitespace */ <ID,ALIAS,LINE>((?!\n)\s)+ /* skip same-line whitespace */
<INITIAL,ID,ALIAS,LINE,arg_directive,type_directive,open_directive>\#[^\n]* /* skip comments */ <INITIAL,ID,ALIAS,LINE>\#[^\n]* /* skip comments */
\%%(?!\{)[^\n]* /* skip comments */ \%%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */ [^\}]\%\%[^\n]* /* skip comments */
[0-9]+(?=[ \n]+) return 'NUM'; [0-9]+(?=[ \n]+) return 'NUM';
@ -106,7 +99,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
start start
: SPACE start : SPACE start
| NEWLINE start | NEWLINE start
| directive start
| SD document { yy.apply($2);return $2; } | SD document { yy.apply($2);return $2; }
; ;
@ -133,11 +125,6 @@ box_line
; ;
directive
: openDirective typeDirective closeDirective 'NEWLINE'
| openDirective typeDirective ':' argDirective closeDirective 'NEWLINE'
;
statement statement
: participant_statement : participant_statement
| 'create' participant_statement {$2.type='createParticipant'; $$=$2;} | 'create' participant_statement {$2.type='createParticipant'; $$=$2;}
@ -215,7 +202,6 @@ statement
$3.unshift({type: 'breakStart', breakText:yy.parseMessage($2), signalType: yy.LINETYPE.BREAK_START}); $3.unshift({type: 'breakStart', breakText:yy.parseMessage($2), signalType: yy.LINETYPE.BREAK_START});
$3.push({type: 'breakEnd', optText:yy.parseMessage($2), signalType: yy.LINETYPE.BREAK_END}); $3.push({type: 'breakEnd', optText:yy.parseMessage($2), signalType: yy.LINETYPE.BREAK_END});
$$=$3;} $$=$3;}
| directive
; ;
option_sections option_sections
@ -335,20 +321,4 @@ text2
: TXT {$$ = yy.parseMessage($1.trim().substring(1)) } : TXT {$$ = yy.parseMessage($1.trim().substring(1)) }
; ;
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', 'sequence'); }
;
%% %%

View File

@ -33,10 +33,6 @@
%x FLOATING_NOTE %x FLOATING_NOTE
%x FLOATING_NOTE_ID %x FLOATING_NOTE_ID
%x struct %x struct
%x open_directive
%x type_directive
%x arg_directive
%x close_directive
// A special state for grabbing text up to the first comment/newline // A special state for grabbing text up to the first comment/newline
%x LINE %x LINE
@ -50,18 +46,13 @@
.*direction\s+RL[^\n]* return 'direction_rl'; .*direction\s+RL[^\n]* return 'direction_rl';
.*direction\s+LR[^\n]* return 'direction_lr'; .*direction\s+LR[^\n]* return 'direction_lr';
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%\%(?!\{)[^\n]* /* skip comments */ \%\%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */{ /*console.log('Crap after close');*/ } [^\}]\%\%[^\n]* /* skip comments */{ /*console.log('Crap after close');*/ }
[\n]+ return 'NL'; [\n]+ return 'NL';
[\s]+ /* skip all whitespace */ [\s]+ /* skip all whitespace */
<ID,STATE,struct,LINE,open_directive,type_directive,arg_directive,close_directive>((?!\n)\s)+ /* skip same-line whitespace */ <ID,STATE,struct,LINE>((?!\n)\s)+ /* skip same-line whitespace */
<INITIAL,ID,STATE,struct,LINE,open_directive,type_directive,arg_directive,close_directive>\#[^\n]* /* skip comments */ <INITIAL,ID,STATE,struct,LINE>\#[^\n]* /* skip comments */
\%%[^\n]* /* skip comments */ \%%[^\n]* /* skip comments */
"scale"\s+ { this.pushState('SCALE'); /* console.log('Got scale', yytext);*/ return 'scale'; } "scale"\s+ { this.pushState('SCALE'); /* console.log('Got scale', yytext);*/ return 'scale'; }
<SCALE>\d+ return 'WIDTH'; <SCALE>\d+ return 'WIDTH';
@ -155,7 +146,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
start start
: SPACE start : SPACE start
| NL start | NL start
| directive start
| SD document { /* console.log('--> Root document', $2); */ yy.setRootDoc($2); return $2; } | SD document { /* console.log('--> Root document', $2); */ yy.setRootDoc($2); return $2; }
; ;
@ -241,7 +231,6 @@ statement
$$={ stmt: 'state', id: $3.trim(), note:{position: $2.trim(), text: $4.trim()}}; $$={ stmt: 'state', id: $3.trim(), note:{position: $2.trim(), text: $4.trim()}};
} }
| note NOTE_TEXT AS ID | note NOTE_TEXT AS ID
| directive
| direction | direction
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); } | acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
| acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); } | acc_descr acc_descr_value { $$=$2.trim();yy.setAccDescription($$); }
@ -264,10 +253,6 @@ cssClassStatement
} }
; ;
directive
: openDirective typeDirective closeDirective
| openDirective typeDirective ':' argDirective closeDirective
;
direction direction
: direction_tb : direction_tb
{ yy.setDirection('TB');$$={stmt:'dir', value:'TB'};} { yy.setDirection('TB');$$={stmt:'dir', value:'TB'};}
@ -308,20 +293,4 @@ notePosition
| right_of | right_of
; ;
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', 'state'); }
;
%% %%

View File

@ -9,17 +9,8 @@
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
// Directive states
%x open_directive type_directive arg_directive
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%%(?!\{)[^\n]* /* skip comments */ \%%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */ [^\}]\%\%[^\n]* /* skip comments */
[\n]+ return 'NEWLINE'; [\n]+ return 'NEWLINE';
@ -55,7 +46,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
start start
: timeline document 'EOF' { return $2; } : timeline document 'EOF' { return $2; }
| directive start
; ;
document document
@ -70,11 +60,6 @@ line
| EOF { $$=[];} | EOF { $$=[];}
; ;
directive
: openDirective typeDirective closeDirective 'NEWLINE'
| openDirective typeDirective ':' argDirective closeDirective 'NEWLINE'
;
statement statement
: title {yy.getCommonDb().setDiagramTitle($1.substr(6));$$=$1.substr(6);} : title {yy.getCommonDb().setDiagramTitle($1.substr(6));$$=$1.substr(6);}
| acc_title acc_title_value { $$=$2.trim();yy.getCommonDb().setAccTitle($$); } | acc_title acc_title_value { $$=$2.trim();yy.getCommonDb().setAccTitle($$); }
@ -83,7 +68,6 @@ statement
| section {yy.addSection($1.substr(8));$$=$1.substr(8);} | section {yy.addSection($1.substr(8));$$=$1.substr(8);}
| period_statement | period_statement
| event_statement | event_statement
| directive
; ;
period_statement period_statement
: period {yy.addTask($1,0,'');$$=$1;} : period {yy.addTask($1,0,'');$$=$1;}
@ -92,21 +76,4 @@ event_statement
: event {yy.addEvent($1.substr(2));$$=$1;} : event {yy.addEvent($1.substr(2));$$=$1;}
; ;
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', 'timeline'); }
;
%% %%

View File

@ -9,17 +9,8 @@
%x acc_descr %x acc_descr
%x acc_descr_multiline %x acc_descr_multiline
// Directive states
%x open_directive type_directive arg_directive
%% %%
\%\%\{ { this.begin('open_directive'); return 'open_directive'; }
<open_directive>((?:(?!\}\%\%)[^:.])*) { this.begin('type_directive'); return 'type_directive'; }
<type_directive>":" { this.popState(); this.begin('arg_directive'); return ':'; }
<type_directive,arg_directive>\}\%\% { this.popState(); this.popState(); return 'close_directive'; }
<arg_directive>((?:(?!\}\%\%).|\n)*) return 'arg_directive';
\%%(?!\{)[^\n]* /* skip comments */ \%%(?!\{)[^\n]* /* skip comments */
[^\}]\%\%[^\n]* /* skip comments */ [^\}]\%\%[^\n]* /* skip comments */
[\n]+ return 'NEWLINE'; [\n]+ return 'NEWLINE';
@ -52,7 +43,6 @@ accDescr\s*"{"\s* { this.begin("acc_descr_multili
start start
: journey document 'EOF' { return $2; } : journey document 'EOF' { return $2; }
| directive start
; ;
document document
@ -67,11 +57,6 @@ line
| EOF { $$=[];} | EOF { $$=[];}
; ;
directive
: openDirective typeDirective closeDirective 'NEWLINE'
| openDirective typeDirective ':' argDirective closeDirective 'NEWLINE'
;
statement statement
: title {yy.setDiagramTitle($1.substr(6));$$=$1.substr(6);} : title {yy.setDiagramTitle($1.substr(6));$$=$1.substr(6);}
| acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); } | acc_title acc_title_value { $$=$2.trim();yy.setAccTitle($$); }
@ -79,23 +64,6 @@ statement
| acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); } | acc_descr_multiline_value { $$=$1.trim();yy.setAccDescription($$); }
| section {yy.addSection($1.substr(8));$$=$1.substr(8);} | section {yy.addSection($1.substr(8));$$=$1.substr(8);}
| taskName taskData {yy.addTask($1, $2);$$='task';} | taskName taskData {yy.addTask($1, $2);$$='task';}
| directive
;
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', 'journey'); }
; ;
%% %%