Sto provando a scrivere un parser per il calcolo proposizionale usando Parsec. Il parser utilizza la funzione buildExpressionParser
da Text.Parsec.Expr. Ecco il codice in cui definisco gli operatori logici.Perché viene analizzato solo il primo operatore infisso definito quando si utilizza buildExpressionParser di Parsec?
operators = [ [Prefix (string "~" >> return Negation)]
, [binary "&" Conjunction]
, [binary "|" Disjunction]
, [binary "->" Conditional]
, [binary "<->" Biconditional]
]
binary n c = Infix (spaces >> string n >> spaces >> return c) AssocRight
expr = buildExpressionParser operators term
<?> "compound expression"
ho omesso i parser per le variabili, i termini e le espressioni parentesi, ma se si pensa che possono essere rilevanti per il problema è possibile leggere le full source for the parser.
Il parser ha esito positivo per le espressioni che utilizzano solo la negazione e la congiunzione, ovvero l'unico operatore di prefisso e il primo operatore di infisso.
*Data.Logic.Propositional.Parser2> runPT expr() "" "p & ~q"
Right (p ∧ ¬q)
Espressioni che utilizzano altri operatori non riescono sul primo carattere dell'operatore, con un errore simile al seguente:
*Data.Logic.Propositional.Parser2> runPT expr() "" "p | q"
Left (line 1, column 3):
unexpected "|"
expecting space or "&"
Se commento fuori la linea che definisce il parser per congiunzioni, allora il parser perché la disgiunzione funzionerà (ma il resto continuerà a fallire). Inserirli tutti in un'unica lista (vale a dire della stessa precedenza) non funziona neanche: lo stesso problema si manifesta ancora.
Qualcuno può indicare cosa sto facendo male? Grazie molto.
Grazie a Daniel Fischer per una risposta così rapida e utile.
Per completare il corretto funzionamento di questo parser, ho anche dovuto gestire le ripetute applicazioni del simbolo di negazione, in modo tale che ad es. ~~p
potrebbe analizzare correttamente. This SO answer mi ha mostrato come farlo, e la modifica apportata al parser può essere trovata here.
Grazie per l'ottima risposta, Daniel. Risolve il problema e lo spiega anche. Sono molto grato. –