Quale linguaggio di programmazione scegliere per questa libreria open source? [chiuso]

2

Quale idioma di programmazione è più facile da usare per gli sviluppatori principianti che scrivono classi di analisi dei file concreti?

Sto sviluppando una libreria open source, che una delle funzionalità principali è quella di analizzare i file di testo e ottenere informazioni strutturate da essi. Tutti i file contengono lo stesso tipo di informazioni, ma possono essere in diversi formati come XML, testo normale (ognuno di essi è strutturato in modo diverso), ecc. Ci sono un insieme comune di pezzi di informazione che è lo stesso in tutti (es. nomi, nomi di tabelle, alcuni numeri di identificazione)

Esistono formati molto simili tra loro, quindi è possibile definire una classe base comune per facilitare l'implementazione concreta del parser di formato. Quindi posso chiaramente definire le classi base come SplittablePlainTextFormat , XMLFormat , SeparateSummaryFormat , ecc. Ognuno di loro suggerisce il tipo di struttura che intendono analizzare. Tutte le classi concrete dovrebbero avere le stesse informazioni, non importa quale.

Per essere utile, questa libreria deve definire almeno 30-40 di questi parser. Un paio di questi sono più importanti di altri (ovviamente i formati più popolari).

Ora la mia domanda è: qual è il miglior idioma di programmazione da scegliere per facilitare lo sviluppo di queste classi concrete? Lasciami spiegare:

Penso che la programmazione imperativa sia facile da seguire anche per i principianti, perché il flusso è fisso, le dichiarazioni arrivano una dopo l'altra. In questo momento, ho questo:

class SplittableBaseFormat:
    def parse(self):
        "Parses the body of the hand history, but first parse header if not yet parsed."
        if not self.header_parsed:
            self.parse_header()

        self._parse_table()
        self._parse_players()
        self._parse_button()
        self._parse_hero()
        self._parse_preflop()
        self._parse_street('flop')
        self._parse_street('turn')
        self._parse_street('river')
        self._parse_showdown()
        self._parse_pot()
        self._parse_board()
        self._parse_winners()
        self._parse_extra()

        self.parsed = True

Quindi il parser concreto deve definire questi metodi in modo che essi desiderino. Facile da seguire, ma richiede più tempo per implementare ogni singolo parser concreto.

Quindi che dire di dichiarativo? In questo caso le classi base (come SplittableFormat e XMLFormat ) farebbero il sollevamento pesante in base alle dichiarazioni di numero di riga / nodo nella classe concreta e le classi concrete non hanno alcun codice, solo numeri di riga e regex, forse altri tipi di regole.

In questo modo:

class SplittableFormat:
    def parse_table():
        "Parses TABLE_REGEX and get information"
        # set attributes here

    def parse_players():
        "parses PLAYER_REGEX and get information"
        # set attributes here


class SpecificFormat1(SplittableFormat):
    TABLE_REGEX = re.compile('^(?P<table_name>.*) other info \d* etc')
    TABLE_LINE = 1
    PLAYER_REGEX = re.compile('^Player \d: (?P<player_name>.*) has (.*) in chips.')
    PLAYER_LINE = 16


class SpecificFormat2(SplittableFormat):
    TABLE_REGEX = re.compile(r'^Tournament #(\d*) (?P<table_name>.*) other info2 \d* etc')
    TABLE_LINE = 2
    PLAYER_REGEX = re.compile(r'^Seat \d: (?P<player_name>.*) has a stack of (\d*)')
    PLAYER_LINE = 14

Quindi, se voglio rendere possibile ai non sviluppatori di scrivere queste classi la via da percorrere sembra essere il modo dichiarativo, sono quasi certo di non poter eliminare le dichiarazioni di regex, che chiaramente richiedono (senior: D) programmatori, quindi dovrei preoccuparmene? Pensi che sia importante sceglierne uno rispetto a un altro o non importa affatto? Forse se qualcuno vuole lavorare su questo progetto, lo farà, se non lo farà, indipendentemente dall'idioma che scelgo. Posso "convertire" i non programmatori per aiutarli a svilupparli? Quali sono le tue osservazioni?

