readworld.l
Go to the documentation of this file.
1 %{
2 /*
3 * Lexical analizer for world files
4 */
5 
8 #include <stdlib.h>
9 #include <string.h>
10 #include "defines.h"
11 #include "error_world.h"
12 #include "color.h" /* %union uses Tcolor */
13 #include "readworld.tab.h"
14 
15 typedef struct {
16  YY_BUFFER_STATE buffer;
17  char *prefix;
18  unsigned int pl;
19  unsigned int line;
20  unsigned int fl;
21  unsigned int fo;
22 } TincludeInfo;
23 
24 TincludeInfo includeInfo[MAX_INCLUDES];
25 unsigned int currentIncludeLevel=0;
26 
27 unsigned int firstLink; /* first link in the current object */
28 unsigned int firstObject; /* first object in the current file */
29 
30 int ReadWorldlex(void);
31 
32 extern unsigned int RWline; /*current line number (declared in the YACC module and updated here)*/
33 
34 void Switch2File(char *ln,unsigned int nl,unsigned int no,char *path,char *file);
35 
36 %}
37 %s IN_COMMENT
38 
39 EMPTY [ \t]+
40 RETURN \n
41 DIGIT [0-9]
42 LETTER [a-zA-Z]
43 R_NUMBER (({DIGIT}+(\.{DIGIT}+)?)|(\.{DIGIT}+))((E|e)[+-]?{DIGIT}+)?
44 I_NUMBER {DIGIT}+
45 STRING \"[^\"]+\"
46 IDENTIFIER {LETTER}({DIGIT}|{LETTER}|"_")*
47 EXT_IDENTIFIER {IDENTIFIER}("::"{IDENTIFIER})+
48 COMMENT \%[^\n]*
49 COMMENT2 \#[^\n]*
50 COMMENT3 \/\/[^\n]*
51 
52 %%
53 {COMMENT} { }
54 {COMMENT2} { }
55 {COMMENT3} { }
56 
57 <INITIAL>{
58  "/*" BEGIN(IN_COMMENT);
59 }
60 <IN_COMMENT>{
61  "*/" BEGIN(INITIAL);
62  [^*\n]+ // eat comment in chunks
63  "*" // eat the lone star
64  \n RWline++;
65 }
66 
67 {EMPTY} { }
68 
69 {RETURN} { RWline++; }
70 
71 "[CONSTANTS]" {
72  return(_CONSTANTS);
73  }
74 
75 ":=" {
76  return(_ASSIGN);
77  }
78 
79 "==" {
80  return(_EQUAL);
81  }
82 
83 "!=" {
84  return(_NOT_EQUAL);
85  }
86 
87 "<=" {
88  return(_LESS_EQUAL);
89  }
90 
91 ">=" {
92  return(_GREATER_EQUAL);
93  }
94 
95 "<" {
96  return(_LESS);
97  }
98 
99 ">" {
100  return(_GREATER);
101  }
102 
103 PI {
104  return(_PI);
105  }
106 
107 EXP {
108  return(_EXP);
109  }
110 
111 SIN {
112  return(_SIN);
113  }
114 
115 COS {
116  return(_COS);
117  }
118 
119 TAN {
120  return(_TAN);
121  }
122 
123 COT {
124  return(_COT);
125  }
126 
127 ACOS {
128  return(_ACOS);
129  }
130 
131 ASIN {
132  return(_ASIN);
133  }
134 
135 ATAN {
136  return(_ATAN);
137  }
138 
139 ATAN2 {
140  return(_ATAN2);
141  }
142 
143 SQRT {
144  return(_SQRT);
145  }
146 
147 ABS {
148  return(_ABS);
149  }
150 
151 PARAMETER {
152  return(_PARAMETER);
153  }
154 
155 PRINT {
156  return(_PRINT);
157  }
158 
159 "[LINKS]" {
160  return(_LINKS);
161  }
162 
163 "BODY" {
164  return(_BODY);
165  }
166 
167 "GRANULARITY" {
168  return(_GRANULARITY);
169  }
170 
171 "HIDDEN" {
172  return(_HIDDEN);
173  }
174 
175 "DECORATION" {
176  return(_DECORATION);
177  }
178 
179 "[JOINTS]" {
180  return(_JOINTS);
181  }
182 
183 "FIX" {
184  return(_FIX);
185  }
186 
187 "ID" {
188  return(_ID);
189  }
190 
191 "TX" {
192  return(_TX);
193  }
194 
195 "TY" {
196  return(_TY);
197  }
198 
199 "TZ" {
200  return(_TZ);
201  }
202 
203 "TXYZ" {
204  return(_TXYZ);
205  }
206 
207 "RX" {
208  return(_RX);
209  }
210 
211 "RY" {
212  return(_RY);
213  }
214 
215 "RZ" {
216  return(_RZ);
217  }
218 
219 "PRISMATIC" {
220  return(_PRISMATIC);
221  }
222 
223 "REVOLUTE" {
224  return(_REVOLUTE);
225  }
226 
227 "CREVOLUTE" {
228  return(_CREVOLUTE);
229  }
230 
231 "SPHERICAL" {
232  return(_SPHERICAL);
233  }
234 
235 "UNIVERSAL" {
236  return(_UNIVERSAL);
237  }
238 
239 "SPH_SPH" {
240  return(_SPH_SPH);
241  }
242 
243 "SPH_PRS_SPH" {
244  return(_SPH_PRS_SPH);
245  }
246 
247 "IN_PATCH" {
248  return(_IN_PATCH);
249  }
250 
251 "LENGTH" {
252  return(_LENGTH);
253  }
254 
255 "RADIUS" {
256  return(_RADIUS);
257  }
258 
259 "BOX" {
260  return(_BOX);
261  }
262 
263 "PRISM" {
264  return(_PRISM);
265  }
266 
267 "SPHERE" {
268  return(_SPHERE);
269  }
270 
271 "CYLINDER" {
272  return(_CYLINDER);
273  }
274 
275 "LINE" {
276  return(_LINE);
277  }
278 
279 "SEGMENTS" {
280  return(_SEGMENTS);
281  }
282 
283 
284 "[OBSTACLES]" {
285  return(_OBSTACLES);
286  }
287 
288 "[COLLISIONS]" {
289  return(_COLLISIONS);
290  }
291 
292 "COLOR" {
293  return(_COLOR);
294  }
295 
296 "RED" {
297  return(_RED);
298  }
299 
300 "GREEN" {
301  return(_GREEN);
302  }
303 
304 "BLUE" {
305  return(_BLUE);
306  }
307 
308 "WHITE" {
309  return(_WHITE);
310  }
311 
312 "BLACK" {
313  return(_BLACK);
314  }
315 
316 "GREY" {
317  return(_GREY);
318  }
319 
320 "YELLOW" {
321  return(_YELLOW);
322  }
323 
324 "CYAN" {
325  return(_CYAN);
326  }
327 
328 "PURPLE" {
329  return(_PURPLE);
330  }
331 
332 "RANGE" {
333  return(_RANGE);
334  }
335 
336 "CHECK" {
337  return(_CHECK);
338  }
339 
340 "DO NOT" {
341  return(_NO);
342  }
343 
344 "ALL" {
345  return(_ALL);
346  }
347 
348 "CONNECTED" {
349  return(_CONNECTED);
350  }
351 
352 "SELFCOLLISIONS" {
353  return(_SELFCOLLISIONS);
354  }
355 
356 "AVOID" {
357  return(_AVOID);
358  }
359 
360 "LIMITS" {
361  return(_LIMITS);
362  }
363 
364 "[INCLUDE]" {
365  return(_INCLUDE);
366  }
367 
368 {I_NUMBER} {
369  char string_tmp[100];
370 
371  memcpy(string_tmp,ReadWorldtext,(unsigned int)ReadWorldleng);
372  string_tmp[ReadWorldleng]=0;
373  ReadWorldlval.int_number=atoi(string_tmp);
374  return(_INTEGER);
375  }
376 
377 {R_NUMBER} {
378  char string_tmp[100];
379 
380  memcpy(string_tmp,ReadWorldtext,(unsigned int)ReadWorldleng);
381  string_tmp[ReadWorldleng]=0;
382  ReadWorldlval.real_number=atof(string_tmp);
383 
384  return(_REAL);
385  }
386 
387 {STRING} {
388  NEW(ReadWorldlval.string,ReadWorldleng,char);
389 
390  memcpy(ReadWorldlval.string,&(ReadWorldtext[1]),(unsigned int)ReadWorldleng-2);
391  ReadWorldlval.string[ReadWorldleng-2]=0;
392 
393  return(_STRING);
394  }
395 
396 {IDENTIFIER} {
397  if (currentIncludeLevel==0)
398  {
399  NEW(ReadWorldlval.id,ReadWorldleng+1,char);
400  memcpy(ReadWorldlval.id,ReadWorldtext,(unsigned int)ReadWorldleng);
401 
402  ReadWorldlval.id[ReadWorldleng]=0;
403  }
404  else
405  {
406  NEW(ReadWorldlval.id,includeInfo[currentIncludeLevel-1].pl+2+ReadWorldleng+1,char);
407  sprintf(ReadWorldlval.id,"%s__%s",includeInfo[currentIncludeLevel-1].prefix,ReadWorldtext);
408  ReadWorldlval.id[includeInfo[currentIncludeLevel-1].pl+ReadWorldleng+2]=0;
409  }
410 
411  return(_IDENTIFIER);
412  }
413 
414 {EXT_IDENTIFIER} {
415  unsigned int i;
416 
417  if (currentIncludeLevel==0)
418  {
419  NEW(ReadWorldlval.id,ReadWorldleng+1,char);
420  memcpy(ReadWorldlval.id,ReadWorldtext,(unsigned int)ReadWorldleng);
421 
422  ReadWorldlval.id[ReadWorldleng]=0;
423 
424  for(i=0;i<ReadWorldleng;i++)
425  {
426  if (ReadWorldlval.id[i]==':')
427  ReadWorldlval.id[i]='_';
428  }
429  }
430  else
431  {
432  unsigned int k;
433 
434  NEW(ReadWorldlval.id,includeInfo[currentIncludeLevel-1].pl+2+ReadWorldleng+1,char);
435  sprintf(ReadWorldlval.id,"%s__%s",includeInfo[currentIncludeLevel-1].prefix,ReadWorldtext);
436  ReadWorldlval.id[includeInfo[currentIncludeLevel-1].pl+ReadWorldleng+2]=0;
437 
438  for(i=0,k=includeInfo[currentIncludeLevel-1].pl+2;i<ReadWorldleng;i++,k++)
439  {
440  if (ReadWorldlval.id[k]==':')
441  ReadWorldlval.id[k]='_';
442  }
443  }
444 
445  return(_EXT_IDENTIFIER);
446  }
447 
448 <<EOF>> {
449  if (currentIncludeLevel>0)
450  {
451  currentIncludeLevel--;
452 
453  /* Recover the line number */
454  RWline=includeInfo[currentIncludeLevel].line;
455 
456  /* Deletes the prefix */
457  free(includeInfo[currentIncludeLevel].prefix);
458 
459  /* Recover the first link/object in the upper file */
460  firstLink=includeInfo[currentIncludeLevel].fl;
461  firstObject=includeInfo[currentIncludeLevel].fo;
462 
463  /* Deletes the lex buffer and switch */
464  yy_delete_buffer(YY_CURRENT_BUFFER);
465  yy_switch_to_buffer(includeInfo[currentIncludeLevel].buffer);
466  }
467  else
468  yyterminate();
469  }
470 
471 . { return(ReadWorldtext[0]); }
472 
473 %%
474 
475 /*
476  * This function is automatically called by the parser at the end of a file.
477  * If 1 is returned the lexical analysis is stopped.
478  */
479 int ReadWorldwrap()
480 {
481  return(1);
482 }
483 
487 void Switch2File(char *ln,unsigned int nl,unsigned int no,char *path,char *file)
488 {
489  FILE *f;
490  unsigned int l1,l2;
491  char *name;
492 
493  if (currentIncludeLevel>=MAX_INCLUDES)
494  ReadWorlderror("Includes nested too deeply. A loop of includes?" );
495 
496  /* in the new file, lines are numbered from 1 again :) */
497  includeInfo[currentIncludeLevel].line=RWline;
498  RWline=1;
499 
500  /* Store the first link/object in the current file and reset them */
501  includeInfo[currentIncludeLevel].fl=firstLink;
502  includeInfo[currentIncludeLevel].fo=firstObject;
503  firstLink=nl;
504  firstObject=no;
505 
506  /* identifiers in the new file will need the prefix defined next */
507  l2=strlen(ln);
508  if (currentIncludeLevel>0)
509  {
510  /* If we have a previous prefix, add it to the current prefix */
511  l1=includeInfo[currentIncludeLevel-1].pl;
512  NEW(includeInfo[currentIncludeLevel].prefix,l1+l2+2,char);
513  memcpy(includeInfo[currentIncludeLevel].prefix,includeInfo[currentIncludeLevel-1].prefix,l1*sizeof(char));
514  includeInfo[currentIncludeLevel].prefix[l1]='_';
515  l1++;
516  }
517  else
518  {
519  l1=0;
520  NEW(includeInfo[currentIncludeLevel].prefix,l2+1,char);
521  }
522  /* add the link name to the prefix */
523  memcpy(&(includeInfo[currentIncludeLevel].prefix[l1]),ln,l2*sizeof(char));
524  includeInfo[currentIncludeLevel].prefix[l1+l2]=0;
525 
526  includeInfo[currentIncludeLevel].pl=l1+l2; /* cache of the prefix lenght */
527 
528  /* stack the yybuffer */
529  includeInfo[currentIncludeLevel].buffer=YY_CURRENT_BUFFER;
530  currentIncludeLevel++;
531 
532  /* Now try to open the file to be included */
533  l1=strlen(path);
534  l2=strlen(file);
535  NEW(name,l1+l2+1,char);
536  memcpy(name,path,l1*sizeof(char));
537  memcpy(&(name[l1]),file,l2*sizeof(char));
538  name[l1+l2]=0;
539 
540  f=fopen(name,"r");
541  if (!f)
542  {
543  char *m;
544 
545  NEW(m,l1+l1+100,char);
546  sprintf(m,"Can not open included file: %s",name);
547  ReadWorlderror(m);
548  free(m);
549  }
550  else
551  {
552  yy_switch_to_buffer(yy_create_buffer(f,YY_BUF_SIZE));
553  BEGIN(INITIAL);
554  }
555 }
unsigned int RWline
Number of the line currently parsed when reading a .world file.
Definition: error_world.c:45
#define PURPLE
Purple.
Definition: color.h:72
#define BLUE
Blue.
Definition: color.h:37
#define RZ
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:75
#define RY
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:67
#define CYLINDER
One of the possible type of polyhedrons.
Definition: polyhedron.h:80
#define TZ
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:51
#define SEGMENTS
One of the possible type of polyhedrons.
Definition: polyhedron.h:100
#define LINE
One of the possible type of polyhedrons.
Definition: polyhedron.h:90
#define WHITE
White.
Definition: color.h:58
#define BLACK
Black.
Definition: color.h:44
#define TX
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:35
Definitions of constants and macros used in several parts of the cuik library.
#define YELLOW
Yellow.
Definition: color.h:65
#define GREEN
Green.
Definition: color.h:30
#define GREY
Grey.
Definition: color.h:51
#define MAX_INCLUDES
Maximum number of nested included files.
Definition: defines.h:148
#define SPHERE
One of the possible type of polyhedrons.
Definition: polyhedron.h:70
Definition of the Tcolor type and the associated functions.
#define RX
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:59
#define CYAN
Cyan.
Definition: color.h:79
#define RED
Red.
Definition: color.h:23
#define TY
One of the types of homogeneous transforms in R^3.
Definition: htransform.h:43
Error function specific of world.