|
|
@ -7207,80 +7207,166 @@ Timeline.prototype.getItemRange = function getItemRange() { |
|
|
|
*/ |
|
|
|
function parseStatement() { |
|
|
|
var attr; |
|
|
|
var id = token; // can be as string or a number
|
|
|
|
getToken(); |
|
|
|
|
|
|
|
attr = parseAttributeStatement(); |
|
|
|
if (!attr) { |
|
|
|
var id = token; // can be a string or a number
|
|
|
|
getToken(); |
|
|
|
|
|
|
|
if (token == '=') { |
|
|
|
// id statement
|
|
|
|
getToken(); |
|
|
|
if (!graph.attr) { |
|
|
|
graph.attr = {}; |
|
|
|
} |
|
|
|
graph.attr[id] = token; |
|
|
|
getToken(); |
|
|
|
} |
|
|
|
else { |
|
|
|
// node statement
|
|
|
|
var node = { |
|
|
|
id: id |
|
|
|
}; |
|
|
|
attr = parseAttributes(); |
|
|
|
if (attr) { |
|
|
|
node.attr = attr; |
|
|
|
} |
|
|
|
addNode(node); |
|
|
|
|
|
|
|
// edge statements
|
|
|
|
parseEdge(id); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* parse an attribute statement like "node [shape=circle fontSize=16]". |
|
|
|
* Available keywords are 'node', 'edge', 'graph' |
|
|
|
* @returns {Object | null} attr |
|
|
|
*/ |
|
|
|
function parseAttributeStatement () { |
|
|
|
var attr = null; |
|
|
|
|
|
|
|
// attribute statements
|
|
|
|
if (id == 'node') { |
|
|
|
if (token == 'node') { |
|
|
|
getToken(); |
|
|
|
|
|
|
|
// node attributes
|
|
|
|
attr = parseAttributes(); |
|
|
|
if (attr) { |
|
|
|
nodeAttr = merge(nodeAttr, attr); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (id == 'edge') { |
|
|
|
else if (token == 'edge') { |
|
|
|
getToken(); |
|
|
|
|
|
|
|
// edge attributes
|
|
|
|
attr = parseAttributes(); |
|
|
|
if (attr) { |
|
|
|
edgeAttr = merge(edgeAttr, attr); |
|
|
|
} |
|
|
|
} |
|
|
|
else if (id == 'graph') { |
|
|
|
else if (token == 'graph') { |
|
|
|
getToken(); |
|
|
|
|
|
|
|
// graph attributes
|
|
|
|
attr = parseAttributes(); |
|
|
|
if (attr) { |
|
|
|
graph.attr = merge(graph.attr, attr); |
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
if (token == '=') { |
|
|
|
// id statement
|
|
|
|
getToken(); |
|
|
|
if (!graph.attr) { |
|
|
|
graph.attr = {}; |
|
|
|
} |
|
|
|
graph.attr[id] = token; |
|
|
|
getToken(); |
|
|
|
|
|
|
|
return attr; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* Parse an edge or a series of edges |
|
|
|
* @param {String | Number} from Id of the from node |
|
|
|
*/ |
|
|
|
function parseEdge(from) { |
|
|
|
while (token == '->' || token == '--') { |
|
|
|
var type = token; |
|
|
|
getToken(); |
|
|
|
|
|
|
|
if (token == '{') { |
|
|
|
// parse a set of nodes, like "node1 -> {node2, node3}"
|
|
|
|
parseEdgeSet(from, type); |
|
|
|
break; |
|
|
|
} |
|
|
|
else { |
|
|
|
// node statement
|
|
|
|
var node = { |
|
|
|
id: id |
|
|
|
// parse a single edge, like "node1 -> node2 -> node3"
|
|
|
|
var to = token; |
|
|
|
addNode({ |
|
|
|
id: to |
|
|
|
}); |
|
|
|
getToken(); |
|
|
|
var attr = parseAttributes(); |
|
|
|
|
|
|
|
// create edge
|
|
|
|
var edge = { |
|
|
|
from: from, |
|
|
|
to: to, |
|
|
|
type: type |
|
|
|
}; |
|
|
|
attr = parseAttributes(); |
|
|
|
if (attr) { |
|
|
|
node.attr = attr; |
|
|
|
edge.attr = attr; |
|
|
|
} |
|
|
|
addNode(node); |
|
|
|
addEdge(edge); |
|
|
|
|
|
|
|
// edge statements
|
|
|
|
var from = id; |
|
|
|
while (token == '->' || token == '--') { |
|
|
|
var type = token; |
|
|
|
getToken(); |
|
|
|
from = to; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
var to = token; |
|
|
|
addNode({ |
|
|
|
id: to |
|
|
|
}); |
|
|
|
getToken(); |
|
|
|
attr = parseAttributes(); |
|
|
|
/** |
|
|
|
* Parse a set of nodes, like "{node1; node2; node3}" |
|
|
|
* @param {String | Number} from Id of the from node |
|
|
|
* @param {String} type Edge type, '--' or '->' |
|
|
|
* @return {Node[] | null} nodes |
|
|
|
*/ |
|
|
|
function parseEdgeSet(from, type) { |
|
|
|
var nodes = null; |
|
|
|
|
|
|
|
// create edge
|
|
|
|
var edge = { |
|
|
|
from: from, |
|
|
|
to: to, |
|
|
|
type: type |
|
|
|
}; |
|
|
|
if (attr) { |
|
|
|
edge.attr = attr; |
|
|
|
} |
|
|
|
addEdge(edge); |
|
|
|
if (token == '{') { |
|
|
|
getToken(); |
|
|
|
|
|
|
|
while (token !== '' && token != '}') { |
|
|
|
// create to node
|
|
|
|
if (tokenType != TOKENTYPE.IDENTIFIER) { |
|
|
|
throw newSyntaxError('Identifier expected'); |
|
|
|
} |
|
|
|
var to = token; |
|
|
|
addNode({ |
|
|
|
id: to |
|
|
|
}); |
|
|
|
getToken(); |
|
|
|
|
|
|
|
from = to; |
|
|
|
// create edge
|
|
|
|
var edge = { |
|
|
|
from: from, |
|
|
|
to: to, |
|
|
|
type: type |
|
|
|
}; |
|
|
|
var attr = parseAttributes(); |
|
|
|
if (attr) { |
|
|
|
edge.attr = attr; |
|
|
|
} |
|
|
|
addEdge(edge); |
|
|
|
|
|
|
|
// separator
|
|
|
|
if (token == ';') { |
|
|
|
getToken(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// closing bracket
|
|
|
|
if (token != '}') { |
|
|
|
throw newSyntaxError('bracket } expected'); |
|
|
|
} |
|
|
|
getToken(); |
|
|
|
} |
|
|
|
|
|
|
|
return nodes; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
@ -7315,6 +7401,10 @@ Timeline.prototype.getItemRange = function getItemRange() { |
|
|
|
getToken(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (token != ']') { |
|
|
|
throw newSyntaxError('Bracket ] expected'); |
|
|
|
} |
|
|
|
getToken(); |
|
|
|
|
|
|
|
return attr; |
|
|
|