!759 static boolean printNulls = true, full = false; static L inputs = toLinesFullTrim([[ hello "hello!" hello you hello < you [hello] [hello] [you] [hello < you] [ ? < Is < it < safe < to < allow [PowerTOP] to [make < all < the < changes < located on < the < Tunables < tab] ] [ I < was < going to < create < a < startup script < for < it ] ]]); static S snlRules = [[ // highest (strongest binding) level = idword = subword ? = idword ! = idword = word = word // juxtaposition on highest level = word // bracketing takes us to highest level [ ] = subword ( ) = subword // < is intermediate = arrows < = arrows = lowest // allow empty here = lowest ]]; static class SNL { S op; new L subs; *() {} *(S op) {} *(S op, L *subs) {} } p { for (S input : inputs) { SNL snl = parseSNL(input); print(); print("PARSING: " + input); print(); print(" " + structure(snl)); print(); } } static SNL parseSNL(S input) { Explain exp = explainFull(input, snlRules, "lowest"); ret explainToSNL(exp); } static SNL explainToSNL(Explain e) { if (e == null) ret null; S c = e.className(); if (eq(c, "word")) ret new SNL(e.string()); exp.sub else { //printStructure(exp.e); printTree(0, exp); } } static void printTree(int indent, Explain e) { if (e == null) { // this would print "null" for every etc if (printNulls) print(indent(indent) + "null"); } else { print(indent(indent) + e.className() + " | " + quote(e.string())); for (Explain sub : e.subs) printTree(indent+2, sub); } }