Il mio obiettivo è creare un parser di comandi con sintassi di base e più rami possibili in ogni punto. Questi comandi provengono dagli utenti del sistema e sono di input di testo (senza GUI). La sintassi di base è base_command [sub_command [optional_parameters]]
, in cui optional_parameters
è uno spazio separato elenco di parametri.
Esempi:
add event "Program-a-thon"
add notification program-a-thon meeting
add pattern "follow the white rabbit"
remove event "Program-a-thon"
remove notification meeting
remove pattern "follow the white rabbit"
edit pattern "follow the white rabbit" "follow the white tiger"
reload settings
Come puoi vedere, ho 4 comandi di base ( add
, remove
, edit
e reload
). Tuttavia, prevedo di aggiungerne altri in futuro. Ho anche 4 sottocomandi ( event
, notification
, pattern
e settings
). Tuttavia, edit
ha solo 1 sottocomando e settings
si applica solo al comando reload
base. Non tutti i sottocomandi sono associati a tutti i comandi di base. Infine, ho dei parametri. Per semplicità, sto pensando di rendere queste posizioni basate.
Sto scrivendo questa applicazione in Python (utilizzando il ramo 2.7).
Finora, ho trovato questo:
-
Utilizza il comando
.split()
e prendi i primi due risultati per ottenere il comando e il comando di base. Il terzo indice (se esiste) sarà gli argomenti posizionali.o
-
Utilizzare un'espressione regolare per ottenere il comando di base e il sottocomando. Il terzo indice sarà argomenti posizionali.
Quindi, utilizzando queste informazioni, guarda un dizionario come questo per vedere se l'opzione comando / sottocomando è valida. Se lo è, chiama method
descritto nella chiave commands[base_command][sub_command]['method']
per eseguire la mia azione.
Il lato positivo di questo è che posso facilmente capire se la combinazione comando / sottocomando è valida. Il rovescio della medaglia è mantenere un tale dizionario ed eventualmente estenderlo se desidero aggiungere più opzioni o informazioni. Per questi pochi comandi ho già un dizionario come questo (con alcuni attributi di supporto)
commands =
{
'add' :
{
'help_text' : "Add a 'event', 'notification', or 'pattern'",
'sub_commands': {
'event' : {
'help_text' : "Add an event",
'method' : "add_event",
'permissions' : 'trusted',
},
'notification' : {
'help_text' : "Recieve a notification for events that are tagged with the values you wish (tag1 [,tag2[,tag3[,tag4]]])",
'method' : "add_notification",
'permissions' : 'all',
},
'pattern' : {
'help_text' : "Add a pattern you wish the system to watch for in new event descriptions",
'method' : "add_pattern",
'permissions' : 'all',
},
},
'sub_command_required' : True,
'method' : None,
},
'remove':
{
'help_text': "Remove a 'event', 'notification', or 'pattern'",
'sub_commands': {
'event' : {
'help_text' : "Remove an event",
'method' : "remove_event",
'permissions' : 'trusted',
},
'notification' : {
'help_text' : "Remove a notification for specific tags (tag1 [,tag2[,tag3[,tag4]]])",
'method' : "remove_notification",
'permissions' : 'all',
},
'pattern' : {
'help_text' : "Add a pattern you wish the system to watch for in new event descriptions",
'method' : "remove_pattern",
'permissions' : 'all',
},
},
'sub_command_required' : True,
'method' : None,
},
'edit':
{
'help_text': "Edit an existing 'pattern'",
'sub_commands': {
'pattern' : {
'help_text' : "Edit a pattern pattern to watch for in new event descriptions (old_pattern, new_pattern)",
'method' : "edit_pattern",
'permissions' : 'all',
},
},
'sub_command_required' : True,
'method' : None,
},
'reload':
{
'help_text': "Reload application options",
'sub_commands': {
'settings' : {
'help_text' : "Reload the settings of the application",
'method' : "reload_settings",
'permissions' : 'owner',
},
},
'sub_command_required' : True,
'method' : None,
},
}
Le mie domande sono, come faccio a progettare correttamente il parser in modo che io possa
- Estendi l'albero dei comandi facilmente in futuro?
- Hai una combinazione di comandi secondari che possono essere applicati a tutti i comandi di base?
E
- L'utilizzo di un dizionario, come sopra, vale il problema della manutenzione durante l'aggiunta di comandi? Mi rendo conto che i comandi saranno "relativamente" stabili (una volta aggiunte, le modifiche saranno rare al dizionario stesso). Tuttavia, quando li aggiungo, probabilmente arriveranno almeno in coppie (
add
eremove
), il che significa che il potenziale per incasinare il dizionario si verifica in più punti.