Autore Topic: Idee e spunti per una calcolatrice - Parte Software  (Letto 21908 volte)

Offline Allanon

  • Administrator
  • Synthetic Voodoo
  • *****
  • Post: 3498
  • Karma: +17/-4
    • Mostra profilo
    • http://www.a-mc.biz
Re:Idee e spunti per una calcolatrice - Parte Software
« Risposta #30 il: 21 Giugno 2015, 16:41:41 »
Credo tu debba per forza analizzare tutti gli elementi e vedere se hanno il punto al loro interno e decifrarli

numero . numero -> decimale
non-numero . numero -> boh
numero . non-numero -> possibile notazione scientifica?
non-numero . non-numero -> possibile struct member?

Insomma, robaccia grezza e bruta tipo questa :P

ocio però a
.245
p.p_this.p_that

X_X

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
Re:Idee e spunti per una calcolatrice - Parte Software
« Risposta #31 il: 21 Giugno 2015, 17:10:14 »
beh semplice: un nome di variabile non può iniziare con un numero, quindi se stavi parsando un numero e trovi un punto, sarà un numero in virgola mobile. Anche se vuoi parsare espressioni tipo ".25", di sicuro non può essere il punto inteso come indicizzazione in struttura.

Esempi:

12.48 -- Vede 1 e inizia a leggere un "numero"; quando arriva al . capisce che non è "intero" ma è "float", e quindi finisce le ultime due cifre.
.88     -- il punto è seguito da un numero: è per forza un numero float nella forma 0.xxx (e di sicuro non può essere una struttura, perchè non hai il nome della struttura su cui applicare il punto).
p123.z4 -- parte da "p", deve essere un identificatore. Continua leggendo "p123" come identificatore. Quando incontra il punto, è ovvio che non può essere un numero, e quindi viene emesso il token di indicizzazione in struttura. Continua leggendo "z4" che è un identificatore valido e termina.
456.0abc7 -- Errore: inizia leggendo 456, vede il punto (=> è un float in forma 456.xxx), legge 0 e gli va ancora bene, legge "a" e si ferma in errore in quanto "a" non è una cifra valida.
98.abc77  -- inizia leggendo "98", al punto capisce che è float, si ferma al "a" in quanto si aspettava la parte decimale fatta solo da cifre (nota che, in se, "abc77" è un identificatore valido, però avendolo trovato mentre il lexer era in modalità "numero float" non ci va bene).
kk_a8.9087 -- vede "k" e parte in modalità identificatore; legge "kk_a8" che è un identificatore valido, al punto capisce che deve essere una struttura (ed emette il token adeguato), però dopo incontra un "9" che non va bene come carattere iniziale di un identificatore, e quindi si ferma in errore (nota che di per se "9087" è un numero valido).

Insomma, il lexer deve avere uno stato su cui può lavorare, non puoi parsare solo guardando un carattere alla volta.

Per i prefissi scientifici, la situazione è la stessa: sei nel quarto caso (456.0abc7), solo che in questo caso (mettiamo 456.01M), quando incontri M, puoi vedere nella tabellina di prefissi validi, scopri che lo è, e quindi lo includi nel numero (o magari scali direttamente il numero della potenza adeguata), solo che poi devi star attento a portare il lexer via dalla modalità "numero", perchè non puoi avere 123.23M214, quindi qualsiasi cifra successiva va segnata come errore.

Per l'esponente, stesso discorso di sopra, solo che una volta che incontri "e" o "E", invece di portare il lexer in modalità "niente cifre", lo porti in modalità "lettura esponente", e procedi come per qualsiasi altro numero.

TL;DR: un numero lo discrimini da un identificatore perchè un numero inizia con una cifra, mentre un identificatore con una lettera (o "_").

Offline Z80Fan

  • Administrator
  • Guru
  • *****
  • Post: 1671
  • Karma: +13/-2
    • Mostra profilo
    • http://z80fan.altervista.org
Re:Idee e spunti per una calcolatrice - Parte Software
« Risposta #32 il: 21 Giugno 2015, 22:18:41 »
non ragiona un carattere alla volta, ragiona per win look ahead
finestre in cui identifica
- separator (che possono essere anche + lunghi di 1 carattere)
- keyword

