First steps on work with sequence diagrams.

This commit is contained in:
knsv
2014-11-20 20:46:51 +01:00
parent 4c26ec7414
commit eac94e5370
11 changed files with 408 additions and 135 deletions

View File

@@ -17,11 +17,11 @@ gulp.task('jison', shell.task([
// 'jison src/parser/flow.jison -o src/parser/flow.js', // 'jison src/parser/flow.jison -o src/parser/flow.js',
])) ]))
gulp.task('jison2', shell.task([ gulp.task('jisonSd', shell.task([
'jison src/parser/flow.jison -o src/parser/flow.js', //'jison src/parser/flow.jison -o src/parser/flow.js',
'jison src/parser/sequence.jison -o src/parser/sequence.js', 'jison src/parser/sequence.jison -o src/parser/sequence.js'
'source scripts/compileFlow.sh' //'source scripts/compileFlow.sh'
])) ]));
gulp.task('distSlim', function() { gulp.task('distSlim', function() {
gulp.src(['./src/parser/flow.js','./src/graph.js','./src/main.js']) gulp.src(['./src/parser/flow.js','./src/graph.js','./src/main.js'])
@@ -44,3 +44,10 @@ gulp.task('dist', ['distSlim', 'distFull'], function() {
.pipe(concat('mermaid.full.min.js')) .pipe(concat('mermaid.full.min.js'))
.pipe(gulp.dest('./dist/')) .pipe(gulp.dest('./dist/'))
}); });
var jasmine = require('gulp-jasmine');
gulp.task('jasmine',['jison'], function () {
return gulp.src('src/parser/flow.spec.js')
.pipe(jasmine());
});

View File

@@ -19,6 +19,8 @@
"karma-requirejs": "~0.2.2", "karma-requirejs": "~0.2.2",
"gulp-concat": "~2.4.1", "gulp-concat": "~2.4.1",
"gulp-uglify": "~1.0.1", "gulp-uglify": "~1.0.1",
"gulp-ext-replace": "~0.1.0" "gulp-ext-replace": "~0.1.0",
"browserify": "~6.2.0",
"gulp-jasmine": "~1.0.1"
} }
} }

102
src/graphDb.js Normal file
View File

@@ -0,0 +1,102 @@
/**
* Created by knut on 14-11-03.
*/
var vertices = {};
var edges = [];
var direction;
/**
* Function called by parser when a node definition has been found
* @param id
* @param text
* @param type
* @param style
*/
exports.addVertex = function (id, text, type, style) {
console.log('Got node ' + id + ' ' + type + ' ' + text + ' styles: ' + JSON.stringify(style));
if (typeof vertices[id] === 'undefined') {
vertices[id] = {id: id, styles: []};
}
if (typeof text !== 'undefined') {
vertices[id].text = text;
}
if (typeof type !== 'undefined') {
vertices[id].type = type;
}
if (typeof style !== 'undefined') {
if (style !== null) {
style.forEach(function (s) {
vertices[id].styles.push(s);
});
}
}
};
/**
* Function called by parser when a link/edge definition has been found
* @param start
* @param end
* @param type
* @param linktext
*/
exports.addLink = function (start, end, type, linktext) {
var edge = {start: start, end: end, type: undefined, text: ''};
var linktext = type.text;
if (typeof linktext !== 'undefined') {
edge.text = linktext;
}
if (typeof type !== 'undefined') {
edge.type = type.type;
}
edges.push(edge);
};
/**
* Updates a link with a style
* @param pos
* @param style
*/
exports.updateLink = function (pos, style) {
var position = pos.substr(1);
edges[position].style = style;
};
/**
* Called by parser when a graph definition is found, stores the direction of the chart.
* @param dir
*/
exports.setDirection = function (dir) {
direction = dir;
};
exports.getDirection = function () {
return direction;
};
/**
* Retrieval function for fetching the found nodes after parsing has completed.
* @returns {{}|*|vertices}
*/
exports.getVertices = function () {
return vertices;
};
/**
* Retrieval function for fetching the found links after parsing has completed.
* @returns {{}|*|edges}
*/
exports.getEdges = function () {
return edges;
};
/**
* Clears the internal graph db so that a new graph can be parsed.
*/
exports.clear = function () {
vertices = {};
edges = [];
};
/**
*
* @returns {string}
*/
exports.defaultStyle = function () {
return "fill:#ffa;stroke: #f66; stroke-width: 3px; stroke-dasharray: 5, 5;fill:#ffa;stroke: #666;";
};

View File

