Anyone interested in a Spirit for D?
Jacques
jpdt at telkomsa.net
Thu Oct 19 12:15:09 PDT 2006
Kristian wrote:
>
> Well, couldn't one use arrays to define actions? For example:
>
> r = make_parser("real_number[0] (',' real_number[1])*");
>
> array[] = {&firstAction, //[0]
> &generalAction //[1]
> };
> r.attach(array);
>
>
> You could also give string ids for actions:
>
> r = make_parser("real_number[myaction] (',' real_number[real])*");
>
> array[] = {"myaction", &firstAction,
> "real", &generalAction
> };
> r.attach(array);
I actually did something similar to this when creating a generic PEG
parser. (http://en.wikipedia.org/wiki/Parsing_Expression_Grammar)
I opted to use the square brackets to denote semantic groups. Each
semantic group has an associated delegate, which performs an action
on the nodes in the group and returns a replacement node for the parse
tree.
The following is part of my calculator test that parses and evaluates an
expression.
auto c = new RuleSet();
// Number.create creates a number object from a string.
c.addRegex("Number",
"\s*(([\+\-])*([0-9]+)(\.([0-9]*))?(([eE])([\+\-]*)([0-9]+))?)\s*",
&Number.create);
c.addRegex("Identifier", r"\s*([a-zA-Z_]\w*)\s*");
c.addRule("Statement", "Assignment / Expression");
c.addRule("Assignment", r"[Identifier '=' Expression]",
// assign value to variable
delegate Node(Node[] n) {
// All this casting feels a bit clunky!
char[] s = (cast(RegexNode)n[0]).match[1];
vars[s] = (cast(Number)n[2]).eval();
return new Number(vars[s]);
});
c.addRule("Expression", "[Term (('+' / '-') Term)*]",
// perform addition and subtraction
delegate Node(Node[] n) {
...
});
c.addRule("Term", "[Factor (('*' / '/') Factor)*]",
// perform multiplication and division
delegate Node(Node[] n) {
...
});
c.addRule("Factor", "Number / [Identifier] / ['(' Expression ')']",
// Get value of identifier
delegate Node(Node[] n) {
...
},
// 2 is a shortcut for returning 2nd node in semantic group.
// The expression itself in this case.
2);
auto p = new Parser(c);
Its all runtime as my templating abilities arent up to the task. A
compile time version will be fun though!
More information about the Digitalmars-d
mailing list