ora, un separator e' il "." punto, se lo escludo dalla lista dei separator qualsiasi cosa contenga un punto viene vista come un monoblocco

Beh, si potrebbe dire che abbiamo trovato il limite di questo approccio al lexer. :D

A meno di non rifare tutto il lexer con un approccio più "tradizionale"* (potenzialmente più complesso nella sua implementazione), la soluzione con la funzione alternativa che ricontrolla il blocco per discriminare ulteriormente può essere una buona soluzione.
Stai solo attento mentre vai avanti nello sviluppo e tieni un occhio su questi casi speciali in modo che non esplodano e rendano tutto più difficile da seguire. In caso sia necessario, è conveniente a quel punto ripensare al linguaggio ed eventualmente ripartire da capo (se il parser e il lexer sono abbastanza isolati, questo processo dovrebbe essere relativamente indolore).


* Con "tradizionale" intendo un lexer che elabora l'input con un singolo carattere di look-ahead, e a ogni iterazione aggiorna il suo stato interno per seguire l'input. In questo modo, casi "speciali" come questo non sono per niente speciali (semplicemente un altro stato nella state-machine), e puoi scrivere il codice più o meno come ho descritto a parole prima.
Da quanto ho capito, il tuo lexer funziona prima prendendo la massima stringa di caratteri che non contiene un separatore, e successivamente cerca di associarci un significato come blocco unico. Come ti è capitato proprio ora, per alcune situazioni particolari, dove ogni carattere è una specie di separatore, o quantomeno un carattere in una certa posizione può avere significati diversi (es. un alfanumerico che non sia "e" dopo un punto è quasi sicuramente l'inizio di un identificatore, mentre se trovi un numero è la parte decimale di un float), questo approccio ha limitazioni che possono essere gestite solo attraverso un caso speciale che rompe l'"ortogonalità" del lexer.

Offline Allanon

  • Administrator
  • Synthetic Voodoo
  • *****
  • Post: 3498
  • Karma: +17/-4
    • Mostra profilo
    • http://www.a-mc.biz
Re:Idee e spunti per una calcolatrice - Parte Software
« Risposta #33 il: 16 Agosto 2015, 08:03:09 »
Saranno tutti in ferie!
Cmq io questo thread lo sto seguendo ma non intervengo perchè la faccenda è un po' complessa :P

Offline Allanon

  • Administrator
  • Synthetic Voodoo
  • *****
  • Post: 3498
  • Karma: +17/-4
    • Mostra profilo
    • http://www.a-mc.biz
Re:Idee e spunti per una calcolatrice - Parte Software
« Risposta #34 il: 21 Settembre 2015, 23:52:26 »
O_O'
Ma stai progettando un tokener/parser o Skynet??

Offline Allanon

  • Administrator
  • Synthetic Voodoo
  • *****
  • Post: 3498
  • Karma: +17/-4
    • Mostra profilo
    • http://www.a-mc.biz
Re:Idee e spunti per una calcolatrice - Parte Software
« Risposta #35 il: 22 Settembre 2015, 08:11:18 »
O_O'
Mi riservo di rileggere gli ultimi post con più calma  ;D

Offline Allanon

  • Administrator
  • Synthetic Voodoo
  • *****
  • Post: 3498
  • Karma: +17/-4
    • Mostra profilo
    • http://www.a-mc.biz
Re:Idee e spunti per una calcolatrice - Parte Software
« Risposta #36 il: 22 Settembre 2015, 15:45:59 »
summoniamolo!!  ;D

Offline saimon69

  • Guru
  • *****
  • Post: 1833
  • Karma: +23/-3
  • Web Dev e musicista da camera (da letto)
    • Mostra profilo
    • binarydoodles Blog
Re:Idee e spunti per una calcolatrice - Parte Software
« Risposta #37 il: 07 Luglio 2016, 19:04:47 »
chi si vede \o bentornato!
AROS : mica bau bau micio micio =^x^=

Tags: