A jelenség: multi-statementet nem fogadja el a kapcsos zárójeleken belül. Miért rossz és hogyan kellene ezt helyesen?
(megj.: Nem használok semmilyen speciális termináló karaktert, pl. ';'
0x363 > a=3 : b=2:c=3:b=a : a=c ---> ok
0x377 > while (a>b) a=3 ---> ok
0x382 > while (a>b) { a=3 } ---> ok
0x38d > while (a>b) { a=3 : b=2 } ---> syntax error
:
:
b
=
2
0x38d >
Az ide vágó bison deklarációk:
stmt:
......
......
| WHILE '(' expr ')' stmt_list { $$ = opr(WHILE, 2, $3, $5); }
| stmt_list ':' stmt { $$ = opr(':', 2, $1, $3); }
| error {
yyerror((char *)yytext);
$$ = NULL;
errorflag=1;
}
;
stmt_list:
stmt { $$ = $1; }
| '{' stmt_list '}' { $$ = $2; }
;
- 7729 megtekintés
Hozzászólások
Nem ezt szeretnéd?
stmt: while '(' expr ')' stmt
| '{' stmtlist '}'
...
| error
;
stmtlist: stmt
| stmtlist ':' stmt
;
- A hozzászóláshoz be kell jelentkezni
Így teljesen ugyanazt az eredményt adja :(
0x363 > a=3 : b=2:c=3:b=a : a=c ---> ok
0x377 > while (a>b) a=3 ---> ok
0x382 > while (a>b) { a=3 } ---> ok
0x38d > while (a>b) { a=3 : b=2 } ---> syntax error
:
:
b
=
2
0x38d >
- A hozzászóláshoz be kell jelentkezni
Azt lehet tudni, hogy az ,,opr'' függvény mit csinál, és azt hogy csinálja?
- A hozzászóláshoz be kell jelentkezni
Nem kell veletlenul ; a lezaro } ele?
- A hozzászóláshoz be kell jelentkezni
Úgy tűnik, nem olvastad :(
Nem használok semmilyen speciális termináló karaktert, pl. ';'
- A hozzászóláshoz be kell jelentkezni
bisonon be lehet kapcsolni debug opciokent hogy irja ki a parse stack-et. YYDEBUG vagy valami hasonlo ha jol remlik. ha postolod abbol esetleg kiderulhet valami. Vagy ha kiteszed valahova a teljes bison fajlt.
- A hozzászóláshoz be kell jelentkezni
Köszönöm a tanácsot.
- A hozzászóláshoz be kell jelentkezni
Te kérdezted ugyanezt a prog.hu-n pár hónapja? Vagy iskolai feladat?
http://forum.prog.hu/tudastar/161854/Bison+terminal+karakter.html
http://forum.prog.hu/tudastar/161933/Bison+multiline.html
- A hozzászóláshoz be kell jelentkezni
Igen, én kérdeztem, de jó ideig félre kellett tennem a témát és most poroltam le újra.
Emlékszem is Rád a válaszadók között.
Nem iskolai feladat, én már 60 elmóltam, még 8080-Z80 -on nevelkedtem. Ez nekem hobby, még visz még a lendület :))
- A hozzászóláshoz be kell jelentkezni
És milyen gondod támadt a megoldással, amit ott elfogadtál? Vagyis hogy a lexikális elemző nem semmisíti meg a sorvége-jeleket, hanem a következő trükköt csinálja velük:
1. ha egy sorban csak whitespace (szóköz, tab, kocsivissza) van, azt egyetlen sorvége jellel helyettesíti
2. több egymást követő sorvége jelet eggyé alakít
3. gondoskodik róla, hogy a kapcsos nyitó és csukó zárójelek előtt és mögött legyen egy-egy sorvége jel (vagyis ha nincs ott, akkor hamisít egyet, ha több van egynél, akkor is csak egyet jelent)
azután a szabályok:
block: '\n' '{' '\n' opt_stmt_lines '}' '\n'
opt_stmt_lines: /* empty */
| stmt_group '\n' opt_stmt_lines;
stmt_group: stmt;
| stmt ':' stmt_group;
stmt: ... | block | IF '(' expr ')' stmt | ...;
- A hozzászóláshoz be kell jelentkezni
Mind a multistate, mind a multiline megvalósítása célom, de hogy tisztábban lássam a dolgokat, egyelőre a multistate megoldására fókuszálok, de minden próbálkozásom ellenére ezt a lécet sem sikerül átugrani. A javaslatodat viszem magaddal kipróbálni, pár napig nem leszek netközelben, de majd visszajelzek. Addig is köszönöm+!
- A hozzászóláshoz be kell jelentkezni
És milyen gondod támadt a megoldással, amit ott elfogadtál?
Mivel hályogkovács módjára, a dolgot teljes mélységében nem átlátva bénázok, egy vesszőhiba fejreállít mindent és napokig tart, mire értelmezni tudom, mi is okozza a dolgot. Pl. az egyik mint szerinti sorra itt egy warning, hogy semmit sem csinál. Számomra ettől kezdve megáll a tudomány, ott vagyok, ahol eddig.
opt_stmt_lines: /* empty */
| stmt_group '\n' opt_stmt_lines;
bas.y:44.15: warning: empty rule for typed nonterminal, and no action
Hogy ez okozza-e azt, hogy így már az a=1 utasításra is syntax error lesz, azt már végképp nem tudom.
- A hozzászóláshoz be kell jelentkezni
Azt én nem tudhatom, hogy a programodban mi van; ha mondjuk a stmt előállít egy Code * pointert, és van egy Sequence nevű programrész, ami két Code *-ból előállít egy harmadikat, akkor ilyesmi lenne:
opt_stmt_lines: /* empty */ { $$= NULL; }
| stmt_group '\n' opt_stmt_lines { if ($3) $$= Sequence ($1, $3); else $$= $1; }
stmt_group: stmt { $$= $1; }
| stmt ':' stmt_group { $$= Sequence ($1, $3) };
- A hozzászóláshoz be kell jelentkezni