@@ -1,14 +1,12 @@
var mermaid; var graph = require('./graphDb');
if (typeof mermaid === 'undefined') { var flow = require('./parser/flow');
mermaid = {}
}
/** /**
* Function that adds the vertices found in the graph definition to the graph to be rendered. * Function that adds the vertices found in the graph definition to the graph to be rendered.
* @param vert Object containing the vertices. * @param vert Object containing the vertices.
* @param g The graph that is to be drawn. * @param g The graph that is to be drawn.
*/ */
mermaid.addVertices = function (vert, g) { var addVertices = function (vert, g) {
var keys = Object.keys(vert); var keys = Object.keys(vert);
// Iterate through each item in the vertice object (containing all the vertices found) in the graph definition // Iterate through each item in the vertice object (containing all the vertices found) in the graph definition
@@ -51,7 +49,7 @@ mermaid.addVertices = function (vert, g) {
* @param edges * @param edges
* @param g * @param g
*/ */
mermaid.addEdges = function (edges, g) { var addEdges = function (edges, g) {
edges.forEach(function (edge) { edges.forEach(function (edge) {
// Set link type for rendering // Set link type for rendering
@@ -89,16 +87,16 @@ mermaid.addEdges = function (edges, g) {
* @param text * @param text
* @param id * @param id
*/ */
mermaid.drawChart = function (text, id) { var drawChart = function (text, id) {
mermaid.graph.clear(); graph.clear();
parser.yy = mermaid.graph; flow.parser.yy = graph;
// Parse the graph definition // Parse the graph definition
parser.parse(text); flow.parser.parse(text);
// Fetch the default direction, use TD if none was found // Fetch the default direction, use TD if none was found
var dir; var dir;
dir = mermaid.direction; dir = graph.getDirection();
if(typeof dir === 'undefined'){ if(typeof dir === 'undefined'){
dir='TD'; dir='TD';
} }
@@ -115,11 +113,11 @@ mermaid.drawChart = function (text, id) {
}); });
// Fetch the verices/nodes and edges/links from the parsed graph definition // Fetch the verices/nodes and edges/links from the parsed graph definition
var vert = mermaid.graph.getVertices(); var vert = graph.getVertices();
var edges = mermaid.graph.getEdges(); var edges = graph.getEdges();
this.addVertices(vert, g); addVertices(vert, g);
this.addEdges(edges, g); addEdges(edges, g);
// Create the renderer // Create the renderer
var render = new dagreD3.render(); var render = new dagreD3.render();
@@ -182,7 +180,7 @@ mermaid.drawChart = function (text, id) {
/** /**
* Go through the document and find the chart definitions in there and render the charts * Go through the document and find the chart definitions in there and render the charts
*/ */
mermaid.init = function () { var init = function () {
var arr = document.querySelectorAll('.mermaid'); var arr = document.querySelectorAll('.mermaid');
var cnt = 0; var cnt = 0;
@@ -199,7 +197,7 @@ mermaid.init = function () {
'<g />' + '<g />' +
'</svg>'; '</svg>';
this.drawChart(chartText, id); drawChart(chartText, id);
} }
; ;
}; };
@@ -208,12 +206,12 @@ mermaid.init = function () {
* Version management * Version management
* @returns {string} * @returns {string}
*/ */
mermaid.version = function(){ exports.version = function(){
return '0.1.1'; return '0.2.0';
} }
/** /**
* Wait for coument loaded before starting the execution * Wait for coument loaded before starting the execution
*/ */
document.addEventListener('DOMContentLoaded', function(){ document.addEventListener('DOMContentLoaded', function(){
mermaid.init(); init();
}, false); }, false);

View File

@@ -1,22 +1,26 @@
/** /**
* Created by knut on 14-11-03. * Created by knut on 14-11-03.
*/ */
var graph = require('../graphDb');
var flow = require('./flow');
describe('when parsing ',function(){ describe('when parsing ',function(){
beforeEach(function(){ beforeEach(function(){
mermaid.graph.clear(); flow.parser.yy = require('../graphDb');
parser.yy = mermaid.graph; flow.parser.yy.clear();
/*parser.parse.parseError= function parseError(str, hash) { /*flow.parser.parse.parseError= function parseError(str, hash) {
console.log(str); console.log(str);
}*/ }*/
console.log('in mm spec'); console.log('in mm spec');
}); });
it('should handle a nodes and edges',function(){ it('should handle a nodes and edges',function(){
var res = parser.parse('graph TD;A-->B;'); var res = flow.parser.parse('graph TD;A-->B;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['A'].id).toBe('A'); expect(vert['A'].id).toBe('A');
expect(vert['B'].id).toBe('B'); expect(vert['B'].id).toBe('B');
@@ -28,60 +32,60 @@ describe('when parsing ',function(){
}); });
it('should handle open ended edges',function(){ it('should handle open ended edges',function(){
var res = parser.parse('graph TD;A---B;'); var res = flow.parser.parse('graph TD;A---B;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow_open'); expect(edges[0].type).toBe('arrow_open');
}); });
it('should handle cross ended edges',function(){ it('should handle cross ended edges',function(){
var res = parser.parse('graph TD;A--xB;'); var res = flow.parser.parse('graph TD;A--xB;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow_cross'); expect(edges[0].type).toBe('arrow_cross');
}); });
it('should handle open ended edges',function(){ it('should handle open ended edges',function(){
var res = parser.parse('graph TD;A--oB;'); var res = flow.parser.parse('graph TD;A--oB;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow_circle'); expect(edges[0].type).toBe('arrow_circle');
}); });
it('should handle text on edges without space',function(){ it('should handle text on edges without space',function(){
var res = parser.parse('graph TD;A--x|textNoSpace|B;'); var res = flow.parser.parse('graph TD;A--x|textNoSpace|B;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow_cross'); expect(edges[0].type).toBe('arrow_cross');
}); });
it('should handle text on edges with space',function(){ it('should handle text on edges with space',function(){
var res = parser.parse('graph TD;A--x|text including space|B;'); var res = flow.parser.parse('graph TD;A--x|text including space|B;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow_cross'); expect(edges[0].type).toBe('arrow_cross');
}); });
it('should handle multi-line text',function(){ it('should handle multi-line text',function(){
var res = parser.parse('graph TD;A--o|text space|B;\n B-->|more text with space|C;'); var res = flow.parser.parse('graph TD;A--o|text space|B;\n B-->|more text with space|C;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges[0].type).toBe('arrow_circle'); expect(edges[0].type).toBe('arrow_circle');
expect(edges[1].type).toBe('arrow'); expect(edges[1].type).toBe('arrow');
@@ -98,58 +102,58 @@ describe('when parsing ',function(){
}); });
it('should handle text in vertices with space',function(){ it('should handle text in vertices with space',function(){
var res = parser.parse('graph TD;A[chimpansen hoppar]-->C;'); var res = flow.parser.parse('graph TD;A[chimpansen hoppar]-->C;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['A'].type).toBe('square'); expect(vert['A'].type).toBe('square');
expect(vert['A'].text).toBe('chimpansen hoppar'); expect(vert['A'].text).toBe('chimpansen hoppar');
}); });
it('should handle text in vertices with space',function(){ it('should handle text in vertices with space',function(){
var res = parser.parse('graph TD;A(chimpansen hoppar)-->C;'); var res = flow.parser.parse('graph TD;A(chimpansen hoppar)-->C;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['A'].type).toBe('round'); expect(vert['A'].type).toBe('round');
expect(vert['A'].text).toBe('chimpansen hoppar'); expect(vert['A'].text).toBe('chimpansen hoppar');
}); });
it('should handle text in vertices with space',function(){ it('should handle text in vertices with space',function(){
var res = parser.parse('graph TD;A{chimpansen hoppar}-->C;'); var res = flow.parser.parse('graph TD;A{chimpansen hoppar}-->C;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['A'].type).toBe('diamond'); expect(vert['A'].type).toBe('diamond');
expect(vert['A'].text).toBe('chimpansen hoppar'); expect(vert['A'].text).toBe('chimpansen hoppar');
}); });
it('should handle text in vertices with space',function(){ it('should handle text in vertices with space',function(){
var res = parser.parse('graph TD;A-->C{Chimpansen hoppar};'); var res = flow.parser.parse('graph TD;A-->C{Chimpansen hoppar};');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['C'].type).toBe('diamond'); expect(vert['C'].type).toBe('diamond');
expect(vert['C'].text).toBe('Chimpansen hoppar'); expect(vert['C'].text).toBe('Chimpansen hoppar');
}); });
it('should handle text in vertices with åäö and minus',function(){ it('should handle text in vertices with åäö and minus',function(){
var res = parser.parse('graph TD;A-->C{Chimpansen hoppar åäö-ÅÄÖ};'); var res = flow.parser.parse('graph TD;A-->C{Chimpansen hoppar åäö-ÅÄÖ};');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['C'].type).toBe('diamond'); expect(vert['C'].type).toBe('diamond');
expect(vert['C'].text).toBe('Chimpansen hoppar åäö-ÅÄÖ'); expect(vert['C'].text).toBe('Chimpansen hoppar åäö-ÅÄÖ');
}); });
it('should handle text in vertices with åäö, minus and space',function(){ it('should handle text in vertices with åäö, minus and space',function(){
var res = parser.parse('graph TD;A-->C{Chimpansen hoppar åäö - ÅÄÖ};'); var res = flow.parser.parse('graph TD;A-->C{Chimpansen hoppar åäö - ÅÄÖ};');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['C'].type).toBe('diamond'); expect(vert['C'].type).toBe('diamond');
expect(vert['C'].text).toBe('Chimpansen hoppar åäö - ÅÄÖ'); expect(vert['C'].text).toBe('Chimpansen hoppar åäö - ÅÄÖ');
@@ -157,50 +161,50 @@ describe('when parsing ',function(){
it('should handle a single node',function(){ it('should handle a single node',function(){
// Silly but syntactically correct // Silly but syntactically correct
var res = parser.parse('graph TD;A;'); var res = flow.parser.parse('graph TD;A;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges.length).toBe(0); expect(edges.length).toBe(0);
expect(vert['A'].styles.length).toBe(0); expect(vert['A'].styles.length).toBe(0);
}); });
it('should handle a single node with alphanumerics starting on a char',function(){ it('should handle a single node with alphanumerics starting on a char',function(){
// Silly but syntactically correct // Silly but syntactically correct
var res = parser.parse('graph TD;id1;'); var res = flow.parser.parse('graph TD;id1;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges.length).toBe(0); expect(edges.length).toBe(0);
expect(vert['id1'].styles.length).toBe(0); expect(vert['id1'].styles.length).toBe(0);
}); });
it('should handle a single node with alphanumerics starting on a num',function(){ it('should handle a single node with alphanumerics starting on a num',function(){
// Silly but syntactically correct // Silly but syntactically correct
var res = parser.parse('graph TD;1id;'); var res = flow.parser.parse('graph TD;1id;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges.length).toBe(0); expect(edges.length).toBe(0);
expect(vert['1id'].styles.length).toBe(0); expect(vert['1id'].styles.length).toBe(0);
}); });
it('should handle a single node with alphanumerics containing a minus sign',function(){ it('should handle a single node with alphanumerics containing a minus sign',function(){
// Silly but syntactically correct // Silly but syntactically correct
var res = parser.parse('graph TD;i-d;'); var res = flow.parser.parse('graph TD;i-d;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges.length).toBe(0); expect(edges.length).toBe(0);
expect(vert['i-d'].styles.length).toBe(0); expect(vert['i-d'].styles.length).toBe(0);
}); });
//console.log(parser.parse('graph TD;style Q background:#fff;')); //console.log(flow.parser.parse('graph TD;style Q background:#fff;'));
it('should handle styles for vertices',function(){ it('should handle styles for vertices',function(){
var res = parser.parse('graph TD;style Q background:#fff;'); var res = flow.parser.parse('graph TD;style Q background:#fff;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
var style = vert['Q'].styles[0]; var style = vert['Q'].styles[0];
@@ -208,20 +212,20 @@ describe('when parsing ',function(){
expect(vert['Q'].styles[0]).toBe('background:#fff'); expect(vert['Q'].styles[0]).toBe('background:#fff');
}); });
//console.log(parser.parse('graph TD;style Q background:#fff;')); //console.log(flow.parser.parse('graph TD;style Q background:#fff;'));
it('should handle styles for edges',function(){ it('should handle styles for edges',function(){
var res = parser.parse('graph TD;a-->b;\nstyle #0 stroke: #f66;'); var res = flow.parser.parse('graph TD;a-->b;\nstyle #0 stroke: #f66;');
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(edges.length).toBe(1); expect(edges.length).toBe(1);
}); });
it('should handle multiple styles for a vortex',function(){ it('should handle multiple styles for a vortex',function(){
var res = parser.parse('graph TD;style R background:#fff,border:1px solid red;'); var res = flow.parser.parse('graph TD;style R background:#fff,border:1px solid red;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['R'].styles.length).toBe(2); expect(vert['R'].styles.length).toBe(2);
expect(vert['R'].styles[0]).toBe('background:#fff'); expect(vert['R'].styles[0]).toBe('background:#fff');
@@ -229,10 +233,10 @@ describe('when parsing ',function(){
}); });
it('should handle multiple styles in a graph',function(){ it('should handle multiple styles in a graph',function(){
var res = parser.parse('graph TD;style S background:#aaa;\nstyle T background:#bbb,border:1px solid red;'); var res = flow.parser.parse('graph TD;style S background:#aaa;\nstyle T background:#bbb,border:1px solid red;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['S'].styles.length).toBe(1); expect(vert['S'].styles.length).toBe(1);
expect(vert['T'].styles.length).toBe(2); expect(vert['T'].styles.length).toBe(2);
@@ -242,10 +246,10 @@ describe('when parsing ',function(){
}); });
it('should handle styles and graph definitons in a graph',function(){ it('should handle styles and graph definitons in a graph',function(){
var res = parser.parse('graph TD;S-->T;\nstyle S background:#aaa;\nstyle T background:#bbb,border:1px solid red;'); var res = flow.parser.parse('graph TD;S-->T;\nstyle S background:#aaa;\nstyle T background:#bbb,border:1px solid red;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
var edges = parser.yy.getEdges(); var edges = flow.parser.yy.getEdges();
expect(vert['S'].styles.length).toBe(1); expect(vert['S'].styles.length).toBe(1);
expect(vert['T'].styles.length).toBe(2); expect(vert['T'].styles.length).toBe(2);
@@ -254,10 +258,10 @@ describe('when parsing ',function(){
expect(vert['T'].styles[1]).toBe('border:1px solid red'); expect(vert['T'].styles[1]).toBe('border:1px solid red');
}); });
it('should handle styles and graph definitons in a graph',function(){ it('should handle styles and graph definitons in a graph',function(){
var res = parser.parse('graph TD;style T background:#bbb,border:1px solid red;'); var res = flow.parser.parse('graph TD;style T background:#bbb,border:1px solid red;');
//var res = parser.parse('graph TD;style T background: #bbb;'); //var res = flow.parser.parse('graph TD;style T background: #bbb;');
var vert = parser.yy.getVertices(); var vert = flow.parser.yy.getVertices();
expect(vert['T'].styles.length).toBe(2); expect(vert['T'].styles.length).toBe(2);
expect(vert['T'].styles[0]).toBe('background:#bbb'); expect(vert['T'].styles[0]).toBe('background:#bbb');

View File

@@ -10,7 +10,7 @@
\- return 'MINUS'; \- return 'MINUS';
\+ return 'PLUS'; \+ return 'PLUS';
\= return 'EQUALS'; \= return 'EQUALS';
[a-zåäöæøA-ZÅÄÖÆØ]+ return 'ALPHA'; [a-zåäöæøA-ZÅÄÖÆØ()]+ return 'ALPHA';
"/" return 'SLASH'; "/" return 'SLASH';
"(" return 'PS'; "(" return 'PS';
")" return 'PE'; ")" return 'PE';
@@ -41,18 +41,22 @@ statements
{$$=$1;} {$$=$1;}
| statement EOF | statement EOF
{$$=$1;} {$$=$1;}
| statement newlines EOF
{$$=$1;}
; ;
preStatement preStatement
: alphaNum COLON alphaNum : alphaNum COLON alphaNum
{console.log('Got new actor id='+$1+' descr='+$3);$$={a:$1,b:$3}} {$$={a:$1,b:$3}}
; ;
statement statement
: preStatement : preStatement
{console.log('Got new actor id='+$1.a+' descr='+$1.b);$$='actor';} {yy.addActor($1.a,'actor',$1.b);$$='actor';}
| preStatement DOT message
{yy.addMessage($1.a,$1.b,$3);$$='message';}
| preStatement EQUALS callee DOT message | preStatement EQUALS callee DOT message
{console.log('Got new message from='+$1.a+' to='+$3+' message='+$5+' answer='+$1.b);$$='actor';} {yy.addMessage($1.a,$3,$5,$1.b);$$='actor';}
; ;
action: action:
@@ -62,7 +66,7 @@ action:
actorDefinition: actorDefinition:
alphaNum COLON alphaNum alphaNum COLON alphaNum
{console.log('Got new actor id='+$1+' descr='+$3);$$='actor';} {$$='actor';}
; ;
messageDefinition: messageDefinition:
caller COLON answer EQUALS callee DOT message caller COLON answer EQUALS callee DOT message

View File

@@ -72,60 +72,63 @@
} }
*/ */
var parser = (function(){ var parser = (function(){
var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,9],$V1=[1,10],$V2=[1,13],$V3=[5,24],$V4=[5,10,11,13,24,27,28],$V5=[27,28]; var o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[1,9],$V1=[1,10],$V2=[1,13],$V3=[5,24],$V4=[5,10,11,13,24,27,28],$V5=[5,27,28];
var parser = {trace: function trace() { }, var parser = {trace: function trace() { },
yy: {}, yy: {},
symbols_: {"error":2,"expressions":3,"statements":4,"EOF":5,"statement":6,"newlines":7,"preStatement":8,"alphaNum":9,"COLON":10,"EQUALS":11,"callee":12,"DOT":13,"message":14,"action":15,"SQS":16,"SQE":17,"actorDefinition":18,"messageDefinition":19,"caller":20,"answer":21,"spaceList":22,"SPACE":23,"NEWLINE":24,"alphaNumStatement":25,"alphaNumToken":26,"ALPHA":27,"NUM":28,"text":29,"MINUS":30,"$accept":0,"$end":1}, symbols_: {"error":2,"expressions":3,"statements":4,"EOF":5,"statement":6,"newlines":7,"preStatement":8,"alphaNum":9,"COLON":10,"DOT":11,"message":12,"EQUALS":13,"callee":14,"action":15,"SQS":16,"SQE":17,"actorDefinition":18,"messageDefinition":19,"caller":20,"answer":21,"spaceList":22,"SPACE":23,"NEWLINE":24,"alphaNumStatement":25,"alphaNumToken":26,"ALPHA":27,"NUM":28,"text":29,"MINUS":30,"$accept":0,"$end":1},
terminals_: {2:"error",5:"EOF",10:"COLON",11:"EQUALS",13:"DOT",16:"SQS",17:"SQE",23:"SPACE",24:"NEWLINE",27:"ALPHA",28:"NUM",30:"MINUS"}, terminals_: {2:"error",5:"EOF",10:"COLON",11:"DOT",13:"EQUALS",16:"SQS",17:"SQE",23:"SPACE",24:"NEWLINE",27:"ALPHA",28:"NUM",30:"MINUS"},
productions_: [0,[3,1],[3,1],[4,3],[4,2],[8,3],[6,1],[6,5],[15,2],[18,3],[19,7],[20,1],[21,1],[12,1],[14,1],[22,2],[22,1],[7,2],[7,1],[9,1],[25,2],[25,1],[26,1],[26,1],[29,3],[29,5],[29,1]], productions_: [0,[3,1],[3,1],[4,3],[4,2],[4,3],[8,3],[6,1],[6,3],[6,5],[15,2],[18,3],[19,7],[20,1],[21,1],[14,1],[12,1],[22,2],[22,1],[7,2],[7,1],[9,1],[25,2],[25,1],[26,1],[26,1],[29,3],[29,5],[29,1]],
performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) { performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {
/* this == yyval */ /* this == yyval */
var $0 = $$.length - 1; var $0 = $$.length - 1;
switch (yystate) { switch (yystate) {
case 1: case 19: case 22: case 23: case 1: case 21: case 24: case 25:
this.$=$$[$0]; this.$=$$[$0];
break; break;
case 3: case 3: case 5:
this.$=$$[$0-2]; this.$=$$[$0-2];
break; break;
case 4: case 4:
this.$=$$[$0-1]; this.$=$$[$0-1];
break; break;
case 5:
console.log('Got new actor id='+$$[$0-2]+' descr='+$$[$0]);this.$={a:$$[$0-2],b:$$[$0]}
break;
case 6: case 6:
console.log('Got new actor id='+$$[$0].a+' descr='+$$[$0].b);this.$='actor'; this.$={a:$$[$0-2],b:$$[$0]}
break; break;
case 7: case 7:
console.log('Got new message from='+$$[$0-4].a+' to='+$$[$0-2]+' message='+$$[$0]+' answer='+$$[$0-4].b);this.$='actor'; yy.addActor($$[$0].a,'actor',$$[$0].b);this.$='actor';
break; break;
case 8: case 8:
console.log('#a');this.$='action'; yy.addMessage($$[$0-2].a,$$[$0-2].b,$$[$0]);this.$='message';
break; break;
case 9: case 9:
console.log('Got new actor id='+$$[$0-2]+' descr='+$$[$0]);this.$='actor'; yy.addMessage($$[$0-4].a,$$[$0-2],$$[$0],$$[$0-4].b);this.$='actor';
break; break;
case 10: case 10:
console.log('#a');this.$='action';
break;
case 11:
this.$='actor';
break;
case 12:
console.log('Got new message from='+$$[$0-6]+' to='+$$[$0-2]+' message='+$$[$0]+' answer='+$$[$0-4]);this.$='actor'; console.log('Got new message from='+$$[$0-6]+' to='+$$[$0-2]+' message='+$$[$0]+' answer='+$$[$0-4]);this.$='actor';
break; break;
case 20: case 22:
this.$=$$[$0-1]+''+$$[$0]; this.$=$$[$0-1]+''+$$[$0];
break; break;
case 24: case 26:
this.$ = $$[$0-2] + ' ' +$$[$0]; this.$ = $$[$0-2] + ' ' +$$[$0];
break; break;
case 25: case 27:
this.$ = $$[$0-4] + ' - ' +$$[$0]; this.$ = $$[$0-4] + ' - ' +$$[$0];
break; break;
case 26: case 28:
this.$ = $$[$0]; this.$ = $$[$0];
break; break;
} }
}, },
table: [{3:1,4:2,5:[1,3],6:4,8:5,9:6,25:7,26:8,27:$V0,28:$V1},{1:[3]},{1:[2,1]},{1:[2,2]},{5:[1,12],7:11,24:$V2},o($V3,[2,6],{11:[1,14]}),{10:[1,15],26:16,27:$V0,28:$V1},o($V4,[2,19]),o($V4,[2,21]),o($V4,[2,22]),o($V4,[2,23]),{4:17,6:4,8:5,9:6,25:7,26:8,27:$V0,28:$V1},{1:[2,4]},o($V5,[2,18],{7:18,24:$V2}),{9:20,12:19,25:7,26:8,27:$V0,28:$V1},{9:21,25:7,26:8,27:$V0,28:$V1},o($V4,[2,20]),{1:[2,3]},o($V5,[2,17]),{13:[1,22]},{13:[2,13],26:16,27:$V0,28:$V1},o([5,11,24],[2,5],{26:16,27:$V0,28:$V1}),{9:24,14:23,25:7,26:8,27:$V0,28:$V1},o($V3,[2,7]),o($V3,[2,14],{26:16,27:$V0,28:$V1})], table: [{3:1,4:2,5:[1,3],6:4,8:5,9:6,25:7,26:8,27:$V0,28:$V1},{1:[3]},{1:[2,1]},{1:[2,2]},{5:[1,12],7:11,24:$V2},o($V3,[2,7],{11:[1,14],13:[1,15]}),{10:[1,16],26:17,27:$V0,28:$V1},o($V4,[2,21]),o($V4,[2,23]),o($V4,[2,24]),o($V4,[2,25]),{4:18,5:[1,19],6:4,8:5,9:6,25:7,26:8,27:$V0,28:$V1},{1:[2,4]},o($V5,[2,20],{7:20,24:$V2}),{9:22,12:21,25:7,26:8,27:$V0,28:$V1},{9:24,14:23,25:7,26:8,27:$V0,28:$V1},{9:25,25:7,26:8,27:$V0,28:$V1},o($V4,[2,22]),{1:[2,3]},{1:[2,5]},o($V5,[2,19]),o($V3,[2,8]),o($V3,[2,16],{26:17,27:$V0,28:$V1}),{11:[1,26]},{11:[2,15],26:17,27:$V0,28:$V1},o([5,11,13,24],[2,6],{26:17,27:$V0,28:$V1}),{9:22,12:27,25:7,26:8,27:$V0,28:$V1},o($V3,[2,9])],
defaultActions: {2:[2,1],3:[2,2],12:[2,4],17:[2,3]}, defaultActions: {2:[2,1],3:[2,2],12:[2,4],18:[2,3],19:[2,5]},
parseError: function parseError(str, hash) { parseError: function parseError(str, hash) {
if (hash.recoverable) { if (hash.recoverable) {
this.trace(str); this.trace(str);
@@ -608,7 +611,7 @@ case 3:return 30;
break; break;
case 4:return 'PLUS'; case 4:return 'PLUS';
break; break;
case 5:return 11; case 5:return 13;
break; break;
case 6:return 27; case 6:return 27;
break; break;
@@ -622,7 +625,7 @@ case 10:return 16;
break; break;
case 11:return 17; case 11:return 17;
break; break;
case 12:return 13; case 12:return 11;
break; break;
case 13:return 23; case 13:return 23;
break; break;
@@ -630,7 +633,7 @@ case 14:return 5;
break; break;
} }
}, },
rules: [/^(?:\n)/,/^(?:[0-9]+)/,/^(?::)/,/^(?:-)/,/^(?:\+)/,/^(?:=)/,/^(?:[a-zåäöæøA-ZÅÄÖÆØ]+)/,/^(?:\/)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\.)/,/^(?:\s)/,/^(?:$)/], rules: [/^(?:\n)/,/^(?:[0-9]+)/,/^(?::)/,/^(?:-)/,/^(?:\+)/,/^(?:=)/,/^(?:[a-zåäöæøA-ZÅÄÖÆØ()]+)/,/^(?:\/)/,/^(?:\()/,/^(?:\))/,/^(?:\[)/,/^(?:\])/,/^(?:\.)/,/^(?:\s)/,/^(?:$)/],
conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],"inclusive":true}} conditions: {"INITIAL":{"rules":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14],"inclusive":true}}
}); });
return lexer; return lexer;

View File

@@ -13,8 +13,8 @@ str = 'a12:d12\n\na24:d24';
str = 'bfs:queue\n\nbfs3:queue\n'; str = 'bfs:queue\n\nbfs3:queue\n';
str = str + 'bfs:message=someNode.setLevel\n'; str = str + 'bfs:message=someNode.setLevel\n';
str = str + 'bfs:message2=someNode.setLevel2'; str = str + 'bfs:message2=someNode.setLevel2';
console.log(str); //console.log(str);
console.log(sq.parse(str)); //console.log(sq.parse(str));
str = 'bfs:BFS\n'; str = 'bfs:BFS\n';
str = str + 'someNode:SomeNode\n'; str = str + 'someNode:SomeNode\n';
@@ -22,3 +22,76 @@ str = str + 'bfs:queue.new\n';
str = str + 'bfs:someNode.setLevel'; str = str + 'bfs:someNode.setLevel';
//console.log(str); //console.log(str);
//console.log(sq.parse(str)); //console.log(sq.parse(str));
describe('when parsing ',function() {
beforeEach(function () {
sq = require('./parser/sequence').parser;
sq.yy = require('./sequenceDb');
sq.yy.clear();
sq.yy.parseError = function(err, hash) {
// don't print error for missing semicolon
if (!((!hash.expected || hash.expected.indexOf("';'") >= 0) && (hash.token === 'CLOSEBRACE' || parser.yy.lineBreak || parser.yy.lastLineBreak || hash.token === 1 || parser.yy.doWhile))) {
throw new SyntaxError(err);
}
};
//parser.yy = mermaid.graph;
/*parser.parse.parseError= function parseError(str, hash) {
console.log(str);
}*/
});
it('should handle an actor', function () {
str = 'bfs1:queue';
sq.parse(str);
var actors = sq.yy.getActors();
actors.bfs1.description = 'queue';
});
it('should handle a statement ending with a newline', function () {
str = 'bfs1:queue\n';
sq.parse(str);
var actors = sq.yy.getActors();
actors.bfs1.description = 'queue';
});
it('should handle a errors', function () {
str = 'bfs1!!!!queue\n';
spyOn('sq.yy',parseError);
sq.parse(str);
expect(sq.yy.parseError).toHaveBeenCalled();
});
it('should handle multiple actors', function () {
str = 'bfs1:queue\n\nbfs2:queue';
sq.parse(str);
var actors = sq.yy.getActors();
actors.bfs1.description = 'queue';
actors.bfs2.description = 'queue';
});
it('should handle a message with response', function () {
str = 'bfs1:queue\n\nbfs2:queue\n';
str = str + 'bfs1:message=bfs2.setLevel(0)';
//console.log(str);
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages.length).toBe(1);
expect(messages[0].from).toBe('bfs1');
});
it('should handle a message with no response', function () {
str = 'bfs1:queue\n\nbfs2:queue\n';
str = str + 'bfs1:bfs2.start';
//console.log(str);
sq.parse(str);
var messages = sq.yy.getMessages();
expect(messages.length).toBe(1);
expect(messages[0].from).toBe('bfs1');
});
});

27
src/sequenceDb.js Normal file
View File

@@ -0,0 +1,27 @@
/**
* Created by knut on 14-11-19.
*/
var actors = {};
var messages = [];
exports.addActor = function(id,name,description){
//console.log('Adding actor: '+id);
actors[id] = {name:name, description:description};
};
exports.addMessage = function(idFrom, idTo, message, answer){
//console.log('Adding message from='+idFrom+' to='+idTo+' message='+message+' answer='+answer);
messages.push({from:idFrom, to:idTo, message:message, answer:answer});
};
exports.getMessages = function(){
return messages;
};
exports.getActors = function(){
return actors;
};
exports.clear = function(){
actors = {};
messages = [];
};

View File

@@ -1,9 +1,9 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<script src="../vendor/d3/d3.js"></script> <scrpt src="../vendor/d3/d3.js"></scrpt>
<script src="../vendor/dagre-d3/dist/dagre-d3.core.js"></script> <scrpt src="../vendor/dagre-d3/dist/dagre-d3.core.js"></scrpt>
<script src="../dist/mermaid.slim.js"></script> <script src="../dist/mm.full.js"></script>
<style id="css"> <style id="css">
/* This sets the color for "TK" nodes to a light blue green. */ /* This sets the color for "TK" nodes to a light blue green. */
g.type-TK > rect { g.type-TK > rect {
@@ -31,9 +31,62 @@
</head> </head>
<body> <body>
<div class="mermaid"> <div class="mermaid">
graph LR; graph TD;
A-->B; df103do1[Start 103 1];
B-->D; df103do1-->df103do30[Switch 103 30];
df103do30-->|Schedule Kvällsmeny Open|df103do70[Menu 103 70];
df103do30-->|Schedule Kvällsmeny Closed|df103do35[Start 103 35];
df103do35-->df103do40[Gosub 103 40];
df103do40-->|Sub|df104do1[Start 104 1];
df104do1-->df104do3[Phrase StängtInfoTelefontid 104 3];
df104do3-->df104do4[Phrase StängtInfoSkadeärende 104 4];
df104do4-->df104do5[Phrase StängtInfoOmbud 104 5];
df104do5-->df104do6[Phrase InfoWebbplats 104 6];
df104do6-->df104do7[Phrase TackOchVälkommenÅter 104 7];
df104do7-->df104do8[Return 104 8];
df104do8-->df103do50[Goto 103 50];
df103do50-->df103do998[Start 103 998];
df103do998-->df103do999[Drop 103 999];
df103do70-->|1|df103do110[Start 103 110];
df103do110-->df103do116[Goto 103 116];
df103do116-->df6do10[Start 6 10];
df6do10-->df6do11[Switch 6 11];
df6do11-->|Öppet|df6do200[Route CG route 6 200];
df103do70-->|2|df103do120[Start 103 120];
df103do120-->df103do126[Goto 103 126];
df103do126-->df6do10[Start 6 10];
df6do10-->df6do11[Switch 6 11];
df6do11-->|Öppet|df6do200[Route CG route 6 200];
df103do70-->|3|df103do130[Start 103 130];
df103do130-->df103do136[Goto 103 136];
df103do136-->df6do10[Start 6 10];
df6do10-->df6do11[Switch 6 11];
df6do11-->|Öppet|df6do200[Route CG route 6 200];
df103do70-->|invalid|df103do80[Goto 103 80];
df103do80-->df103do180[Start 103 180];
df103do180-->df103do184[Phrase MenyOkäntval 103 184];
df103do184-->df103do186[Goto 103 186];
df103do186-->df103do300[Start 103 300];
df103do300-->df103do305[Counter 103 305];
df103do70-->|timeout|df103do85[Goto 103 85];
df103do85-->df103do300;
df103do305-->|2x|df103do310[Phrase MenyFörsökigen 103 310];
df103do310-->df103do315[Goto 103 315];
df103do315-->df103do65[Start 103 65];
df103do65-->df103do70;
df103do305-->|3x|df103do325[Goto 103 325];
df103do325-->df103do984[Start 103 984];
df103do984-->df103do985[Gosub 103 985];
df103do985-->|Sub|df105do1[Start 105 1];
df105do1-->df105do3[Phrase InfoWebbplats 105 3];
df105do3-->df105do4[Phrase TackOchVälkommenÅter 105 4];
df105do4-->df105do8[Return 105 8];
df105do8-->df103do990[Goto 103 990];
df103do990-->df103do998;
</div> </div>
</body> </body>
</html> </html>

View File

@@ -28,7 +28,7 @@
} }
</style> </style>
<script src="../dist/mermaid.full.js"></script> <script src="../dist/mm.full.js"></script>
</head> </head>
<body> <body>
<div class="mermaid"> <div class="mermaid">