lex yacc segítség

Fórumok

Sziasztok!

Most írtam config file parsert lex yacc segítségével, de van egy kis problémám. A HOWTO-k alapján csak olyan parsert tudtam írni, amiben van main én mindenféle jó, de én egy kész programhoz akarom illeszteni, egy függvényhívással akarom megoldani a dolgot. Csinált már valaki ilyet? Hogy lehet megoldani a dolgot?

Hozzászólások

Írd át a generált kódban a main()-t közönséges fügvénnyé!


%{
#include <stdio.h>

#define YYERROR_VERBOSE 1
#define YYDEBUG 1

int yylex(void);
void yyerror(char *);
FILE*   yyin;

%}

%token IZE BIGYO ...

%%

rules...

%%

int
main(int argc, char** argv)
{
  FILE*         f;
  int           rc = 0;
  
  if (argc != 2) {
    return -1;
  }

  if ((f = fopen(argv[1], "r")), f == NULL) {
    return -2;
  }

  yyin = f;

...


Hahó!

A flex info-doksiban (info flex) találtam egy struktúrát

FILE *yyin

amely -- a leírás szerint -- felüldefiniálható, s így az input ,,máshonnan'' is vehető.

Talán ez közelebb visz a megoldáshoz.

G.

Azt szeretném, ha pl a parserem felismerte a Toldel 2,3 { Negyzet(1,1,5,5) } struktúrát,
akkor kirajzolom OpenGL-el.

De az OpenGL-es részt hova írjam a .y-ban?
Hogy döntöm el, hogy már felismerte?

Azt ajánlom, hogy a .y-ból csak függvényeket hívogass meg, amiket másik c/c++ fájlokban írsz meg, különben átláthatatlanná fog válni a .y fájlod.
Úgy döntöd el, hogy a megfelelő helyre rakod. Sajnos már régen csináltam és nem emlékszem a terminológiára, de ez a lényeg:
amikor kapsz egy értéket, akkor azt eltárolod (változóba, vagy meghívód a megfelelő függvényt) és amikor az egész szerkezet egyben lefutott, akkor hívod meg a végrehajtó függvényedet.

Szívesen segítenék azzal, hogy rendesen utánanézek a leírásban, de nincs időm. A bison info lapjait nézd meg (parancssorban info bison, vagy konquerorban info:bison)

Ok, de milyen függvényeket?

kb ilyenek vannak egy .y fájlban. Egyetlen error függvény van:

---------------------------------------------
vec2flist : SFVec2f
| SFVec2f ',' vec2flist
;

MFVec2f : SFVec2f
| '[' vec2flist ']'
;

vec3flist : SFVec3f
| SFVec3f ',' vec3flist
;

MFVec3f : SFVec3f
| '[' vec3flist ']'
;

%%

yyerror(char *s)
{
extern char yytext[];
int linenum;
char *ff;

linenum = vrml_filel_linenum(&ff);
fprintf(stderr, "%s:%d: Error:\n%s at or before '%s'\n\n\n",
ff,linenum, (char *)s, *yytext=='\n'? "\\n": yytext);
return;
}

---------------------------------------------

ilyesmi rémlik:

MFVec3f:
SFVec3f { SFVec3f(); }
| '[' vec3flist ']' { SFVec3f($1); }
;

vec3flist:
SFVec3f { lista.append($1); } // $1-ben lesz az érték
| SFVec3f ',' vec3flist { }
;

A kapcsos zárójelben lévő részben a $1, $2 ... részeket az adott pozícióban lévő értékkel (változóval) helyettesíti, a $$ a rule visszatérési értéke lesz. A behelyettesítés után egyszerű c kódrészletként behelyettesíti. Neked kell megtalálnod, hogy milyen műveletet pontosan melyik ponton kell elvégeztetni.
Ha jól emlékszem, akkor a bisonnál bármelyik pontra berakhatod a C forráskódrészletet, de lehet, hogy tévedek.

Ha ezek nem világosak, akkor azt ajánlom, hogy az egész nagy lendülettel elkezdett feladatot rakd félre és olvasd át a teljes doksit, tanulmányozd a mintapéldákat, csinálj meg egyszerűbb feladatokat benne, amíg minden világos nem lesz! A neten is találsz rengeteg példát! Én 15 évnyi programozás után estem neki a bisonnal úgy, hogy már több éve tudtam a létezéséről, de ugye mindig mással van az ember elfoglalva. Aztán egyszer rászántam magam és addig én se tudtam előre jutni vele, amíg át nem néztem töviről hegyire, hogy pontosan miről is van szó. Úgyhogy türelem, mert ha lassan jársz, tovább érsz!

Ha végképp nem tudod, hogy mit csinálj, akkor: google("yacc tutorial")

A pccts (The Purdue Compiler Construction Tool Set (PCCTS)). az sokkal jobb,
hasznald inkabb azt. A lex,yacc meg egy oskovulet.

g

Ha már C++, akkor spirit.
http://spirit.sourceforge.net/

Tisztán C++ kódot kell írni, semmi generálás ésatöbbi.
(A Boost része is egyébként)

Pont egy .obj file parsert írtam vele, volt vagy 20 sor.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee."
-- Ted Ts'o

Összeállítottam a fájlokat, de szerintem rosszul próbálom fordítani:

gcc lex.yy.c y.tab.c vrml_parser.c

Az .l és .y fájlok hibátlanok
Eredmény:

vrml.l:27:22: vrml.tab.h: No such file or directory
lex.yy.c:3580: warning: prototype for `yywrap' follows
vrml.l:32: warning: non-prototype definition here
vrml.l: In function `yylex':
vrml.l:55: error: `DEF' undeclared (first use in this function)
vrml.l:55: error: (Each undeclared identifier is reported only once
vrml.l:55: error: for each function it appears in.)
vrml.l:56: error: `yylval' undeclared (first use in this function)
vrml.l:58: error: `VRMLWORD' undeclared (first use in this function)
vrml.l:61: error: `USE' undeclared (first use in this function)
vrml.l:63: error: `ASCIITEXT' undeclared (first use in this function)
vrml.l:64: error: `CONE' undeclared (first use in this function)
vrml.l:65: error: `COORDINATE3' undeclared (first use in this function)
vrml.l:66: error: `CUBE' undeclared (first use in this function)
vrml.l:67: error: `CYLINDER' undeclared (first use in this function)
vrml.l:68: error: `DIRECTIONALLIGHT' undeclared (first ...