-1 + -5
sto cercando di creare un programma che mi risolva queste somme algebriche ma non so come fare.
un'aiuto sarebbe gradito..............................
-1 + -5
sto cercando di creare un programma che mi risolva queste somme algebriche ma non so come fare.
un'aiuto sarebbe gradito..............................
E SE TUTTO FOSSE SOLO UN RIFLESSO?
-1 + -5 in algebra non avrebbe nessun senso, mentre dovresti scrivere (-1)+(-5).
Quindi, perchè riesca bene, dovresti fare un parser che memorizzi in una struttura ad albero i vari livelli di parentesi (come sto facendo io...ma non ho ancora codice...sono ancora all'analisi).
Consiglio di interpretare il + e - come operatori unari (il - nega il segno del numero alla sua destra) che agiscano su un intero con segno.
Insomma, bisognerebbe fare un mini-parser di espressioni.
I've got a bike. You can ride it if you like.
ma scusate.. fare una funzione add(x,y) che fa la somma di due numeri e poi chiamare add(-1,5)?
non funziona??
Gli uomini si dividono in due categorie: i geni e quelli che dicono di esserlo. Io sono un genio.
io quando ho scritto il mio compilatore ho preso spunto da qui:
http://www.textfiles.com/programming/crenshawtut.txt
che insegna anche a fare un parser..
(e' in pascal)
1. Clicca su "start"
2. Clicca su "Programmi"
3. Clicca su "Accessori"
4. Clicca su "calcolatrice"
Il resto è semplice!!!
VVoVe:
L'ambiguità è risolta dando precedenza all'operatore unario in fase di analisi sintattica, o altrimenti forire una grammatica non ambigua ottenibile a partire da una ambigua utilizzando tecniche come la fattorizzazione sinistra ad esempioOriginariamente inviato da edriv
-1 + -5 in algebra non avrebbe nessun senso, mentre dovresti scrivere (-1)+(-5).
dagli appunti presi da Compilers
by Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman
oppure ancora in fase di generazione di codice durante la discesa del parse tree,Analisi discendente - parser predittivo
• L’analisi discendente può richiedere il backtrack: per un
simbolo input a è possibile applicare più produzioni:
A => a1 |…|an se esistono più alternative (a1 …an ) che
iniziano con a. Rimedio: fattorizzazione sinistra
• L’analisi discendente non è applicabile se la grammatica è
ricorsiva sinistra (left recursive), cioè se A Þ Aa (A non
terminale). Rimedio: eliminazione ricorsione sinistra
es:
<stmt> => if <expr> then <stmt>
| if <expr> then <stmt> else <stmt>
fattorizzazione sinistra:
<stmt> => if <expr> then <stmt><S>
<S> ® e | else <stmt>
un pezzo del generatore di codice un mini-compilatore pascal
codice:/* versione unaria */ case T_MINUS: // Token - /* se numero di operandi == 1 */ if (n->opr.nops == 1) { gencode(n->opr.op[0]); fprintf(g_code_file, "\t%s\n", get_instr(I_NEG)); break; } ........ default: gencode(n->opr.op[0]); gencode(n->opr.op[1]); switch (n->opr.oper) { case T_PLUS: // Token + fprintf(g_code_file, "\t%s\n", get_instr(I_ADD)); break; case T_MINUS: // Token - fprintf(g_code_file, "\t%s\n", get_instr(I_SUB)); break; ........codice:program test1; var x: integer; begin x := -1 + -5; end.genera questo codicecodice:compiling test1.pas ... Symbol table ------------ id: 'test1', declared: false id: 'x', declared: true Syntax tree ----------- opr: T_SEMICOLON 1-opr: T_ASSIGNMENT 2-id: 'x', declared: true 2-opr: T_PLUS 3-opr: T_MINUS 4-value: 1 3-opr: T_MINUS 4-value: 5
che valutato da correttamente -6codice:pushINT 1 neg pushINT 5 neg add pop x
Credo di avere capito che il + viene interpretato come un operatore binario mentre il - è unario.
E' una soluzione che non genera mai errori/ambiguità?
x := 4-2 lo metterebbe in crisi?
E poi in algebra sarebbe legale anche scrivere:
+3
+3 * +5
-4 + 4 - 5
questo argomento è molto interessante...
I've got a bike. You can ride it if you like.
No perchè viene creato un nodo T_MINUS (T_MINUS = token '-')Originariamente inviato da edriv
Credo di avere capito che il + viene interpretato come un operatore binario mentre il - è unario.
E' una soluzione che non genera mai errori/ambiguità?
x := 4-2 lo metterebbe in crisi?
con 2 nodi figli
codice:simple_expression : term { $$ = $1; } /* crea un nodo con 2 figli */ | simple_expression addop term { $$ = make_opr_node($2, 2, $1, $3); } ; addop : T_PLUS { $$ = T_PLUS; } | T_MINUS { $$ = T_MINUS; } ; factor /* crea un nodo unario, con 1 solo figlio */ : sign factor { $$ = make_opr_node($1, 1, $2); } ... ; sign : T_PLUS { $$ = T_PLUS; } | T_MINUS { $$ = T_MINUS; } ;l'albero generato è questocodice:program test1; var x: integer; begin x := 4-2 end.
T_MINUS ha 2 nodicodice:Syntax tree ----------- opr: T_ASSIGNMENT 1-id: 'x', declared: true 1-opr: T_MINUS 2-value: 4 2-value: 2
genera
assegna il risultato di 4-2=2 a xcodice:pushINT 4 pushINT 2 sub pop x
ti consiglio questa paginaE poi in algebra sarebbe legale anche scrivere:
+3
+3 * +5
-4 + 4 - 5
questo argomento è molto interessante...
http://www.epaperpress.com/lexandyacc/
http://www.epaperpress.com/lexandyac...ad/lexyacc.pdf
LEX è un tool per realizzare l'analizzatore lessicale (detto anche "lexer" e genera i token a partire dal codice sorgente)
YACC serve per generare il parser, cioè quel modulo che si occupa di costruire l'albero sintattico (parser) a partire dai token ottenuti dall'analizzatore lessicale (lexer)
qui invece c'è la grammatica per realizzare un compilatore Pascal
http://www.moorecad.com/standardpascal/yacclex.html
questo genera il lexer tramite LEX
http://www.moorecad.com/standardpascal/pascal.l
questo invece il parser tramite YACC
http://www.moorecad.com/standardpascal/pascal.y
Un parser di espressioni lo vorrei fare (e lo sto facendo) facendo analisi da solo, senza prendere spunti, per poi confrontarmi.
Non ho capito come fare a distinguere un - (o +) unario o binario!
I've got a bike. You can ride it if you like.
non è che qualcuno mi potrebbe indicare una buona guida(in italiano per favore) su cos'è un parser come funziona come crearli?
perliamo sempre di c++ s'intende.
E SE TUTTO FOSSE SOLO UN RIFLESSO?