Sto imparando i combinatori di parser in scala e vedo diversi modi di analizzare. Io vedo principalmente tre diversi tipi di parser, ad esempio .RegexpParsers, StandardTokenParsers e JavaTokenParsers.Io sono nuovo nell'analizzare e non ottenere l'idea di come sceglieremo il parser adatto in base alle nostre esigenze. Qualcuno può spiegare come funzionano questi diversi parser e quando usarli.Differenza tra RegexpParsers, StandardTokenParsers e JavaTokenParsers in scala
risposta
RegexpParsers
consentono di utilizzare valori RE (in genere nel modulo "re pattern".r
ma ugualmente qualsiasi altra istanza Regex). Non ci sono produzioni lessicali predefinite (token).
JavaTokenParsers
definisce produzioni lessicali per i token di Java: decimalNumber
, floatingPointNumber
, stringLiteral
, wholeNumber
, ident
(identificatore).
StandardTokenParsers
StandardTokenParsers
definisce produzioni lessicali "... per un linguaggio semplice simile a Scala, analizza parole chiave e identificatori, valori letterali numerici (numeri interi), stringhe e delimitatori". I suoi componenti sono effettivamente definiti in StdLexical
.
ci sono diversi tratti parser diverse e classi base per scopi diversi.
La caratteristica principale è scala.util.parsing.combinator.Parsers
. Questo ha la maggior parte dei combinatori principali come opt
, rep
, elem
, accept
, ecc sicuramente guardare sopra la documentazione per questo, dal momento che questo è la maggior parte di ciò che è necessario sapere. La classe attuale Parser
è qui definita come una classe interna, e questo è importante anche da sapere.
Un'altra caratteristica importante è scala.util.parsing.combinator.lexical.Scanners
. Questa è la caratteristica di base per i parser che legge un flusso di caratteri e produce un flusso di token (noti anche come lexer). Per implementare questo tratto, è necessario implementare un parser whitespace
, che legge caratteri di spazi bianchi, commenti, ecc. È inoltre necessario implementare un metodo token
, che legge il token successivo. I token possono essere qualsiasi cosa tu voglia, ma devono essere una sottoclasse di Scanners.Token
. Lexical
estende Scanners
e StdLexical
estende Lexical
. Il primo fornisce alcune utili operazioni di base (come digit
, letter
), mentre il secondo in realtà definisce e applica i token comuni (come valori letterali numerici, identificatori, stringhe, parole riservate). Devi solo definire e reserved
, e otterrai qualcosa di utile per la maggior parte delle lingue. Le definizioni del token sono in scala.util.parsing.combinator.token.StdTokens
.
Una volta creato un lexer, è possibile definire un parser che legge un flusso di token (prodotto dal lexer) e genera un albero di sintassi astratto. Separare il lexer e il parser è una buona idea poiché non dovrai preoccuparti di spazi bianchi, commenti o altre complicazioni nella sintassi. Se si utilizza StdLexical
, si può prendere in considerazione l'utilizzo di scala.util.parsing.combinator.syntax.StdTokenPasers
che contiene i parser integrati per tradurre token in valori (ad es. StringLit
in String
). Non sono sicuro di quale sia la differenza con StandardTokenParsers
. Se definisci le tue classi di token, dovresti semplicemente usare Parsers
per semplicità.
È espressamente chiesto circa RegexParsers
e JavaTokenParsers
. RegexParsers
è un tratto che si estende Parsers
con un combinatore aggiuntivo: regex
, che fa esattamente quello che ci si aspetterebbe. Mescola RegexParsers
al tuo lexer se vuoi usare le espressioni regolari per abbinare i token.JavaTokenParsers
fornisce alcuni parser che i token lex dalla sintassi Java (come identificatori, numeri interi) ma senza il bagaglio token di Lexical
o StdLexical
.
Per riepilogare, probabilmente si vogliono due parser: uno che legge caratteri e produce token e uno che prende token e produce un AST. Utilizzare qualcosa basato su Lexical
o StdLexical
per il primo. Utilizzare qualcosa in base a Parsers
o StdTokenParsers
per il secondo a seconda se si utilizza StdLexical
.
- 1. Differenza tra Iterator e Stream in Scala?
- 2. Differenza tra scansione e scanLeft in Scala
- 3. In Scala, qual è la differenza tra Any e Object?
- 4. Qual è la differenza tra espressioni e istruzioni in Scala
- 5. La differenza tra "HashSet" e "Set" in Scala?
- 6. Differenza tra la mappa e il metodo foreach in Scala?
- 7. Differenza tra `% in%` e `` ==
- 8. Differenza tra Scala REPL e Clojure REPL - compilare velocità
- 9. Qual è la differenza tra Clojure REPL e Scala REPL?
- 10. Differenza tra mapValues e trasformazione in Mappa
- 11. Differenza tra "" e "" in Python
- 12. Differenza tra $ @ e $! in perl
- 13. Differenza tra. e: in Lua
- 14. Differenza tra parentesi funzione con e senza
- 15. La differenza tra non-fatale ed eccezione in Scala
- 16. Differenza tra. e #
- 17. Differenza tra "o" e "||"
- 18. MySQL: Differenza tra ",", "e"
- 19. Differenza tra "e" e && in Ruby?
- 20. Differenza tra oggetto e *?
- 21. Differenza tra ". +" E ". +?"
- 22. Differenza tra | = e^= css
- 23. CMake: differenza tra $ {} e "$ {}"
- 24. La differenza tra $ * e $ @
- 25. Differenza tra $ # e $ {# @}
- 26. Differenza tra unwrapObservable e()
- 27. Differenza tra "**/* /" e "** /"?
- 28. Differenza tra jquery e $
- 29. VBA: Differenza tra & e +
- 30. Differenza tra numpy.logical_and e &