www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - D Template based paser generator in 137 loc

reply BCS <BCS pathlink.com> writes:
This is a totaly template based system. No external utilities are 
needed. (* the 137 loc is after removal of all unneeded line)

Here is a slightly compressed use case:

struct set
{
/******* action code ********/
static PObject Action(char[] string : "MULTIPLY")(PObject[3] set)
    {...}
static PObject Action(char[] string : "SUM"     )(PObject[3] set)
    {...}
static PObject Action(char[] string : "PASS"    )(PObject[1] set)
    {...}

/******** Terminal code *********/
static PObject Terminal(char[] name : "NUM")(IParser p)  {...}
static PObject Terminal(char[] name : "PLUS")(IParser p) {...}
static PObject Terminal(char[] name : "TIMES")(IParser p){...}

// "ADD" indecates the root rule

mixin Parser!("ADD",
     "PRIMARY:PASS/NUM;
      MUL:MULTIPLY/PRIMARY TIMES MUL|PASS/PRIMARY;
      ADD:SUM/MUL PLUS ADD|PASS/MUL;");
}

void main()
{
    auto a = new ExpGrammer;
    a.data = "1 + 3 * 4 + 5 * 5 ";

    Value v = cast(Value)set.Parser(a);

    assert(v !is null);
    writef("%d\n", v.value);
}


full example here:

http://www.webpages.uidaho.edu/~shro8822/exp_grammer.d

full code here:

http://www.webpages.uidaho.edu/~shro8822/dparse.d
Jan 04 2007
next sibling parent reply Chris Nicholson-Sauls <ibisbasenji gmail.com> writes:
BCS wrote:
 This is a totaly template based system. No external utilities are 
 needed. (* the 137 loc is after removal of all unneeded line)
 
 Here is a slightly compressed use case:
 
 struct set
 {
 /******* action code ********/
 static PObject Action(char[] string : "MULTIPLY")(PObject[3] set)
    {...}
 static PObject Action(char[] string : "SUM"     )(PObject[3] set)
    {...}
 static PObject Action(char[] string : "PASS"    )(PObject[1] set)
    {...}
 
 /******** Terminal code *********/
 static PObject Terminal(char[] name : "NUM")(IParser p)  {...}
 static PObject Terminal(char[] name : "PLUS")(IParser p) {...}
 static PObject Terminal(char[] name : "TIMES")(IParser p){...}
 
 // "ADD" indecates the root rule
 
 mixin Parser!("ADD",
     "PRIMARY:PASS/NUM;
      MUL:MULTIPLY/PRIMARY TIMES MUL|PASS/PRIMARY;
      ADD:SUM/MUL PLUS ADD|PASS/MUL;");
 }
 
 void main()
 {
    auto a = new ExpGrammer;
    a.data = "1 + 3 * 4 + 5 * 5 ";
 
    Value v = cast(Value)set.Parser(a);
 
    assert(v !is null);
    writef("%d\n", v.value);
 }
 
 
 full example here:
 
 http://www.webpages.uidaho.edu/~shro8822/exp_grammer.d
 
 full code here:
 
 http://www.webpages.uidaho.edu/~shro8822/dparse.d

Quite impressive! Find a way to implement optional/repeated items, and grouping, and you've got one heck of a tool there. (It's useful now, mind you, for simple grammars.) -- Chris Nicholson-Sauls
Jan 04 2007
parent BCS <nothing pathlink.com> writes:
Chris Nicholson-Sauls wrote:
 BCS wrote:
 This is a totaly template based system. No external utilities are 
 needed. (* the 137 loc is after removal of all unneeded line)


 
 Quite impressive! 

Thank you
 Find a way to implement optional/repeated items, and 
 grouping, and you've got one heck of a tool there.  (It's useful now, 
 mind you, for simple grammars.)
 
 -- Chris Nicholson-Sauls

Yah, it sort of like a Turing machine. It can do any context free grammar (I think) but some are a bit harder. One advantage of skipping optional/repeated items is it make the Action rules easier for the user to define.
Jan 04 2007
prev sibling parent reply Don Clugston <dac nospam.com.au> writes:
BCS wrote:
 This is a totaly template based system. No external utilities are 
 needed. (* the 137 loc is after removal of all unneeded line)

A beautiful piece of work. The use of default template value arguments to distinguish actions is an act of genius. Incidentally, the technique can be used for classes as well, allowing you to instantiate a class from a string literal. There's lots of potential here. --- class ReflectableObject(char [] reflectionName) { static assert(0, "Undeclared class"); } class ReflectableObject(char [] reflectionName : "Animal") { int numberOfLegs; } class ReflectableObject(char [] reflectionName : "Dog") : ReflectableObject!("Animal") { int dog; } class ReflectableObject(char [] reflectionName : "Cat") : ReflectableObject!("Animal") { int cat; } void main() { auto x = new ReflectableObject!("Dog"); x.numberOfLegs=7; x.dog = 53; // OK: animal is a base class of Dog. ReflectableObject!("Animal") y = x; // Won't compile, because a Dog isn't a Cat. ReflectableObject!("Cat") z = x; }
Jan 05 2007
parent BCS <nothing pathlink.com> writes:
Don Clugston wrote:
 
 A beautiful piece of work.
 The use of default template value arguments to distinguish actions is an 
 act of genius.
 
 Incidentally, the technique can be used for classes as well, allowing 
 you to instantiate a class from a string literal.
 There's lots of potential here.

SWEET!!!
 ---
 class ReflectableObject(char [] reflectionName) {
     static assert(0, "Undeclared class");
 }
 
 class ReflectableObject(char [] reflectionName : "Animal") {
   int numberOfLegs;
 }
 
 class ReflectableObject(char [] reflectionName : "Dog") : 
 ReflectableObject!("Animal") {
  int dog;
 }
 
 class ReflectableObject(char [] reflectionName : "Cat") : 
 ReflectableObject!("Animal")  {
  int cat;
 }
 
 
 void main()
 {
    auto x = new ReflectableObject!("Dog");
    x.numberOfLegs=7;
    x.dog = 53;
 
 // OK: animal is a base class of Dog.
   ReflectableObject!("Animal") y = x;
 
   // Won't compile, because a Dog isn't a Cat.
   ReflectableObject!("Cat") z = x;
 }

Jan 05 2007