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