next up previous contents
Next: init Up: Parser Previous: parser_l.l

 

parser_y.y

Deklaraktionen

%token BEGIN_ POINTS POLYGONS BACKGROUND VIEWPOINT VIEWMATRIX END
%token <long_val> INT_CONST
%token <float_val> FLOAT_CONST
%token <string> IDENTIFIER
legt die Tokens fest.
%start scene
legt fest, welche Regel den Startpunkt bildet.

Regeln

scene        : BEGIN_ IDENTIFIER  { PR("reading scene : %s\n", $2); }
                sections END IDENTIFIER  { PR("done : %s\n", $6); }
             ;
Die ganze Szene besteht aus dem Token BEGIN_, einem Identifier, den sections, dem Token END und wiederum dem Identifier. PR bewirkt die Ausgabe einer Meldung.
sections     : point_section poly_section background viewpoint
             | point_section poly_section background viewpoint viewmatrix
             ;
Die Regel sections beschreibt die einzelnen Abschnitte der Szene: Punkte, Polygone, Hintergrundfarbe, Viewpunkt oder Punkte, Polygone, Hintergrundfarbe, Viewpunkt und Viewmatrix.
point_section: POINTS INT_CONST
                 { 
		   number_of_points = $2;
		   PR("-> points : Number_of_points = %d\n", number_of_points );
		   Points = (struct point_struct *)malloc((number_of_points+
	                     MAX_EXTRA_POINTS)*sizeof(struct point_struct));
		   assert(Points);
		   the_point_datas = (struct point_data_struct *)
                     malloc((number_of_points+MAX_EXTRA_POINTS)
                             *sizeof(struct point_data_struct));
		   assert(the_point_datas);
		   point_nr = 0;
		 }
                point_datas
                 { if (point_nr < number_of_points) 
                    p_error("Syntax error or too few points."); }
             ;
Die Punktesektion besteht aus dem Token POINTS, einer Integerkonstanten (Anzahl Punkte) und der Untersektion point_datas. Hier wird der Speicher reserviert für die Punktestruktur.
point_datas  : /* none */
             | point_datas float_or_int float_or_int float_or_int
                 { 
		   if (point_nr >= number_of_points) p_error("Too many points.");
		   Points[point_nr].x_world = $2; 
		   Points[point_nr].y_world = $3;
		   Points[point_nr].z_world = $4; 
		   Points[point_nr].Number_of_Polygons = 0;
		   Points[point_nr].Polygons = 0L;
		   Points[point_nr].flags = 0;
		   Points[point_nr].p = the_point_datas++;
		   point_nr++;
		 }
             ;
Regel für beliebig viele Punktdaten (rekursiver Aufruf).
poly_section : POLYGONS INT_CONST 
                 { 
		   number_of_polys = $2;
		   PR("-> polygons : Number_of_polygons = %d\n", number_of_polys );
		   Polygons = (struct polygon_struct *) malloc(number_of_polys*
                               sizeof(struct polygon_struct));
		   assert(Polygons);
		   the_poly_datas = (struct polygon_data_struct *)malloc(number_of_polys*
                                    sizeof(struct polygon_data_struct));
		   assert(the_poly_datas);
		   poly_nr = 0;
		 }
                poly_datas
                 { if (poly_nr < number_of_polys) 
                   p_error("Syntax error or too few polygons."); }
             ;

poly_datas   : /* none */
             | poly_datas INT_CONST  
                 { 
		   if (poly_nr >= number_of_polys) p_error("Too many polygons.");
		   Polygons[poly_nr].Number_of_Points = $2;
		   Polygons[poly_nr].Points = (struct point_struct **)
                     malloc(Polygons[poly_nr].Number_of_Points
                       *sizeof(struct point_struct *));
		   assert(Polygons[poly_nr].Points);
		   Polygons[poly_nr].Old_Number_of_Points = 0;
		   Polygons[poly_nr].Old_Points = 0L;
		   Polygons[poly_nr].flags = 0;
		   Polygons[poly_nr].p = the_poly_datas++;
		   poly_point_nr = 0;
		 }
                poly_points ','
                INT_CONST INT_CONST INT_CONST INT_CONST
                 { 
		   if (poly_point_nr <Polygons[poly_nr].Number_of_Points) 
			p_error("Too few polygon points.");
		   Polygons[poly_nr].RGB_color = $6 + 256*$7 + 256*256*$8;
		   Polygons[poly_nr].RGB = Polygons[poly_nr].RGB_color;
		   Polygons[poly_nr].flags = $9;
		 }
poly_points  : /* none */
             | poly_points INT_CONST
                 { 
		   if (poly_point_nr >= Polygons[poly_nr].Number_of_Points) 
                     p_error("Too many polygon points.");
		   Polygons[poly_nr].Points[poly_point_nr] = &Points[$2]; poly_point_nr++;
		 }
             ;
Regel für die Polygonsektion, analog zu den Punktdaten.
background   : BACKGROUND INT_CONST INT_CONST INT_CONST
                 { backgroundColor = $2 + 256*$3 + 256*256*$4; }  
             ;
Regel für die Hintergrundfarbe.
viewpoint    : VIEWPOINT
                float_or_int float_or_int float_or_int
                float_or_int float_or_int float_or_int
                float_or_int
                float_or_int
                 {
		   MFLOAT cx,cy,cz,fx,fy,fz,phi;

		   Views = (struct view_struct *) malloc(sizeof(struct view_struct));
		   assert(Views);
		   cx = $2; cy = $3; cz = $4;
		   fx = $5; fy = $6; fz = $7;
		   phi = $8; Views->Distance_to_screen = $9;
		   calc_view_matrix(cx, cy, cz, fx, fy, fz, phi, Views->Object_to_World);
		 }  
             ;
Regel für den Viewpunkt.
viewmatrix   : VIEWMATRIX
                float_or_int float_or_int float_or_int float_or_int
                float_or_int float_or_int float_or_int float_or_int
                float_or_int float_or_int float_or_int float_or_int
                float_or_int float_or_int float_or_int float_or_int
                 {
		   assert(Views);
		   #define view Views->Object_to_World
		   view[0][0] = $2; view[0][1] = $3; view[0][2] = $4; view[0][3] = $5; 
		   view[1][0] = $6; view[1][1] = $7; view[1][2] = $8; view[1][3] = $9; 
		   view[2][0] = $10; view[2][1] = $11; view[2][2] = $12; view[2][3] = $13; 
		   view[3][0] = $14; view[3][1] = $15; view[3][2] = $16; view[3][3] = $17;
		   #undef view
		 }  
             ;
Regel für die Viewmatrix, die den Viewpunkt überschreibt.
float_or_int : FLOAT_CONST { $$ = $1; }
             | INT_CONST   { $$ = (float)$1; };
             ;
Regel float_or_int bewirkt, dass alle Koordinaten auch als Integerwerte angegeben werden können.

Hilfsprozeduren

tabular2621

Die Funktion parse öffnet die Datei Scene_filename und ruft die Funktion yyparse, die von Yacc generiert wurde, auf. Schliesslich kopiert sich in der View-Struktur Object_to_world nach Object_to_world_begin. Abbildung 5.1 auf Seite gif zeigt den Pseudocode. 27

  figure2653
Abbildung 5.1: Pseudocode der Funktion parse 



Martin Frey
Tue Jun 17 13:29:20 MET DST 1997