Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.graphstream.stream.file.dot.DOTParser.jj Maven / Gradle / Ivy
options { JDK_VERSION = "1.5"; STATIC = false; IGNORE_CASE = true; }
PARSER_BEGIN(DOTParser)
/*
* Copyright 2006 - 2012
* Stefan Balev
* Julien Baudry
* Antoine Dutot
* Yoann Pigné
* Guilhelm Savin
*
* This file is part of GraphStream .
*
* GraphStream is a library whose purpose is to handle static or dynamic
* graph, create them from scratch, file or any source and display them.
*
* This program is free software distributed under the terms of two licenses, the
* CeCILL-C license that fits European law, and the GNU Lesser General Public
* License. You can use, modify and/ or redistribute the software under the terms
* of the CeCILL-C license as circulated by CEA, CNRS and INRIA at the following
* URL or under the terms of the GNU LGPL as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C and LGPL licenses and that you accept their terms.
*/
package org.graphstream.stream.file.dot;
import java.io.InputStream;
import java.io.IOException;
import java.io.Reader;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import org.graphstream.stream.SourceBase.ElementType;
import org.graphstream.stream.file.FileSourceDOT;
import org.graphstream.graph.implementations.AbstractElement.AttributeChangeEvent;
import org.graphstream.util.parser.ParseException;
import org.graphstream.util.parser.Parser;
import org.graphstream.util.parser.SimpleCharStream;
import org.graphstream.util.parser.Token;
import org.graphstream.util.parser.TokenMgrError;
/**
* This class defines a DOT parser.
*
* It respects the specifications of the DOT language that can be found
* here .
*
* Subgraph produces no error but has no effect on the graph.
*/
@SuppressWarnings("unused")
public class DOTParser implements Parser {
/**
* The DOT source associated with this parser.
*/
private FileSourceDOT dot;
/**
* Id of the parser used in events.
*/
private String sourceId;
/**
* Flag telling if the graph is directed.
*/
private boolean directed;
/**
* Flag telling if the graph is 'strict'.
*/
private boolean strict;
/**
* Global attributes of nodes.
*/
private HashMap globalNodesAttributes;
/**
* Global attributes of edges.
*/
private HashMap globalEdgesAttributes;
/**
* IDs of added nodes.
*/
private HashSet nodeAdded;
/**
* Create a new parser associated with a DOT source from an input stream.
*/
public DOTParser(FileSourceDOT dot, InputStream stream) {
this(stream);
init(dot);
}
/**
* Create a new parser associated with a DOT source from a reader.
*/
public DOTParser(FileSourceDOT dot, Reader stream ) {
this(stream);
init(dot);
}
/**
* Closes the parser, closing the opened stream.
*/
public void close() throws IOException {
jj_input_stream.close();
}
private void init(FileSourceDOT dot) {
this.dot = dot;
this.sourceId = String.format("", System.nanoTime());
globalNodesAttributes = new HashMap();
globalEdgesAttributes = new HashMap();
nodeAdded = new HashSet();
}
private void addNode(String nodeId, String [] port,
HashMap attr) {
if (nodeAdded.contains(nodeId)) {
if (attr != null) {
for (String key : attr.keySet())
dot.sendAttributeChangedEvent( sourceId, nodeId, ElementType.NODE,
key, AttributeChangeEvent.ADD, null, attr.get(key));
}
}
else {
dot.sendNodeAdded(sourceId, nodeId);
nodeAdded.add(nodeId);
if (attr == null) {
for (String key : globalNodesAttributes.keySet())
dot.sendAttributeChangedEvent( sourceId, nodeId, ElementType.NODE,
key, AttributeChangeEvent.ADD, null, globalNodesAttributes.get(key));
} else {
for (String key : globalNodesAttributes.keySet()) {
if (!attr.containsKey(key))
dot.sendAttributeChangedEvent( sourceId, nodeId, ElementType.NODE,
key, AttributeChangeEvent.ADD, null, globalNodesAttributes.get(key));
}
for (String key : attr.keySet())
dot.sendAttributeChangedEvent( sourceId, nodeId, ElementType.NODE,
key, AttributeChangeEvent.ADD, null, attr.get(key));
}
}
}
private void addEdges(LinkedList edges,
HashMap attr) {
HashMap hash = new HashMap();
String [] ids = new String [(edges.size() - 1) / 2];
boolean [] directed = new boolean [(edges.size() - 1) / 2];
int count = 0;
for (int i = 0; i < edges.size() - 1; i += 2) {
String from = edges.get(i);
String to = edges.get(i+2);
if (!nodeAdded.contains(from))
addNode(from, null, null);
if (!nodeAdded.contains(to))
addNode(to, null, null);
String edgeId = String.format("(%s;%s)", from, to);
String rev = String.format("(%s;%s)", to, from);
if (hash.containsKey(rev)) {
directed [hash.get(rev)] = false;
} else {
hash.put(edgeId, count);
ids [count] = edgeId;
directed [count] = edges.get(i+1).equals("->");
count++;
}
}
hash.clear();
if (count == 1 && attr != null && attr.containsKey("id")) {
ids [0] = attr.get("id").toString();
attr.remove("id");
}
for (int i = 0; i < count; i++) {
dot.sendEdgeAdded(sourceId, ids [i], edges.get(i*2),
edges.get((i+1)*2), directed [i]);
if (attr == null) {
for (String key : globalEdgesAttributes.keySet())
dot.sendAttributeChangedEvent( sourceId, ids [i], ElementType.EDGE,
key, AttributeChangeEvent.ADD, null, globalEdgesAttributes.get(key));
} else {
for (String key : globalEdgesAttributes.keySet()) {
if (!attr.containsKey(key))
dot.sendAttributeChangedEvent( sourceId, ids [i], ElementType.EDGE,
key, AttributeChangeEvent.ADD, null, globalEdgesAttributes.get(key));
}
for (String key : attr.keySet())
dot.sendAttributeChangedEvent( sourceId, ids [i], ElementType.EDGE,
key, AttributeChangeEvent.ADD, null, attr.get(key));
}
}
}
private void setGlobalAttributes(String who, HashMap attr) {
if (who.equalsIgnoreCase("graph")) {
for (String key : attr.keySet())
dot.sendAttributeChangedEvent( sourceId, sourceId, ElementType.GRAPH,
key, AttributeChangeEvent.ADD, null, attr.get(key));
}
else if (who.equalsIgnoreCase("node"))
globalNodesAttributes.putAll(attr);
else if (who.equalsIgnoreCase("edge"))
globalEdgesAttributes.putAll(attr);
}
}
PARSER_END(DOTParser)
/************************************************************************
* The lexer.
*/
SKIP :
{ " "
| "\r"
| "\t"
| "\n"
| <"/*" (~["*"]|"*" ~["/"])* "*/">
| <("//" | "#") (~["\n","\r"])* >
}
//
// Private tokens.
//
TOKEN: {
< #EOL : (("\r")|("\n"))>
| < #DIGIT : ["0"-"9"] >
| < #HEXDIGIT : (["0"-"9","a"-"f","A"-"F"])>
}
//
// Symbols
//
TOKEN: {
< LSQBR : "[" >
| < RSQBR : "]" >
| < LBRACE : "{" >
| < RBRACE : "}" >
| < COLON : ":" >
| < COMMA : "," >
| < EQUALS : "=" >
}
//
// DOT keywords
//
TOKEN: {
< GRAPH : "graph" >
| < DIGRAPH : "digraph" >
| < SUBGRAPH : "subgraph" >
| < NODE : "node" >
| < EDGE : "edge" >
| < STRICT : "strict" >
| < EDGE_OP : ( "--" | "->" ) >
}
//
// Complex tokens
//
TOKEN: {
< REAL : ( "-" | "+" )? ( )+ ( "." ()+ )?>
| < STRING : (("\"" (~["\""]|"\\\"")* "\"")|("'" (~["'"])* "'")) >
| < WORD : [ "a"-"z", "A"-"Z", "\200"-"\377", "_" ] ( [ "a"-"z", "A"-"Z", "\200"-"\377", "_", "0"-"9" ] )* >
}
/*****************************************************************
* The parser.
*/
public void all():
{}
{
graph() ( statement() )*
}
public boolean next():
{
boolean hasMore = false;
}
{
( statement() { hasMore = true; }
|
|
)
{return hasMore;}
}
public void open():
{}
{
graph()
}
private void graph():
{
directed = false;
strict = false;
globalNodesAttributes.clear();
globalEdgesAttributes.clear();
}
{
( {strict = true;})?
( | { directed = true; } )
( this.sourceId = id() )?
}
private void subgraph():
{
}
{
( id() )? ( statement() )*
}
private String id():
{
Token t;
String id;
}
{
(
t =
{
id = t.image.substring(1, t.image.length() - 1);
}
| t =
{
id = t.image;
}
| t =
{
id = t.image;
}
)
{ return id; }
}
private void statement():
{
}
{
(LOOKAHEAD(3)
edgeStatement()
| nodeStatement()
| attributeStatement()
| subgraph()
)
";"
}
private void nodeStatement():
{
String nodeId;
String [] port;
HashMap attr = null;
port = null;
}
{
nodeId = id() ( port = port() )? ( attr = attributesList() )?
{ addNode(nodeId, port, attr); }
}
private String compassPoint():
{
Token pt = null;
}
{
( pt = "n"
| pt = "ne"
| pt = "e"
| pt = "se"
| pt = "s"
| pt = "sw"
| pt = "w"
| pt = "nw"
| pt = "c"
| pt = "_"
)
{return pt.image;}
}
private String [] port():
{
String [] p = { null, null };
}
{
( p [0] = id() ( p [1] = compassPoint() )?
| p [1] = compassPoint()
)
{return p;}
}
private void edgeStatement():
{
String id;
LinkedList edges = new LinkedList();
HashMap attr = null;
}
{
id = id() { edges.add(id); }
edgeRHS(edges)
( attr = attributesList() )?
{ addEdges(edges, attr); }
}
private void edgeRHS(LinkedList edges):
{
Token t;
String i;
}
{
t = { edges.add(t.image); }
i = id() { edges.add(i); }
( edgeRHS(edges) )?
}
private void attributeStatement():
{
Token t;
HashMap attr;
}
{
( t =
| t =
| t =
)
attr = attributesList()
{setGlobalAttributes(t.image, attr);}
}
private HashMap attributesList():
{
HashMap attributes = new HashMap();
}
{
(( attributeList(attributes) ( attributeList(attributes) )* )? )+
{ return attributes; }
}
private void attributeList(HashMap attributes):
{
String key;
Object val;
Token t;
}
{
key = id() { val = Boolean.TRUE; }
(
(LOOKAHEAD(2)
t = { val = Double.parseDouble(t.image); }
| val = id()
)
)?
{attributes.put(key, val);}
}