[ Inhalt ] [ Index ]

Next: Statische und dynamische Semantik Up: Codeerzeugung Previous: Konkrete vs. abstrakte Syntax

Der abstrakte Programmbaum

    Wir werden den abstrakten Programmbaum durch C++-Datenstrukturen darstellen. Dazu definieren wir eine abstrakte Basisklasse, die die Schnittstelle unserer syntaktischen Objekte festlegt:

class Node // abstrakte Basisklasse
      {
       protected:
        int nodetype;
       public:
        Node(){};
        virtual ~Node() {};
        virtual void Read() = 0;    // Einlesen von cin
        virtual void Write() = 0;   // Ausgabe auf cout
        virtual int Iswf() = 0;         // stat. Semantik
        virtual void Compile() = 0; // übersetzen
      };
typedef Node *Nodeptr;

class IntNode : public Node
      {private:
        int i;
       public:
        IntNode(int ini = 0);
        ~IntNode();
        void Read();
        void Write();
        friend ostream& operator << (ostream &os, 
                                     const IntNode &n);
        virtual int Iswf();         
        virtual void Compile() = 0; 
      };

class IdNode : public Node
      {private:
        char *name;
       public:
        IdNode(char *n= NULL);
        ~IdNode();
        void Read();
        void Write();
        virtual int Iswf();         
        virtual void Compile(); 
      };

class UnNode : public Node
      {private:
        Nodeptr l;
       public:
        UnNode(Nodeptr il = NULL, int iop = 0);
        ~UnNode();
        void Read();
        void Write();
        virtual int Iswf();         
        virtual void Compile(); 
      };

class BinNode : public Node
      {private:
        Nodeptr l, r;
       public:
        BinNode(Nodeptr il = NULL, 
                int iop = 0, Nodeptr ir = NULL);
        ~BinNode();
        void Read();
        void Write();
        virtual int Iswf();         
        virtual void Compile(); 
      };

typedef IntNode    *IntNodeptr;
typedef IdNode     *IdNodeptr;
typedef UnNode     *UnNodeptr;
typedef BinNode    *BinNodeptr;

Im Parser werden nun in den semantischen Aktionen     die Knoten des abstrakten Programmbaums erzeugt. Wir betrachten wieder die arithmetischen Ausdrücke von OBERON-0:

%{
#include "ober.h"
%}

%union {Node *nodeptr;
	char strval[256]; /* Identifikatoren   */
	long intval;      /* Integerkonstanten */
       }

%token <intval> multop divop modop andop addop subop orop
...
%token <intval> integer
%token <strval> ident

%type <intval> Sign Op1 Op2 Relop

%type <nodeptr> Factor Term SimpleExpression Expression

%start Expression

%%

Expression: SimpleExpression 
            {tree = $1;}
          |
            SimpleExpression Relop SimpleExpression
            {tree = new BinNode($1,$2,$3);}

Relop: eqsy    {$$ = eqsy;} 
       | neqsy {$$ = neqsy;} 
       | ltsy  {$$ = ltsy;} 
       | lesy  {$$ = lesy;} 
       | gtsy  {$$ = gtsy;} 
       | gesy  {$$ = gesy;}


SimpleExpression: SimpleExpression Op1 Term
            {$$ = new BinNode($1, $2, $3);}
            |
            Term
            {$$ = $1;}
            |
            Sign Term
            {if ($1 = subop)
              $$ = new UnNode($2, $1);
             else $$ = $2;}

Sign: addop {$$ = addop;} | subop {$$ = subop;}

Op1: addop {$$ = addop;} | subop {$$ = subop;}
   | orop {$$ = orop;}

Term: Factor Op2 Term
      {$$ = new BinNode($1,$2,$3);}
      |
      Factor
      {$$ = $1;}

Op2: multop {$$ = multop;} | divop {$$ = divop;}
   | andop {$$ = andop;}   | modop {$$ = modop;}

Factor: lpar Expression rpar
        {$$ = $2;}
        |
        integer
        {$$ = new IntNode($1);}
        |
        ident
        {$$ = new StringNode($1);}
        | notsy Factor
        {$$ = new UnNode($2, $1);}
%%




Next: Statische und dynamische Semantik Up: Codeerzeugung Previous: Konkrete vs. abstrakte Syntax

Prof. Dr. Reinhard Völler