Bison több utasítás egy sorban

Fórumok

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; }
;

Hozzászólások

Nem ezt szeretnéd?

stmt: while '(' expr ')' stmt
| '{' stmtlist '}'
...
| error
;

stmtlist: stmt
| stmtlist ':' stmt
;

Nem kell veletlenul ; a lezaro } ele?

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.

É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 | ...;

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+!

É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.

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) };