X-Git-Url: http://git.megacz.com/?p=sbp.git;a=blobdiff_plain;f=src%2Fedu%2Fberkeley%2Fsbp%2Fmeta%2FGrammarAST.java;h=586d519d607defd2cefc7de8d1eefe6c7727c814;hp=046c3ac6a039f1a24110bb0493d62649e6da95a4;hb=f95343b3b6e918434ff68924e79df22b9cb074e8;hpb=5fa948c7db9597445448194418537a1c74f46a27 diff --git a/src/edu/berkeley/sbp/meta/GrammarAST.java b/src/edu/berkeley/sbp/meta/GrammarAST.java index 046c3ac..586d519 100644 --- a/src/edu/berkeley/sbp/meta/GrammarAST.java +++ b/src/edu/berkeley/sbp/meta/GrammarAST.java @@ -96,6 +96,7 @@ public class GrammarAST { if (head.equals("Elements")) return new Seq((ElementNode[])Reflection.rebuild(walkChildren(t), ElementNode[].class)); if (head.equals("NonTerminalReference")) return new ReferenceNode(stringifyChildren(t.child(0))); if (head.equals(")")) return new ReferenceNode(stringifyChildren(t.child(0)), true); + if (head.equals(":")) return new LabelNode(stringifyChildren(t.child(0)), walkElement(t.child(1))); if (head.equals("::")) return walkSeq(t.child(1)).tag(walkString(t.child(0))); if (head.equals("...")) return new DropNode(new RepeatNode(new TildeNode(new AtomNode()), null, true, true, false)); @@ -137,6 +138,7 @@ public class GrammarAST { } if (head.equals("\"\"")) return ""; if (head.equals("\n")) return "\n"; + if (head.equals("\t")) return "\t"; if (head.equals("\r")) return "\r"; if (head.equals("SubGrammar")) return GrammarAST.buildFromAST(t.child(0), "s", resolver); if (head.equals("NonTerminal")) @@ -220,10 +222,18 @@ public class GrammarAST { public abstract Element build(Context cx, NonTerminalNode cnt, boolean dropall); } + /** a union, produced by a ( .. | .. | .. ) construct */ private class UnionNode extends ElementNode { + + /** each component of a union is a sequence */ public Seq[][] sequences; - public String sep = null; + + /** if the union is a NonTerminal specified as Foo*=..., this is true */ public boolean rep; + + /** if the union is a NonTerminal specified as Foo* /ws=..., then this is "ws" */ + public String sep = null; + public UnionNode(Seq seq) { this(new Seq[][] { new Seq[] { seq } }); } public UnionNode(Seq[][] sequences) { this(sequences, false, null); } public UnionNode(Seq[][] sequences, boolean rep, String sep) { @@ -283,6 +293,7 @@ public class GrammarAST { } } + /** a NonTerminal is always a union at the top level */ private class NonTerminalNode extends UnionNode { public boolean alwaysDrop; public String name = null; @@ -295,21 +306,27 @@ public class GrammarAST { public Element build(Context cx, NonTerminalNode cnt, boolean dropall) { return cx.get(name); } } + /** a sequence */ private class Seq { + /** elements of the sequence */ + ElementNode[] elements; + /** follow-set, if explicit */ + ElementNode follow; + /** tag to add when building the AST */ + String tag = null; + /** positive conjuncts */ + HashSet and = new HashSet(); + /** negative conjuncts */ + HashSet not = new HashSet(); public boolean alwaysDrop = false; public boolean isDropped(Context cx) { if (alwaysDrop) return true; if (tag!=null) return false; for(int i=0; i and = new HashSet(); - HashSet not = new HashSet(); - ElementNode[] elements; - ElementNode follow; - String tag = null; public Seq(ElementNode e) { this(new ElementNode[] { e }); } public Seq(ElementNode[] elements) { this(elements, true); } public Seq(ElementNode[] el, boolean check) { @@ -412,6 +429,7 @@ public class GrammarAST { } } + /** reference to a NonTerminal by name */ private class ReferenceNode extends ElementNode { public String nonTerminal; public boolean parenthesized; @@ -439,6 +457,7 @@ public class GrammarAST { } } + /** a literal string */ private class LiteralNode extends ElementNode { private String string; private final String thePrefix = prefix; @@ -460,6 +479,7 @@ public class GrammarAST { public Element build(Context cx, NonTerminalNode cnt, boolean dropall) { return CharAtom.string(string); } } + /** an atom (usually a character class) */ private class AtomNode extends ElementNode { char[][] ranges; public AtomNode() { this(new char[0][]); } @@ -473,6 +493,7 @@ public class GrammarAST { } } + /** a repetition */ private class RepeatNode extends ElementNode { public ElementNode e, sep; public final boolean zero, many, max; @@ -499,6 +520,7 @@ public class GrammarAST { } } + /** helper class for syntactic constructs that wrap another construct */ private abstract class ElementNodeWrapper extends ElementNode { protected ElementNode _e; public ElementNodeWrapper(ElementNode e) { this._e = e; } @@ -507,11 +529,13 @@ public class GrammarAST { public Element build(Context cx, NonTerminalNode cnt, boolean dropall) { return _e.build(cx, cnt, dropall); } } + /** a backtick node indicating that, when building the AST, the node's children should be inserted here */ private class BacktickNode extends ElementNodeWrapper { public BacktickNode(ElementNode e) { super(e); } public boolean isLifted() { return true; } } + /** negation */ private class TildeNode extends ElementNodeWrapper { public TildeNode(ElementNode e) { super(e); } public Atom toAtom(Context cx) { return (Atom)((Topology)_e.toAtom(cx).complement()); } @@ -523,6 +547,12 @@ public class GrammarAST { public boolean isDropped(Context cx) { return true; } } + /** provides a label on the fields of a Seq */ + private class LabelNode extends ElementNodeWrapper { + public final String label; + public LabelNode(String label, ElementNode e) { super(e); this.label = label; } + } + ////////////////////////////////////////////////////////////////////////////// public class Context {