Estoy tratando de extender un analizador sintáctico descendente recursivo para manejar nuevos operadores y asociarlos correctamente. Originalmente solo había cuatro operadores (+ -/*) y todos tenían la misma precedencia. La función que estoy mirando es la función parseExpRec:Prioridad y asociatividad del operador en un analizador (Haskell)
parseExpRec :: Exp -> [Token] -> (Exp, [Token])
parseExpRec e [] = (e, [])
parseExpRec e1 (op : ts) =
let (e2, ts') = parsePrimExp ts in
case op of
T_Power -> parseExpRec (BinOpApp Power e1 e2) ts'
T_Plus -> parseExpRec (BinOpApp Plus e1 e2) ts'
T_Minus -> parseExpRec (BinOpApp Minus e1 e2) ts'
T_Times -> parseExpRec (BinOpApp Times e1 e2) ts'
T_Divide -> parseExpRec (BinOpApp Divide e1 e2) ts'
T_GreaterThan -> parseExpRec (BinOpApp GreaterThan e1 e2) ts'
T_LessThan -> parseExpRec (BinOpApp LessThan e1 e2) ts'
T_GreaterOrEqual -> parseExpRec (BinOpApp GreaterOrEqual e1 e2) ts'
T_LessOrEqual -> parseExpRec (BinOpApp LessOrEqual e1 e2) ts'
T_EqualTo -> parseExpRec (BinOpApp EqualTo e1 e2) ts'
_ -> (e1, op : ts)
Todo el patrón de las líneas excepto T_Plus, T_Minus, T_Times y T_Divide juego se han añadido por mí (y así tener la tokens y extensiones asociadas al tipo de datos Exp) Sin embargo, ninguno de ellos parece asociarse correctamente. Por ejemplo, la cadena "3^4 + 2^3" se evalúa como:
BinOpApp alimentación (BinOpApp Plus (BinOpApp alimentación (LitInt 3) (LitInt 4)) (LitInt 2)) (LitInt 3)
que es equivalente a esto en notación infija (con soportes incluidos):
((3^4) +2)^3
¿Cómo puedo solucionar este problema?
Hay muchos excelentes combinadores de analizadores en Haskell. ¿Es una opción usar uno de esos en lugar de implementar el análisis en una función recursiva (que es muy difícil en general)? – Martijn