All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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 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 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 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 rule;
    Token name;
    String uri;
    String type = null;
    NodeSelector selector;
    NodeTransformer 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