at.newmedialab.ldpath.parser.rdfpath.jj Maven / Gradle / Ivy
options
{
STATIC=false;
// LOOKAHEAD=5;
CACHE_TOKENS=true;
// FORCE_LA_CHECK=true;
// CHOICE_AMBIGUITY_CHECK=5;
LOOKAHEAD=2147483647;
// DEBUG_PARSER=true;
// DEBUG_TOKEN_MANAGER=true;
// DEBUG_LOOKAHEAD=true;
}
PARSER_BEGIN(RdfPathParser)
package at.newmedialab.ldpath.parser;
import at.newmedialab.ldpath.model.Constants;
import at.newmedialab.ldpath.api.backend.*;
import at.newmedialab.ldpath.api.functions.*;
import at.newmedialab.ldpath.api.selectors.*;
import at.newmedialab.ldpath.api.tests.*;
import at.newmedialab.ldpath.api.transformers.*;
import at.newmedialab.ldpath.model.fields.*;
import at.newmedialab.ldpath.model.functions.*;
import at.newmedialab.ldpath.model.programs.*;
import at.newmedialab.ldpath.model.selectors.*;
import at.newmedialab.ldpath.model.tests.*;
import at.newmedialab.ldpath.model.transformers.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Locale;
import java.util.Collections;
import java.io.Reader;
import java.io.InputStream;
import java.net.URI;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@SuppressWarnings("all")
public class RdfPathParser {
private enum Mode { RULE, SELECTOR, PROGRAM };
private static final Logger log = LoggerFactory.getLogger(RdfPathParser.class);
/**
* A map mapping from namespace prefix to namespace URI
*/
private Map namespaces = new HashMap();
private RDFBackend backend;
private Configuration config;
private Mode mode = Mode.PROGRAM;
public RdfPathParser(RDFBackend backend, Reader in) {
this(backend,null,in);
}
public RdfPathParser(RDFBackend backend, Configuration config, Reader in) {
this(in);
this.backend = backend;
if(config == null) {
this.config = new DefaultConfiguration();
} else {
this.config = config;
}
initialise();
}
public RdfPathParser(RDFBackend backend, InputStream in) {
this(backend,null,in);
}
public RdfPathParser(RDFBackend backend, Configuration config, InputStream in) {
this(in);
this.backend = backend;
if(config == null) {
this.config = new DefaultConfiguration();
} else {
this.config = config;
}
initialise();
}
public RdfPathParser(RDFBackend backend, InputStream in, String encoding) {
this(backend,null,in,encoding);
}
public RdfPathParser(RDFBackend backend, Configuration config, InputStream in, String encoding) {
this(in,encoding);
this.backend = backend;
if(config == null) {
this.config = new DefaultConfiguration();
} else {
this.config = config;
}
initialise();
}
public Program parseProgram() throws ParseException {
namespaces.clear();
namespaces.putAll(config.getNamespaces());
mode = Mode.PROGRAM;
try {
return Program();
} catch(TokenMgrError error){
throw new ParseException("Unable to parse Program: (Message: "+error.getMessage()+")");
}
}
public NodeSelector parseSelector(Map ctxNamespaces) throws ParseException {
namespaces.clear();
namespaces.putAll(config.getNamespaces());
if(ctxNamespaces != null) {
namespaces.putAll(ctxNamespaces);
}
mode = Mode.SELECTOR;
try {
return Selector();
} catch(TokenMgrError error){
throw new ParseException("Unable to parse Selector: (Message: "+error.getMessage()+")");
}
}
public FieldMapping parseRule(Map ctxNamespaces) throws ParseException {
namespaces.clear();
namespaces.putAll(config.getNamespaces());
if(ctxNamespaces != null) {
namespaces.putAll(ctxNamespaces);
}
mode = Mode.RULE;
try {
return Rule();
} catch(TokenMgrError error){
throw new ParseException("Unable to parse Rule: (Message: "+error.getMessage()+")");
}
}
public Node resolveResource(String uri) {
return backend.createURI(uri);
}
public String resolveNamespace(String prefix) throws ParseException {
String uri = namespaces.get(prefix);
if(uri == null) {
throw new ParseException("Namespace "+prefix+" not defined!");
}
return uri;
}
public SelectorFunction getFunction(String uri) throws ParseException {
if(xsdNodeFunctionMap.get(uri) != null) {
return xsdNodeFunctionMap.get(uri);
} else {
throw new ParseException("function with URI "+uri+"does not exist");
}
}
public NodeTransformer,Node> getTransformer(String uri) throws ParseException {
if(xsdNodeTransformerMap.get(uri) != null) {
return xsdNodeTransformerMap.get(uri);
} else {
throw new ParseException("transformer with URI "+uri+"does not exist");
}
}
private void initialise() {
initTransformerMappings();
initFunctionMappings();
}
/**
* Register the function passed as argument in this parser's function map.
*/
public void registerFunction(SelectorFunction function) {
registerFunction(xsdNodeFunctionMap,function);
}
/**
* Register the result transformer passed as argument for the given type uri.
*/
public void registerTransformer(String typeUri, NodeTransformer,Node> transformer) {
xsdNodeTransformerMap.put(typeUri,transformer);
}
/**
* A map mapping from XSD types to node transformers.
*/
private Map> xsdNodeTransformerMap;
private void initTransformerMappings() {
Map> transformerMap = new HashMap>();
transformerMap.putAll(config.getTransformers());
xsdNodeTransformerMap = transformerMap;
}
private Map> xsdNodeFunctionMap;
private void initFunctionMappings() {
Map> functionMap = new HashMap>();
functionMap.putAll(config.getFunctions());
xsdNodeFunctionMap = functionMap;
}
private void registerFunction(Map> register, final SelectorFunction function) {
register.put(Constants.NS_LMF_FUNCS + function.getPathExpression(backend), function);
}
}
PARSER_END(RdfPathParser)
SKIP :
{
" "
| "\r"
| "\t"
| "\n"
}
MORE:
{
"\"" : WithinString
}
TOKEN:
{
: DEFAULT
}
MORE:
{
<~["\n","\r"]>
}
TOKEN : /* OPERATORS */
{
< AND: "&" > |
< OR: "|" > |
< IS: "is" > |
< TYPE: "^^" >
}
TOKEN :
{
< URI: ["a"-"z","A"-"Z"](["a"-"z","A"-"Z","0"-"9","+","-","."])* "://" (["a"-"z","A"-"Z","0"-"9",";","/","?",":","@","&","=","+","$",".","-","_","!","~","*","'","%"])+ ("#" (["a"-"z","A"-"Z","0"-"9",";","/","?",":","@","&","=","+","$",".","-","_","!","~","*","'","%"])*)? | "#" (["a"-"z","A"-"Z","0"-"9",";","/","?",":","@","&","=","+","$",".","-","_","!","~","*","'","%"])+> |
< IDENTIFIER: ["a"-"z","A"-"Z","0"-"9","_"](["a"-"z","A"-"Z","0"-"9","_","'","-"])* > |
< #URICHAR: ["a"-"z","A"-"Z","0"-"9",";","/","?",":","@","&","=","+","$",".","-","_","!","~","*","'","%"] >
}
Program Program() :
{
Program program = new Program();
NodeTest filter = null;
FieldMapping,Node> rule;
Token prefix = null;
Token uri;
NodeSelector boostSelector;
}
{
(
"@prefix" prefix = ":" "<" uri = ">" ";" {
program.addNamespace(prefix.image, uri.image );
namespaces.put(prefix.image,uri.image);
}
)*
(
"@filter" filter = NodeTest() ";" {
program.setFilter(filter);
}
)?
(
"@boost" boostSelector = Selector() ";" {
NodeTransformer transformer = getTransformer(Program.DOCUMENT_BOOST_TYPE);
FieldMapping booster = new FieldMapping("@boost", Program.DOCUMENT_BOOST_TYPE, boostSelector, transformer, null);
program.setBooster(booster);
}
)?
(
rule = Rule()
{
program.addMapping(rule);
}
)*
{
return program;
}
}
FieldMapping Rule() :
{
FieldMapping,Node> rule;
Token name;
String uri;
String type = null;
NodeSelector selector;
NodeTransformer,Node> transformer;
Map conf = null;
}
{
name = "=" selector = Selector() ("::" type = Uri())? ("(" conf = FieldConfig() ")")? ";" {
if(type != null) {
transformer = getTransformer(type);
} else {
transformer = new IdentityTransformer();
}
if(mode != Mode.PROGRAM) {
throw new ParseException("cannot use field names when parsing single paths");
}
rule = new FieldMapping(name.image,type,selector,transformer, conf);
return rule;
}
| uri = Uri() "=" selector = Selector() ("::" type = Uri())? ("(" conf = FieldConfig() ")")? ";" {
if(type != null) {
transformer = getTransformer(type);
} else {
transformer = new IdentityTransformer();
}
if(mode != Mode.PROGRAM) {
throw new ParseException("cannot use field names when parsing single paths");
}
rule = new FieldMapping(uri,type,selector,transformer, conf);
return rule;
}
| selector = Selector() ("::" type = Uri())? ("(" conf = FieldConfig() ")")? (";")? {
if(type != null) {
transformer = getTransformer(type);
} else {
transformer = new IdentityTransformer();
}
if(mode != Mode.PROGRAM && conf != null) {
throw new ParseException("cannot use configuration parameters when parsing single paths");
}
try {
rule = new FieldMapping(selector.getName(backend),type,selector,transformer, conf);
} catch(UnsupportedOperationException ex) {
if(mode == Mode.PROGRAM) {
rule = new FieldMapping("unnamed",type,selector,transformer, conf);
log.error("error while parsing {}: {}", rule.getPathExpression(backend),ex.getMessage());
throw new ParseException("error while parsing "+rule.getPathExpression(backend)+": "+ex.getMessage());
} else {
rule = new FieldMapping("unnamed",type,selector,transformer, conf);
}
}
return rule;
}
}
Map FieldConfig() : {
Map conf = new HashMap();
Token key = null;
String val = null;
Map more = null;
}
{
( key = "=" val = ConfVal() ("," more = FieldConfig() )? )? {
if (key == null || val == null) return null;
conf.put(key.image, val);
if (more != null) {
conf.putAll(more);
}
return conf;
}
}
String ConfVal() : {
Token str, id;
}
{
str = { return str.image.substring(1, str.image.length() -1); }
| id = { return id.image; }
}
String Uri() : {
Token uri, prefix, localName;
}
{
"<" uri = ">" {
return uri.image;
}
| prefix = ":" localName = {
return resolveNamespace(prefix.image)+localName.image;
}
}
NodeSelector Selector() :
{
NodeSelector result;
}
{
(
result = CompoundSelector()
| result = TestingSelector()
| result = AtomicSelector()
)
{
return result;
}
}
NodeSelector CompoundSelector() :
{
NodeSelector result = null;
}
{
(
/* Union Selector */
result = UnionSelector() |
/* Intersection Selector */
result = IntersectionSelector() |
/* Path Selector */
result = PathSelector()
)
{
return result;
}
}
/**
* As path elements, we do not allow arbitrary compound selectors, but we allow all atomic and path selectors.
*/
NodeSelector AtomicOrTestingOrPathSelector() :
{
NodeSelector result = null;
}
{
(
/* Path Selector */
result = PathSelector() |
/* Atomic Selector */
result = AtomicOrTestingSelector()
)
{
return result;
}
}
NodeSelector AtomicOrTestingSelector() :
{
NodeSelector result = null;
}
{
(
/* Testing Selector */
result = TestingSelector() |
/* Atomic Selector */
result = AtomicSelector()
)
{
return result;
}
}
NodeSelector AtomicSelector() :
{
NodeSelector result = null;
}
{
(
/* Self Selector */
result = SelfSelector() |
/* Property Selector */
result = PropertySelector() |
/* Wildcard Selector */
result = WildcardSelector() |
/* Reverse Property Selector */
result = ReversePropertySelector() |
/* Function Selector */
result = FunctionSelector() |
/* String Constant Selector */
result = StringConstantSelector() |
/* Recursive Path Selector */
result = RecursivePathSelector() |
/* Other selector enclosed in braces */
result = GroupedSelector()
)
{
return result;
}
}
NodeSelector SelfSelector() :
{
}
{
"." { return new SelfSelector(); }
}
NodeSelector GroupedSelector() :
{
NodeSelector result = null;
}
{
/* Other selector enclosed in braces */
"(" result = Selector() ")"
{
return result;
}
}
RecursivePathSelector RecursivePathSelector() :
{
RecursivePathSelector result = null;
NodeSelector delegate = null;
}
{
"(" delegate = Selector() ")" "+"
{
result = RecursivePathSelector.getPathSelectorPlused(delegate);
return result;
} |
"(" delegate = Selector() ")" "*"
{
result = RecursivePathSelector.getPathSelectorStared(delegate);
return result;
}
}
PathSelector PathSelector() :
{
PathSelector result = null;
NodeSelector left = null;
NodeSelector right = null;
}
{
left = AtomicOrTestingSelector() "/" right = AtomicOrTestingOrPathSelector()
{
result = new PathSelector(left,right);
return result;
}
}
IntersectionSelector IntersectionSelector() :
{
IntersectionSelector result = null;
NodeSelector left = null;
NodeSelector right = null;
}
{
left = AtomicOrTestingOrPathSelector() "&" right = Selector()
{
result = new IntersectionSelector(left,right);
return result;
}
}
UnionSelector UnionSelector() :
{
UnionSelector result = null;
NodeSelector left = null;
NodeSelector right = null;
}
{
left = AtomicOrTestingOrPathSelector() "|" right = Selector()
{
result = new UnionSelector(left,right);
return result;
}
}
TestingSelector TestingSelector() :
{
TestingSelector result = null;
NodeSelector delegate = null;
NodeTest test = null;
}
{
delegate = AtomicSelector() "[" test = NodeTest() "]" {
result = new TestingSelector(delegate,test);
return result;
}
}
ReversePropertySelector ReversePropertySelector() :
{
ReversePropertySelector result = null;
Node property;
String uri;
}
{
"^" uri = Uri() {
property = resolveResource(uri);
result = new ReversePropertySelector(property);
return result;
}
}
PropertySelector PropertySelector() :
{
PropertySelector result = null;
Node property;
String uri;
}
{
uri = Uri() {
property = resolveResource(uri);
result = new PropertySelector(property);
return result;
}
}
WildcardSelector WildcardSelector() :
{
WildcardSelector result = null;
}
{
"*" {
result = new WildcardSelector();
return result;
}
}
FunctionSelector FunctionSelector() :
{
FunctionSelector result = null;
List arguments = new ArrayList();
NodeSelector argument;
String uri;
Token fName;
}
{
/* Function-Calls without arguments can skip parenthesis */
/* Does not work... why?
"fn:" fName = {
uri = namespaces.get("fn") + fName.image;
result = new FunctionSelector(getFunction(uri),Collections.emptyList());
return result;
} | */
/* Functions do not need to have arguments */
"fn:" fName = "(" ")" {
uri = namespaces.get("fn") + fName.image;
result = new FunctionSelector(getFunction(uri),Collections.emptyList());
return result;
} |
/* Sometimes arguments are required */
"fn:" fName = "("
argument = Selector() { arguments.add(argument); }
( "," argument = Selector() { arguments.add(argument); } )*
")" {
uri = namespaces.get("fn") + fName.image;
result = new FunctionSelector(getFunction(uri),arguments);
return result;
}
}
StringConstantSelector StringConstantSelector() :
{
StringConstantSelector result = null;
Token literal;
}
{
literal = {
result = new StringConstantSelector(literal.image.substring(1, literal.image.length()-1));
return result;
}
}
NodeTest NodeTest() :
{
NodeTest result;
}
{
(
result = AndTest()
| result = OrTest()
| result = AtomicNodeTest()
)
{
return result;
}
}
NodeTest AtomicNodeTest() :
{
NodeTest result;
}
{
(
result = LiteralLanguageTest()
| result = LiteralTypeTest()
| result = PathEqualityTest()
| result = PathTest()
)
{
return result;
}
}
LiteralLanguageTest LiteralLanguageTest():
{
Token lang;
}
{
"@" lang = {
return new LiteralLanguageTest(lang.image);
}
}
LiteralTypeTest LiteralTypeTest():
{
String type;
}
{
"^^" type = Uri() {
return new LiteralTypeTest(type);
}
}
AndTest AndTest():
{
NodeTest left, right;
}
{
left = AtomicNodeTest() "&" right = NodeTest() {
return new AndTest(left,right);
}
}
OrTest OrTest():
{
NodeTest left, right;
}
{
left = AtomicNodeTest() "|" right = NodeTest() {
return new OrTest(left,right);
}
}
PathEqualityTest PathEqualityTest():
{
NodeSelector path;
Node node;
}
{
path = Selector() "is" node = Node() {
return new PathEqualityTest(path,node);
}
}
Node Node():
{
String uri, type = null;
Token literal, language;
}
{
uri = Uri() {
return resolveResource(uri);
}
| literal = ("^^" type = Uri() )? {
try {
return backend.createLiteral(literal.image.substring(1, literal.image.length()-1),null,type == null ? null : new URI(type));
} catch(java.net.URISyntaxException ex) {
throw new ParseException("could not parse type URI "+type+": "+ex.getMessage());
}
}
| literal = "@" language = {
return backend.createLiteral(literal.image.substring(1, literal.image.length()-1),new Locale(language.image),null);
}
}
PathTest PathTest():
{
NodeSelector path;
}
{
(
path = PathSelector()
| path = TestingSelector()
| path = AtomicSelector()
)
{
return new PathTest(path);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy