Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11

Discussione: [c++]somme algebriche

  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2004
    Messaggi
    85

    [c++]somme algebriche

    -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?

  2. #2
    Utente di HTML.it L'avatar di edriv
    Registrato dal
    Oct 2004
    Messaggi
    367
    -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.

  3. #3
    Utente di HTML.it L'avatar di marco_c
    Registrato dal
    Jun 2004
    Messaggi
    1,047
    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.

  4. #4
    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)

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2004
    Messaggi
    115

    1. Clicca su "start"
    2. Clicca su "Programmi"
    3. Clicca su "Accessori"
    4. Clicca su "calcolatrice"
    Il resto è semplice!!!
    VVoVe:

  6. #6
    Originariamente inviato da edriv
    -1 + -5 in algebra non avrebbe nessun senso, mentre dovresti scrivere (-1)+(-5).
    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 esempio

    dagli appunti presi da Compilers
    by Alfred V. Aho, Ravi Sethi, Jeffrey D. Ullman
    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>
    oppure ancora in fase di generazione di codice durante la discesa del parse tree,

    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.
    codice:
    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
    genera questo codice
    codice:
    	pushINT	1
    	neg
    	pushINT	5
    	neg
    	add
    	pop	x
    che valutato da correttamente -6

  7. #7
    Utente di HTML.it L'avatar di edriv
    Registrato dal
    Oct 2004
    Messaggi
    367
    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.

  8. #8
    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?
    No perchè viene creato un nodo T_MINUS (T_MINUS = token '-')
    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; }
    	;
    codice:
    program test1;
    var x: integer;
    
    begin
      x := 4-2
    end.
    l'albero generato è questo

    codice:
    Syntax tree
    -----------
    opr: T_ASSIGNMENT
    1-id: 'x', declared: true
    1-opr: T_MINUS  
     2-value: 4
     2-value: 2
    T_MINUS ha 2 nodi

    genera
    codice:
    	pushINT	4
    	pushINT	2
    	sub
    	pop	x
    assegna il risultato di 4-2=2 a x

    E poi in algebra sarebbe legale anche scrivere:
    +3
    +3 * +5
    -4 + 4 - 5
    questo argomento è molto interessante...
    ti consiglio questa pagina
    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

  9. #9
    Utente di HTML.it L'avatar di edriv
    Registrato dal
    Oct 2004
    Messaggi
    367
    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.

  10. #10
    Utente di HTML.it
    Registrato dal
    Sep 2004
    Messaggi
    85
    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?

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.