Thread overview
D Template based paser generator in 137 loc
Jan 04, 2007
BCS
Jan 05, 2007
BCS
Jan 05, 2007
Don Clugston
Jan 05, 2007
BCS
January 04, 2007
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
January 05, 2007
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
January 05, 2007
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.
January 05, 2007
BCS wrote:
> This is a totaly template based system. No external utilities are needed. (* the 137 loc is after removal of all unneeded line)
[snip]

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;
}
January 05, 2007
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;
> }