[e-lang] record syntax for E, please help

Dean Tribble tribble at e-dean.com
Wed Jan 9 01:24:41 EST 2008


It sounds like terms fit what you are asking for:

http://www.erights.org/elang/quasi/terms/

I use term tree extensively (e.g., for parse nodes).  Like XML, they
support schemas, though I typically use terms without schemes.  For
example, the following production from a toy calculator grammar:

E ::= n:N                 -> n
    / "(" a:E "+" b:E ")" -> add a b
    / "(" E "-" E ")"     -> subtract a b;

gets parsed and converted to a term as an intermediate result for me
to walk over, pattern match, etc.:

term`firstChoice(
               seq(bind("n", parse("N", [])),
                   ref("n")),
               seq(data("("),
                   bind("a", parse("E", [])),
                   data("+"),
                   bind("b", parse("E", [])),
                   data(")"),
                   act("add",
                       [ref("a"),
                        ref("b")])),
               seq(data("("),
                   bind("a", parse("E", [])),
                   data("-"),
                   bind("b", parse("E", [])),
                   data(")"),
                   act("subtract",
                       [ref("a"),
                        ref("b")])))`

For code munging, I mostly use term visitors that and so don't have as
much pattern matching as I otherwise might. Term visitors will
dispatch to a method based on the type (functor) of the node.  Thus,
the first couple methods of a visitor to find all free references in
the grammar are:

def findFree extends templateVisitor(findFree) {
            to visit_ref(node, name) {
                def nm := name.getOptString()
                if (! bound.contains(nm)) {
                    free.addElement(nm)
                }
            }
            to visit_bind(node, name, value) {
                bound.push(name.getOptString())
                findFree.visit(value)
            }
       ...
            to visitOther(node) {
                findFree.visitAll(node.getArgs())
            }
        }

visit_ref and visit_bind have the code that will be invoked on on ref
and bind nodes, respectively.  visitOther is special in that it will
be invoked on any node for which there is not a corresponding
visit_<node> method. In this case, it just recursively invokes the
visitor.  Note that I use "name.getOptString()" to just grab the name
string. I could also have pattern matched against the term, but this
was easier at the time.

The terms for the grammar do follow a schema, but I've never actually
defined the schema, so there's no checking against it.


More information about the e-lang mailing list