Altre considerazioni: Imperativo consentirà qualsiasi tipo di lavoro; c'è un flusso semplice, che possono seguire ma al loro interno possono fare tutto ciò che vogliono. Sarebbe più difficile forzare un'interfaccia comune con imperativo a causa di queste implementazioni arbitrarie. Il dichiarativo sarà molto più rigido, il che è una cosa negativa, perché i formati potrebbero cambiare nel tempo senza preavviso. Dichiarare sarà più difficile per me sviluppare e richiedere più tempo. Imperativo è già pronto per il rilascio.

Sto cercando risposte su quali idiomi utilizzare quando, il che è meglio per progetti open source con diversi scenari, che è meglio per una vasta gamma di capacità di sviluppo.

TL; DR:

  • Analisi di diversi formati di file (testo normale, XML)
  • contengono lo stesso tipo di informazioni
  • Destinatari: non sviluppatori, principianti
  • Probabilmente il regex non può essere evitato
  • Sono necessarie 30-40 classi di parser concreto
  • Facilitare la codifica di queste classi concrete
  • Quale idioma è migliore?
posta kissgyorgy 25.08.2014 - 14:43
fonte

2 risposte

2

Penso che puoi seguire il percorso dichiarativo in minilanguage, ma difficilmente troverai one che funzioni per tutti questi formati.

Considera di raggruppare i tuoi formati. Ad esempio:

  1. per analizzare l'XML, o qualcosa di simile strutturato, usando qualcosa di diverso da un parser XML probabilmente sta chiedendo dei problemi. Potresti essere in grado di fornire un motore generale XML-to-any che gli utenti meno tecnici possono configurare, magari semplicemente specificando quali tag devono essere mappati su quali campi.
  2. per l'analisi del testo, le espressioni regolari piene sembrano esagerazioni per i tuoi esempi: potresti gestire quelli con scanf. Probabilmente potresti fornire una traduzione da qualcosa come le stringhe in formato Python alla regex, mentre esponi i RE direttamente agli utenti che li vogliono

    ad es. convertire il leggermente più user-friendly

    'Player {player_num:d}: {player_name:s} has {player_chips:d} in chips.'
    

    a

    'Player (?P<player_num>\d+): (?P<player_name>\S+) has (?<player_chips>\d+) in chips.'
    

    NB. la stringa originale non è molto più semplice della RE, anche se c'è un po 'meno rumore, ma ci sono molte meno opportunità per un utente non tecnico di confondersi rispetto a una RE

  3. per l'analisi di formati CSV, a larghezza fissa o binari, alcuni parser generali possono probabilmente essere configurati con delimitatore, larghezza di campo o tipo + informazioni sulla dimensione rispettivamente. Quindi torniamo a specificare il mapping da colonne a campi, simile a XML.

Poiché nessuno di questi ha molto in comune, cercare di adattarli tutti in un unico DSL è difficile. Finirà -come le espressioni regolari- essere troppo generale per un principiante per imparare facilmente.

Lo svantaggio è che sarà difficile fornire uniformità o coerenza tra i formati in diversi gruppi. Tuttavia, ogni singolo gruppo dovrebbe essere molto più facile da imparare e supportare.

    
risposta data 27.08.2014 - 13:43
fonte
1

Dovresti esaminare le librerie combinatore di parser, che, se impostate correttamente, possono darti una sintassi dichiarativa che è più facile da leggere rispetto all'esempio di discesa ricorsiva o all'esempio di regex. Fatto correttamente, sembra una concatenazione di una stringa, ma funziona al contrario. Con un po 'di lavoro da parte tua, potrebbe sembrare qualcosa di simile:

parser = "Player" + playerNumber + ":" + playerName + "has" + chipCount + "in chips"

Detto questo, se vuoi davvero che i non programmatori contribuiscano, vorrai creare una specie di estrattore grafico guidato. Pensa al wizard che ottieni quando apri un file di testo in Excel o al modo in cui AdBlock ti permette di scegliere un elemento sulla pagina da bloccare. Il codice esegue un rilevamento automatico sulla struttura di base, l'utente risponde ad alcune domande per ottenere le colonne in modo corretto, etichetta i diversi campi, quindi il codice evidenzia tutti i campi e l'utente conferma. Questo sistema sarebbe difficile da creare, ma renderà molto piacevole la manutenzione delle modifiche ai formati.

    
risposta data 27.08.2014 - 14:34
fonte

Leggi altre domande sui tag