tibdoc: edu.berkeley.sbp.jar
$(java) -cp $< edu.berkeley.sbp.tib.TibDoc \
tests/tibdoc.g \
- tests/input.tibdoc
+ tests/tib.in
demo: edu.berkeley.sbp.jar
$(java) -cp $< edu.berkeley.sbp.misc.Demo \
import java.io.*;
public class Demo {
+
+ public static boolean harsh = false;
+
public static void main(String[] s) throws Exception {
+
+ ReflectiveMeta m = new ReflectiveMeta();
Tree<String> res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1();
-
- ReflectiveMeta m =
- new ReflectiveMeta(MG.class,
- new Class[] {
- MG.Grammar.class,
- MG.NonTerminal.class,
- MG.AnonUn.class,
- MG.Range.class,
- MG.El.class,
- MG.Seq.class,
- MG.NonTerminalReference.class,
- MG.StringLiteral.class,
- MG.Tree.class,
- MG.CharClass.class
- });
MetaGrammar.Meta.MetaGrammarFile mgf = m.new MetaGrammarFile(res);
MetaGrammar.BuildContext bc = new MetaGrammar.BuildContext(mgf);
Union meta = mgf.get("s").build(bc);
-
System.err.println("parsing " + s[1]);
Tree t = new CharParser(meta).parse(new FileInputStream(s[1])).expand1();
System.out.println("tree:\n" + t.toPrettyString());
public static class ReflectiveMeta extends MetaGrammar.Meta {
private final Class _cl;
private final Class[] _inner;
+ public ReflectiveMeta() {
+ this(MG.class,
+ new Class[] {
+ MG.Grammar.class,
+ MG.NonTerminal.class,
+ MG.AnonUn.class,
+ MG.Range.class,
+ MG.El.class,
+ MG.Seq.class,
+ MG.NonTerminalReference.class,
+ MG.StringLiteral.class,
+ MG.Tree.class,
+ MG.CharClass.class
+ });
+ }
public ReflectiveMeta(Class c, Class[] inner) {
this._cl = c;
this._inner = inner;
}
};
}
- public Sequence resolveTag(String tag, String nonTerminalName, Element[] els, Object[] labels, boolean[] drops) {
+ public Sequence tryResolveTag(String tag, String nonTerminalName, Element[] els, Object[] labels, boolean[] drops) {
Production p = new Production(tag, nonTerminalName, els, labels, drops);
for(Method m : _cl.getMethods())
if (new TargetMethod(m).isCompatible(p))
for(Class c : _inner)
if (new TargetClass(c).isCompatible(p))
return new TargetClass(c).makeSequence(p);
- throw new RuntimeException("could not find a Java method/class/ctor matching tag \""+tag+"\", nonterminal \""+nonTerminalName+"\" with " + els.length + " arguments");
+ return null;
+ }
+ public Sequence resolveTag(String tag, String nonTerminalName, Element[] els, Object[] labels, boolean[] drops) {
+ Sequence ret = tryResolveTag(tag, nonTerminalName, els, labels, drops);
+ if (ret != null) return ret;
+ String message = "could not find a Java method/class/ctor matching tag \""+tag+
+ "\", nonterminal \""+nonTerminalName+"\" with " + els.length + " arguments";
+ if (harsh) {
+ throw new RuntimeException(message);
+ } else {
+ System.err.println(message);
+ return Sequence.rewritingSequence(tag, els, labels, drops);
+ }
}
}
- /*
- public static Object makeFlattener(final Method m, final Element[] els, final Object[] labels, final boolean[] drops) {
- return new Reducer() {
- public Object reduce(Tree t) {
- Object[] o = new Object[m.getParameterTypes()];
- int j = 0;
- for(int i=0; i<els.length; i++)
- }
- };
- }
- */
/**
Union u2 = new Union();
if (sequences.length==1) u2 = u;
for(int j=0; j<group.length; j++) {
- group[j].build(cx, u2);
+ group[j].build(cx, u2, false);
}
if (sequences.length==1) break;
Sequence seq = Sequence.singleton(u2);
this.elements = elements;
return this;
}
- public Sequence build(Context cx, Union u) {
- Sequence ret = build0(cx);
- for(Seq s : and) { Sequence dork = s.build(cx, u); dork.lame = true; ret = ret.and(dork); }
- for(Seq s : not) { Sequence dork = s.build(cx, u); dork.lame = true; ret = ret.not(dork); }
+ public Sequence build(Context cx, Union u, boolean lame) {
+ Sequence ret = build0(cx, lame || this.lame);
+ for(Seq s : and) { Sequence dork = s.build(cx, u, true); ret = ret.and(dork); }
+ for(Seq s : not) { Sequence dork = s.build(cx, u, true); ret = ret.not(dork); }
u.add(ret);
+ ret.lame = lame;
return ret;
}
- public Sequence build0(Context cx) {
+ public Sequence build0(Context cx, boolean lame) {
boolean unwrap = false;
- boolean dropAll = false;
+ boolean dropAll = lame;
if (tag!=null && tag.equals("[]")) unwrap = true;
if (tag!=null && "()".equals(tag)) dropAll = true;
Object[] labels = new Object[elements.length];
public static class Meta {
public Object repeatTag() { return null; }
+ public Sequence tryResolveTag(String s, String nonTerminalName, Element[] els, Object[] labels, boolean [] drops) {
+ //return resolveTag(s, nonTerminalName, els, labels, drops);
+ return null;
+ }
public Sequence resolveTag(String s, String nonTerminalName, Element[] els, Object[] labels, boolean [] drops) {
return Sequence.rewritingSequence(s, els, labels, drops);
}
boolean dropAll = false;
if (tag!=null && tag.equals("[]")) unwrap = true;
if (tag!=null && "()".equals(tag)) dropAll=true;
+
+ NonTerminal old = bc.currentNonTerminal;
+ bc.currentNonTerminal = null;
for(int i=0; i<elements.length; i++) {
int j = separator==null ? i : i*2;
els[j] = elements[i].build(bc);
drops[j+1] = true;
}
}
+ bc.currentNonTerminal = old;
+
Sequence ret = null;
if (dropAll) ret = Sequence.drop(els, false);
else if (unwrap) ret = Sequence.unwrap(els, repeatTag(), drops);
ret = resolveTag(tag, bc.currentNonTerminal==null ? null : bc.currentNonTerminal.name, els, labels, drops);
System.err.println("resolvetag " + tag + " => " + ret);
} else {
- int idx = -1;
- for(int i=0; i<els.length; i++)
- if (!drops[i])
- if (idx==-1) idx = i;
- else throw new Error("multiple non-dropped elements in sequence: " + Sequence.drop(els,false));
- if (idx != -1) ret = Sequence.singleton(els, idx);
- else ret = Sequence.drop(els, false);
+ ret = tryResolveTag(tag, bc.currentNonTerminal==null ? null : bc.currentNonTerminal.name, els, labels, drops);
+ if (ret==null) {
+ int idx = -1;
+ for(int i=0; i<els.length; i++)
+ if (!drops[i])
+ if (idx==-1) idx = i;
+ else throw new Error("multiple non-dropped elements in sequence: " + Sequence.drop(els,false));
+ if (idx != -1) ret = Sequence.singleton(els, idx);
+ else ret = Sequence.drop(els, false);
+ }
}
if (this.followedBy != null)
ret.follow = infer(this.followedBy.build(bc));
//System.err.println("MetaClause.makeMetaClause("+t+")");
if (t==null) return new Epsilon();
if (t.head()==null) return new Epsilon();
- if (t.head().equals("{")) throw new Error("metatree: " + t);
+ if (t.head().equals("{")) return new MetaTree(makeConjunct(t.child(0)));
if (t.head().equals("*")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, null, true, true);
if (t.head().equals("+")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, null, false, true);
if (t.head().equals("?")) return new MetaRepeat(makeMetaClause(t.child(0), c), false, null, true, false);
public String toString() { return "( " + body + " )"; }
public Element build(BuildContext bc) { return body.buildAnon(bc); }
}
- /*
- public static class MetaTree extends MetaClause {
+
+ public class MetaTree extends MetaClause {
public Conjunct body;
- public MetaTree(Tree<String> t) { this.body = makeConjunct(t); }
+ public MetaTree(Conjunct c) { this.body = c; }
public String toString() { return "{ " + body + " }"; }
public Element build(BuildContext bc) {
- return new Union("{}");// body.buildSequence();
+ Union u = new Union();
+ Union u2 = new Union();
+ Sequence seq = body.buildSequence(bc);
+ u2.add(seq);
+ u.add(Sequence.singleton(new Element[] { CharRange.leftBrace,
+ new NonTerminalReference("ws").build(bc),
+ u2,
+ new NonTerminalReference("ws").build(bc),
+ CharRange.rightBrace }
+ , 2));
+ //u.add(seq);
+ return u;
}
}
- */
+
public class MetaRange extends MetaClause {
Range.Set range = new Range.Set();
public String toString() { return range.toString(); }
public class NonTerminalReference extends MetaClause {
public String name;
public NonTerminalReference(Tree<String> name) { this.name = string(name); }
+ public NonTerminalReference(String name) { this.name = name; }
public Element build(BuildContext bc) { return bc.build(name); }
public String toString() { return name; }
}
import edu.berkeley.sbp.chr.*;
import java.util.*;
import java.io.*;
+import static edu.berkeley.sbp.misc.Demo.*;
public class TibDoc {
/*
- // Main //////////////////////////////////////////////////////////////////////////////
-
- public static void main(String[] s) throws Exception {
- try {
- System.out.println("parsing " + s[0]);
- Tree<String> res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1();
- MetaGrammar gram = new Tib.Grammar(TibDoc.class);
- gram = (MetaGrammar)gram.walk(res);
- System.out.println("\nparsing " + s[1]);
- Forest f = new CharParser(gram.done()).parse(new Tib(new FileInputStream(s[1])));
- System.out.println();
- System.out.println(f.expand1().toPrettyString());
- System.out.println();
- Doc doc = (Doc)new ReflectiveGrammar(TibDoc.class).build(f.expand1());
- System.out.println(doc);
- System.out.println();
- System.out.println();
- System.out.println();
- System.out.println();
- StringBuffer sb = new StringBuffer();
- doc.toHTML(new ToHTML.HTML(sb));
- System.out.println(sb);
-
- FileOutputStream fos = new FileOutputStream("out.html");
- PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
- p.println(sb);
- p.flush();
- p.close();
-
- } catch (Ambiguous a) {
- FileOutputStream fos = new FileOutputStream("/Users/megacz/Desktop/out.dot");
- PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
- GraphViz gv = new GraphViz();
- a.ambiguity.toGraphViz(gv);
- gv.dump(p);
- p.flush();
- p.close();
- a.printStackTrace();
-
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
*/
/*
*/
+
+ // Main //////////////////////////////////////////////////////////////////////////////
+
+ public static class TD {
+
+ public @nonterminal("Doc") static class Doc {
+ public @arg("head") Header head;
+ public @arg("body") Body body;
+ public String toString() { return "doc:{"+head+","/*+body*/+"}"; }
+ }
+
+ public @nonterminal("Header") static class Header {
+ public @arg("attrs") KV[] attrs;
+ // FIXME: it would be nice to be able to
+ // void kv(String, String) { ... } imperatively
+ public String toString() {
+ StringBuffer ret = new StringBuffer();
+ ret.append("<");
+ for(KV kv : attrs) ret .append(kv);
+ ret.append(">");
+ return ret.toString();
+ }
+ }
+
+ public @nonterminal("Body") static class Body {
+ public Object[] sections;
+ // FIXME: it would be nice to be able to
+ // void kv(String, String) { ... } imperatively
+ public String toString() {
+ StringBuffer ret = new StringBuffer();
+ ret.append("<");
+ for(Object kv : sections) ret .append(kv);
+ ret.append(">");
+ return ret.toString();
+ }
+ }
+
+ public @nonterminal("kv") static class KV {
+ public @arg("key") String key;
+ public @arg("val") Object val;
+ public String toString() { return "KV["+key+"="+val+"]"; }
+ }
+ }
+
+ public static void main(String[] s) throws Exception {
+ try {
+
+ Demo.ReflectiveMeta m =
+ new Demo.ReflectiveMeta(TibDoc.TD.class,
+ new Class[] {
+ TibDoc.TD.Doc.class,
+ TibDoc.TD.Header.class,
+ TibDoc.TD.Body.class,
+ TibDoc.TD.KV.class
+ });
+ Tree<String> res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1();
+ MetaGrammar.Meta.MetaGrammarFile mgf = m.new MetaGrammarFile(res);
+ MetaGrammar.BuildContext bc = new MetaGrammar.BuildContext(mgf);
+ Union tibgram = mgf.get("s").build(bc);
+
+ System.err.println("parsing " + s[1]);
+ Tree t = new CharParser(tibgram).parse(new Tib(new FileInputStream(s[1]))).expand1();
+ System.out.println("tree:\n" + t.toPrettyString());
+
+ Reducer red = (Reducer)t.head();
+ Object result = red.reduce(t);
+ System.out.println((TD.Doc)result);
+ /*
+ System.out.println("parsing " + s[0]);
+ Tree<String> res = new CharParser(MetaGrammar.make()).parse(new FileInputStream(s[0])).expand1();
+ MetaGrammar gram = new Tib.Grammar(TibDoc.class);
+ gram = (MetaGrammar)gram.walk(res);
+ System.out.println("\nparsing " + s[1]);
+ Forest f = new CharParser(gram.done()).parse(new Tib(new FileInputStream(s[1])));
+ System.out.println();
+ System.out.println(f.expand1().toPrettyString());
+ System.out.println();
+ Doc doc = (Doc)new ReflectiveGrammar(TibDoc.class).build(f.expand1());
+ System.out.println(doc);
+ System.out.println();
+ System.out.println();
+ System.out.println();
+ System.out.println();
+ StringBuffer sb = new StringBuffer();
+ doc.toHTML(new ToHTML.HTML(sb));
+ System.out.println(sb);
+
+ FileOutputStream fos = new FileOutputStream("out.html");
+ PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
+ p.println(sb);
+ p.flush();
+ p.close();
+ */
+ } catch (Ambiguous a) {
+ FileOutputStream fos = new FileOutputStream("/Users/megacz/Desktop/out.dot");
+ PrintWriter p = new PrintWriter(new OutputStreamWriter(fos));
+ GraphViz gv = new GraphViz();
+ a.ambiguity.toGraphViz(gv);
+ gv.dump(p);
+ p.flush();
+ p.close();
+ a.printStackTrace();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
}
s = Doc
-Doc = Doc:: head:{Header} body:Body /ws
-Header = Header:: "header" attrs:{ kv */ ws } /ws
-Body = Body:: sections:(Section*/ws)
+Doc = head:{Header} body:Body /ws
+Header = "header" attrs:{ kv */ ws } /ws
+Body = Section*/ws
Section = { Section:: header:SectionHeader paragraphs:Paragraph* /ws }
SectionHeader = "==" SectionHeaderBody "=="
SectionHeaderBody = "=" SectionHeaderBody "="
sp = " "**
blank = !sp "\n" !sp "\n" !ws
-kv = kv:: key:word "=" val:text /ws
+kv = key:word "=" val:text /ws
wp = w++
num = [0-9]++
Paragraph = Blockquote:: { "\"\" " text }
onums = nums !(". "|") ")
any = ~[]*
-uli = "* " (!ws text &~ any (oli|uli))
-oli = !("# "|onums) (!ws text &~ any (oli|uli))
+uli = "* " (!ws text &~ any !(oli|uli))
+oli = !("# "|onums) (!ws text &~ any !(oli|uli))
text = Item
Itemx = !ws Item
> "[]":: styled Itemx
> "[]":: (Chars:: text:alphanum++) Itemx
> "[]":: "\"" text "\"" Itemx
- > "[]":: symbol Itemx
+// > "[]":: symbol Itemx
> "[]":: (Symbol:: sym++) Itemx
> "[]":: Paragraph Itemx
link = Link:: text:({ text }) "->" href:(url|email)
> Link:: text:alphanum++ !ws "->" href:(url|email)
-structured = command & "\\" [a-zA-Z0-9]++ block?
+structured = command & "\\" !([a-zA-Z0-9]++) block?
> glyph
> email
> url