PARSER_BEGIN(PetalParser)
package cb.parser;
import cb.petal.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Stack;
/**
* Parser for Rational Rose Petal files.
*
* @version $Id: PetalParser.jj,v 1.11 2001/06/18 15:20:05 dahm Exp $
* @author M. Dahm
*/
public class PetalParser {
private static PetalNode current_parent = null;
private static Stack parent_stack = new Stack(); // Stack
private static PetalParser instance;
private static ObjectFactory factory = ObjectFactory.getInstance();
public static PetalFile parse(String file_name)
throws IOException, ParseException
{
return parse(new FileInputStream(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
{
return parse(new FileInputStream(file));
}
public static PetalFile parse(InputStream stream) throws ParseException {
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();
}
}
PARSER_END(PetalParser)
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;
ArrayList docs = new ArrayList();
Token t1, t2=null, t3=null, t4=null;
PetalNode prop;
}
{
/* Object header
*/
"(object" t1 =
(t2 = { docs.add(t2.image); })*
[t3 = ] {
obj = factory.createObject(current_parent, t1.image, docs,
t3 == null? null : t3.image);
saveParent(obj);
}
/* List of properties
*/
(t4 =
prop = parseValue()
{ obj.addProperty(t4.image, prop); })*
")"
{
restoreParent();
obj.init();
return obj;
}
}
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() { 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: (["+", "-"])? >
}