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

jlibs.nblr.editor.serialize.SyntaxBinding Maven / Gradle / Ivy

/**
 * Copyright 2015 Santhosh Kumar Tekuri
 *
 * The JLibs authors license this file to you under the Apache License,
 * version 2.0 (the "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at:
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 */

package jlibs.nblr.editor.serialize;

import jlibs.nblr.Syntax;
import jlibs.nblr.actions.*;
import jlibs.nblr.matchers.*;
import jlibs.nblr.rules.Edge;
import jlibs.nblr.rules.Node;
import jlibs.nblr.rules.Rule;
import jlibs.nblr.rules.RuleTarget;
import jlibs.xml.sax.binding.*;
import org.xml.sax.Attributes;

import javax.xml.namespace.QName;
import java.util.List;

/**
 * @author Santhosh Kumar T
 */
@Binding("syntax")
public class SyntaxBinding extends Matchers{
    static ThreadLocal SYNTAX = new ThreadLocal();
    static Rule getRule(String name){
        Syntax syntax = SyntaxBinding.SYNTAX.get();
        Rule rule = syntax.rules.get(name);
        if(rule==null){
            rule = new Rule();
            rule.name = name;
            syntax.add(name, rule);
        }
        return rule;
    }

    @Binding.Start
    public static Syntax onStart(){
        Syntax syntax = new Syntax();
        SYNTAX.set(syntax);
        return syntax;
    }

    @Binding.Element(element="rule", clazz=RuleBinding.class)
    public static void rule(){}

    @Binding.Start("string-rule")
    public static Rule onStringRule(@Attr String name, @Attr String string){
        Rule rule = SyntaxBinding.getRule(name);
        if(rule.node==null)
            rule.node = new Node();
        rule.addStringBranch(rule.node, string);
        return rule;
    }

    @Relation.Finish({"rule", "string-rule"})
    public static void relateWithRule(Syntax syntax, Rule rule){
        syntax.add(rule.name, rule);
    }

    @Relation.Finish("*")
    public static void relateWithMatcher(Syntax syntax, Matcher matcher){
        syntax.add(matcher.name, matcher);
    }
}

@Binding("matcher")
class MatcherBinding{
    @Binding.Start
    public static Matcher onStart(@Attr String name){
        return SyntaxBinding.SYNTAX.get().matchers.get(name);
    }
}

@Binding("any")
class AnyBinding{
    @Binding.Start
    public static Matcher onStart(@Attr String name, @Attr String javaCode, @Attr String chars){
        Any any = new Any(chars);
        any.name = name;
        any.javaCode = javaCode;
        return any;
    }
}

@Binding("range")
class RangeBinding{
    @Binding.Start
    public static Matcher onStart(@Attr String name, @Attr String javaCode, @Attr String from, @Attr String to){
        Range range = new Range(from.codePointAt(0), to.codePointAt(0));
        range.name = name;
        range.javaCode = javaCode;
        return range;
    }
}

@Binding("not")
class NotBinding extends Matchers{
    @Binding.Start
    public static Attributes onStart(Attributes attrs){
        return attrs;
    }

    @Relation.Finish("*")
    public static void relate(SAXContext parent, Matcher matcher){
        parent.put(new QName("matcher"), matcher);
    }

    @Binding.Finish
    public static Not onFinish(@Temp String name, @Temp String javaCode, @Temp Matcher matcher){
        matcher.usageCount++;
        Not not = new Not(matcher);
        not.name = name;
        not.javaCode = javaCode;
        return not;
    }
}

@Binding("and")
class AndBinding extends Matchers{
    @Binding.Start
    public static Attributes onStart(Attributes attrs){
        return attrs;
    }

    @Relation.Finish("*")
    public static void relate(SAXContext parent, Matcher matcher){
        parent.add(new QName("matchers"), matcher);
    }

    @Binding.Finish
    public static And onFinish(@Temp String name, @Temp String javaCode, @Temp List matchers){
        for(Matcher matcher: matchers)
            matcher.usageCount++;
        And and = new And(matchers.toArray(new Matcher[matchers.size()]));
        and.name = name;
        and.javaCode = javaCode;
        return and;
    }
}

@Binding("or")
class OrBinding extends Matchers{
    @Binding.Start
    public static Attributes onStart(Attributes attrs){
        return attrs;
    }

    @Relation.Finish("*")
    public static void relate(SAXContext parent, Matcher matcher){
        parent.add(new QName("matchers"), matcher);
    }

    @Binding.Finish
    public static Or onFinish(@Temp String name, @Temp String javaCode, @Temp List matchers){
        for(Matcher matcher: matchers)
            matcher.usageCount++;
        Or or = new Or(matchers.toArray(new Matcher[matchers.size()]));
        or.name = name;
        or.javaCode = javaCode;
        return or;
    }
}

class Matchers{
    @Binding.Element(element="matcher", clazz=MatcherBinding.class)
    public static void matcher(){}

    @Binding.Element(element="any", clazz=AnyBinding.class)
    public static void any(){}

    @Binding.Element(element="range", clazz=RangeBinding.class)
    public static void range(){}

    @Binding.Element(element="not", clazz=NotBinding.class)
    public static void not(){}

    @Binding.Element(element="and", clazz=AndBinding.class)
    public static void and(){}

    @Binding.Element(element="or", clazz=OrBinding.class)
    public static void or(){}
}

@Binding("rule")
class RuleBinding{
    @Binding.Start
    public static Rule onStart(@Attr String name){
        return SyntaxBinding.getRule(name);
    }

    @Binding.Element(element="node", clazz=NodeBinding.class)
    public static void node(){}

    @Relation.Finish("node")
    public static @Temp.Add Node relateWithNode(Node node, Rule rule){
        if(rule.node==null)
            rule.node = node;
        return node;
    }

    @Binding.Element(element="edge", clazz=EdgeBinding.class)
    public static void edge(){}

    @Relation.Finish("edge")
    @SuppressWarnings({"unchecked"})
    public static void relateWithEdge(SAXContext parent, @Current Edge edge, @Temp String source, @Temp String target, @Temp String fallback){
        List nodes = (List)parent.get("", "node");
        edge.setSource(nodes.get(Integer.parseInt(source)));
        edge.setTarget(nodes.get(Integer.parseInt(target)));
        edge.fallback = Boolean.valueOf(fallback);
    }
}

@Binding("node")
class NodeBinding{
    @Binding.Start
    public static Node onStart(@Attr String name){
        Node node = new Node();
        node.name = name;
        return node;
    }

    @Binding.Start("buffer")
    public static BufferAction onBuffer(){
        return BufferAction.INSTANCE;
    }

    @Binding.Start("publish")
    public static PublishAction onPublish(@Attr String name, @Attr String begin, @Attr String end){
        return new PublishAction(name, Integer.parseInt(begin), Integer.parseInt(end));
    }

    @Binding.Start("event")
    public static EventAction onEvent(@Attr String name){
        return new EventAction(name);
    }

    @Binding.Start("error")
    public static ErrorAction onError(@Attr String message){
        return new ErrorAction(message);
    }

    @Relation.Start("*")
    public static void relateWithAction(Node node, Action action){
        node.action = action;
    }
}

@Binding("edge")
class EdgeBinding extends Matchers{
    @Binding.Start
    public static Attributes onStart(Attributes attrs){
        return attrs;
    }

    @Binding.Start("rule")
    public static RuleTarget onRuleTarget(@Attr String name, @Attr String node){
        Rule rule = SyntaxBinding.getRule(name);
        RuleTarget ruleTarget = new RuleTarget();
        ruleTarget.rule = rule;
        ruleTarget.name = node;
        return ruleTarget;
    }

    @Relation.Finish("rule")
    public static RuleTarget relateWithRuleTarget(RuleTarget ruleTarget){
        return ruleTarget;
    }

    @Relation.Finish("*")
    public static void relateWithMatcher(SAXContext parent, Matcher matcher){
        parent.put(new QName("matcher"), matcher);
    }

    @Binding.Finish
    public static Edge onFinish(@Temp("rule") RuleTarget ruleTarget, @Temp Matcher matcher){
        Edge edge = new Edge(null, null);
        edge.ruleTarget = ruleTarget;
        edge.matcher = matcher;
        if(matcher!=null)
            matcher.usageCount++;
        return edge;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy