cb.parser.PetalParser.jj Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.crazybeans Show documentation
Show all versions of org.crazybeans Show documentation
Java library to read, modify or create Rational Rose petal files
The newest version!
options {
STATIC = true;
OPTIMIZE_TOKEN_MANAGER = true;
CACHE_TOKENS = true;
COMMON_TOKEN_ACTION = true;
}
PARSER_BEGIN(PetalParser)
package cb.parser;
import cb.petal.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Stack;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Collections;
/**
* Parser for Rational Rose Petal files. Generated with
*< href="http://javacc.dev.java.net/">JavaCC.
*
* @version $Id: PetalParser.jj,v 1.17 2003/11/20 14:54:30 dahm Exp $
* @author M. Dahm
*/
public class PetalParser {
private static PetalNode current_parent = null;
private static Stack parent_stack = new Stack(); // Stack
private static ArrayList docs = new ArrayList(); // Reused list to collect doc strings
private static PetalParser instance;
private static ObjectFactory factory = ObjectFactory.getInstance();
private static java.util.List ignored_nodes = Collections.EMPTY_LIST;
public static PetalFile parse(String file_name)
throws IOException, ParseException
{
return parse(new File(file_name));
}
public static PetalFile parse(java.net.URL url)
throws IOException, ParseException
{
return parse(url.openStream());
}
public static PetalFile parse(File file)
throws IOException, ParseException
{
PetalFile tree = parse(new FileInputStream(file));
String name = file.getName();
int index = name.lastIndexOf('.');
if(index > 0)
name = name.substring(0, index);
tree.setModelName(name);
return tree;
}
public static PetalFile parse(InputStream stream) throws ParseException, IOException {
if(instance == null)
instance = new PetalParser(stream);
else
instance.ReInit(stream);
return instance.parse();
}
private static void saveParent(PetalNode new_parent) {
parent_stack.push(current_parent);
current_parent = new_parent;
}
private static void restoreParent() {
current_parent = (PetalNode)parent_stack.pop();
}
/** If the parser finds such a node while building the petal tree, the node
* will be ignored and not added to the tree. E.g, setIgnoredNodes(Diagram.class) will
* abandon all diagrams of the model.
*/
public static void setIgnoredNodes(java.lang.Class[] nodes) {
ignored_nodes = new ArrayList(Arrays.asList(nodes));
}
public static java.lang.Class[] getIgnoredNodes() {
java.lang.Class[] nodes = new java.lang.Class[ignored_nodes.size()];
ignored_nodes.toArray(nodes);
return nodes;
}
private static boolean ignored(PetalNode obj) {
for(Iterator i = ignored_nodes.iterator(); i.hasNext(); ) {
java.lang.Class clazz = (java.lang.Class)i.next();
if(clazz.isInstance(obj)) {
return true;
}
}
return false;
}
}
PARSER_END(PetalParser)
TOKEN_MGR_DECLS: {
static void CommonTokenAction(Token t) {
t.image = t.image.intern(); // Save memory ...
}
}
SKIP : /* WHITE SPACE */
{
" " | "\t" | "\f"
}
/* \r and \n are not just skipped because they may be significant
* in recognizing multi-line strings (starting with |)
*/
SPECIAL_TOKEN : { | }
/** Top level construct are always petal and design objects
*/
PetalFile parse() :
{
PetalObject petal, design;
PetalFile file = new PetalFile();
current_parent = file;
}
{
petal = parseObject()
design = parseObject()
{
file.setPetal((Petal)petal);
file.setDesign((Design)design);
return file;
}
}
/* Example: (object ClassView "Class" "Use Case View::Student" @76
* location (160, 176))
*/
PetalObject parseObject() :
{
PetalObject obj;
Token t1, t2=null, t3=null, t4=null;
PetalNode prop;
PetalNode parent = ignored(current_parent)? null : current_parent;
docs.clear();
}
{
/* Object header
*/
"(object" t1 =
(t2 = { docs.add(t2.image); })*
[t3 = ] {
obj = factory.createObject(parent, t1.image, docs,
t3 == null? null : t3.image);
saveParent(obj);
}
/* List of properties
*/
(t4 =
prop = parseValue()
{
if(prop != null)
obj.addProperty(t4.image, prop);
})*
")"
{
restoreParent();
if(!ignored(obj)) {
obj.init();
return obj;
} else
return null;
}
}
PetalNode parseValue() :
{
PetalNode p;
}
{
( (p = parseObject())
| (p = parseList())
| LOOKAHEAD(2) (p = parseLiteral())
| (p = parseTuple())
| (p = parseValueObject()))
{
return p;
}
}
/* Example: (list unit_reference_list (object Module_Diagram "Main"
* quid "35CB163B03CF"))
*
*/
List parseList() :
{
List list;
Token t=null;
PetalNode obj;
}
{
"(list" [t = ] {
list = factory.createList(t == null ? null : t.image);
}
(obj = parseValue() {
if(obj != null)
list.add(obj);
})*
")"
{
return list;
}
}
Value parseValueObject() :
{
StringLiteral str;
Token t1;
Value value;
}
{
"(value" t1 = str = parseString() ")"
{
value = factory.createValue(t1.image, str);
return value;
}
}
Tuple parseTuple() :
{
Token t1, t2;
}
{
"(" t1 = t2 = ")"
{
return factory.createTuple(t1.image, t2.image);
}
}
PetalNode parseLiteral() :
{
Token t, t1, t2;
StringLiteral str;
}
{
str = parseString() { return str; }
|
t = { return factory.createInteger(t.image); }
|
t = { return factory.createFloat(t.image); }
|
t = { return factory.createBoolean(t.image); }
|
t = { return factory.createTag(t.image); }
|
"(" t1 = "," t2 = ")"
{
return factory.createLocation(t1.image, t2.image);
}
}
StringLiteral parseString() :
{
Token t;
}
{
t = { return factory.createString(t.image, false); }
|
t = { return factory.createString(t.image, true); }
}
TOKEN : /* LITERALS */
{
< INTEGER: ()+ >
|
< FLOAT: ()+ "." ()* >
|
< BOOLEAN: ("FALSE" | "TRUE") >
|
< IDENTIFIER: (|)* >
|
< TAG: "@" ()+ >
|
< STRING: ("\"") ()* ("\"") >
|
/* Parse special case, like in:
* (value Text
* |// $package
* |#include "$file"
* |
* )
*/
< MULTI_STRING: ("|" ()* (|))+ >
|
< #IN_STRING: ((~["\"","\\","\n","\r"])
| ("\\"
( ["n","t","b","r","f","\\","'","\""]
| ["0"-"7"] ( ["0"-"7"] )?
| ["0"-"3"] ["0"-"7"] ["0"-"7"]
)
)
) >
|
< #LETTER: [ "a"-"z", "A"-"Z", "_", "$" ] >
|
< #ANY: ~["\n","\r"] >
|
< #DIGIT: [ "0"-"9"] >
|
< #PLUSMINUS: (["+", "-"])? >
}