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