
org.globus.rsl.RSLParser.jj Maven / Gradle / Ivy
The newest version!
options {
STATIC = false;
LOOKAHEAD = 1;
FORCE_LA_CHECK = true;
IGNORE_CASE = true;
}
PARSER_BEGIN(RSLParser)
/*
This file is licensed under the terms of the Globus Toolkit Public
License, found at http://www.globus.org/toolkit/download/license.html.
*/
package org.globus.rsl;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.ListIterator;
/**
* Parser for the
* Globus Resource Specification Language RSL v1.0.
*
* Things that are not supported:
* (1) User-specified delimiter for quoted literals.
* (2) RSLs that only contain relations outside of 'spec-list'.
* Other notes:
* (1) Implicit concatenation is not part of the 'simple value' relation
* and is implemented by inspecting the white space between individual
* values.
*/
public class RSLParser {
private Class nodeClass = RslNode.class;
public static void main(String argv[]) throws ParseException {
if ((argv.length != 0) && (argv.length != 1)) {
System.err.println("Usage: RSL [rsl string]");
System.exit(1);
}
RSLParser parser = null;
if (argv.length == 0) {
parser = new RSLParser(System.in);
} else {
parser = new RSLParser(new StringReader(argv[0]));
}
parser.parse();
}
public static RslNode parse(String rsl) throws ParseException {
return (RslNode)parse(RslNode.class, rsl);
}
public static AbstractRslNode parse(Class rslNodeClass, String rsl)
throws ParseException {
RSLParser parser = new RSLParser(new StringReader(rsl));
parser.setRslNodeClass(rslNodeClass);
return parser.parse();
}
public RSLParser(String rsl)
throws ParseException {
this(new StringReader(rsl));
}
public void setRslNodeClass(Class rslNodeClass) {
nodeClass = rslNodeClass;
}
private String unQuotify(String str, char quoteChar) {
char curChar;
char nextChar;
int size = str.length();
StringBuffer buf = new StringBuffer(size-2);
for (int i=1;i 0) {
valueList.add( concat(tokenList) );
tokenList.clear();
}
}
private String unQuotify(Token tok) {
switch(tok.kind) {
case DOUBLE_QUOTED_LITERAL:
return unQuotify(tok.image,'"');
case SINGLE_QUOTED_LITERAL:
return unQuotify(tok.image,'\'');
default:
return tok.image;
}
}
}
PARSER_END(RSLParser)
SPECIAL_TOKEN :
{
" " | "\t" | "\r" | "\n"
}
SKIP :
{
<"(*" (~["*"])* "*" ("*" | ~["*",")"] (~["*"])* "*")* ")">
}
TOKEN :
{
< EQUAL : "=" > | < NOT_EQUAL : "!=" >
| < GREATER_THAN : ">" > | < GREATER_THAN_EQUAL : ">=" >
| < LESS_THAN : "<" > | < LESS_THAN_EQUAL : "<=" >
| < AND : "&" > | < OR : "|" > | < MULTI : "+" >
| < RPAREN : "(" > | < LPAREN : ")" >
| < VARSTART : "$(" >
| < VARIABLES : "rsl_substitution" | "rslsubstitution" >
| < VARIABLES_DQUOTE : "\"" "rsl_substitution" "\"" | "\"" "rslsubstitution" "\"" >
| < VARIABLES_SQUOTE : "'" "rsl_substitution" "'" | "'" "rslsubstitution" "'" >
| < #CHARACTER : ["a"-"z"] | ["A"-"Z"] >
| < #DIGIT : ["0"-"9"] >
| < #OTHER_CHAR : "_" | "-" >
| < UNQUOTED_LITERAL : (~["+","&","|","(",")","=","<",">",
"!","\"","'","^","#","$","\n","\t"," "])+ >
| < DOUBLE_QUOTED_LITERAL : "\"" (~["\""] | "\"\"")* "\"" >
| < SINGLE_QUOTED_LITERAL : "'" (~["'"] | "''")* "'" >
}
AbstractRslNode parse() :
{ AbstractRslNode tree; }
{
( tree = subSpecification() )
{
return tree;
}
}
void specification(AbstractRslNode parentNode) :
{
AbstractRslNode node;
}
{
( relation(parentNode) )
{
}
| ( node = subSpecification() )
{
parentNode.add(node);
}
}
AbstractRslNode subSpecification() :
{
AbstractRslNode node = null;
try {
node = (AbstractRslNode)nodeClass.newInstance();
} catch(Exception e) {
throw new ParseException("Failed to instantiate rsl node class: " + e.getMessage());
}
}
{
( "&" specList(node) )
{
node.setOperator(RslNode.AND);
return node;
}
| ( "+" specList(node) )
{
node.setOperator(RslNode.MULTI);
return node;
}
| ( "|" specList(node) )
{
node.setOperator(RslNode.OR);
return node;
}
}
void relation(AbstractRslNode node) :
{
String attribute;
int op;
LinkedList values;
Token tok;
Bindings bd;
}
{
( tok = "=" values = bindingSequence() )
{
bd = new Bindings(tok.image);
bd.setValues(values);
node.add(bd);
}
| ( tok = "=" values = bindingSequence() )
{
bd = new Bindings(unQuotify(tok.image,'"'));
bd.setValues(values);
node.add(bd);
}
| ( tok = "=" values = bindingSequence() )
{
bd = new Bindings(unQuotify(tok.image,'\''));
bd.setValues(values);
node.add(bd);
}
| ( attribute = attribute() op = op() values = valueSequence() )
{
NameOpValue nm = new NameOpValue(attribute, op);
nm.setValues(values);
node.add(nm);
}
}
void specList(AbstractRslNode node) :
{
}
{
( "(" specification(node) ")" )+
{
}
}
int op() :
{ Token tok; }
{
( tok = )
{
return NameOpValue.EQ;
}
| (tok = )
{
return NameOpValue.NEQ;
}
| (tok = )
{
return NameOpValue.GT;
}
| (tok = )
{
return NameOpValue.GTEQ;
}
| (tok = )
{
return NameOpValue.LT;
}
| (tok = )
{
return NameOpValue.LTEQ;
}
}
String attribute() :
{ String name; }
{
( name = stringLiteral() )
{
return name;
}
}
LinkedList valueSequence() :
{
LinkedList list = new LinkedList();
LinkedList tokenList = new LinkedList();
}
{
( value(list, tokenList) )+
{
if (tokenList.size() > 0) {
list.add( concat(tokenList) );
}
return list;
}
}
LinkedList bindingSequence() :
{
LinkedList list = new LinkedList();
}
{
( binding(list) )+
{
return list;
}
}
void binding(LinkedList list) :
{
Value value;
String name;
}
{
( "(" name = stringLiteral() value = concatSimpleValue() ")" )
{
Binding db = new Binding(name, value);
list.add(db);
}
}
void value(LinkedList list, LinkedList tokenList) :
{
Object value = null;
}
{
( "(" value = valueSequence() ")" )
{
list.add(value);
}
| ( value = SimpleValue(list, tokenList) )
{
tokenList.add(value);
}
}
Value SimpleValue(LinkedList valueList, LinkedList tokenList) :
{
Token t1 = null;
Value v1 = null;
Value v2 = null;
}
{
( t1 = stringToken() v2 = explicitConcat(valueList, tokenList) )
{
updateValueList(t1, valueList, tokenList);
Value v = new Value( unQuotify(t1) );
if (v2 != null) {
v.concat(v2);
}
return v;
}
| ( v1 = variableReference(valueList, tokenList) v2 = explicitConcat(valueList, tokenList) )
{
if (v2 != null) {
v1.concat(v2);
}
return v1;
}
}
Value variableReference(LinkedList valueList, LinkedList tokenList) :
{
String name = null;
Value value = null;
Token t1;
}
{
( t1 = name = stringLiteral() [ value = concatSimpleValue() ] ")" )
{
updateValueList(t1, valueList, tokenList);
VarRef vr = new VarRef(name);
if (value != null) vr.setDefaultValue(value);
return vr;
}
}
Value explicitConcat(LinkedList valueList, LinkedList tokenList) :
{
Object v1 = null;
Value v2 = null;
}
{
[ "#" ( v1 = stringLiteral() | v1 = variableReference(valueList, tokenList) ) v2 = explicitConcat(valueList, tokenList) ]
{
Value v = null;
if (v1 instanceof String) {
v = new Value( (String)v1);
} else if (v1 instanceof Value) {
v = (Value)v1;
}
if (v2 != null) {
v.concat(v2);
}
return v;
}
}
Token stringToken() :
{ Token tok; }
{
( tok = )
{
return tok;
}
| ( tok = )
{
return tok;
}
| ( tok = )
{
return tok;
}
}
String stringLiteral() :
{ Token tok; }
{
( tok = )
{
return tok.image;
}
| ( tok = )
{
return unQuotify(tok.image,'"');
}
| ( tok = )
{
return unQuotify(tok.image,'\'');
}
}
// -----------------------------------------------------
Value concatSimpleValue() :
{
LinkedList list = new LinkedList();
LinkedList tokenList = new LinkedList();
}
{
( concatSimpleValueSub(list, tokenList) )+
{
if (tokenList.size() > 0) {
list.add( concat(tokenList) );
}
if (list.size() == 1) {
return (Value)list.getFirst();
} else {
throw new ParseException("Encountered sequence instead of a single value.");
}
}
}
void concatSimpleValueSub(LinkedList list, LinkedList tokenList) :
{
Object value = null;
}
{
( value = SimpleValue(list, tokenList) )
{
tokenList.add(value);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy