J'essayais de faire un analyseur d'expression pour deux opérateurs dont seul ^
est postfixe unaire, donc avec un opérande cela ressemblerait à R^
.Analyseur d'expression pour opérateur unaire
Le problème est que chaque fois que l'opérateur ^
est rencontré ailleurs que dans la fin, il s'arrête juste là et renvoie tout ce qui a été analysé avec succès. Cela signifie "R;S;T^"
analyse avec succès, mais "R^;S;T^"
s'arrête à R
. Cependant, "(R^);S;T^"
fonctionne bien.
J'ai pris l'aide d'un poste en ligne qu'il utilisait pour moins unaire mais c'est un opérateur de préfixe (par exemple -X
). Sa solution originale donnait des erreurs à reservedOp2
, donc je l'ai modifié à reservedOp2 name = try (string name >> notFollowedBy (oneOf opChar))
et il produit la sortie mentionnée ci-dessus. J'en ai besoin pour travailler avec ou sans parenthèse.
import Control.Applicative
import Text.ParserCombinators.Parsec hiding (many,optinal,(<|>))
import Text.ParserCombinators.Parsec.Expr
import Text.Parsec.Language (haskell)
import qualified Text.Parsec.Token as P
import Text.Parsec.String (Parser)
data RT = Comp RT RT
| Conv RT
| Var String
deriving (Show)
whiteSpace = P.whiteSpace haskell
word = P.identifier haskell
parens = P.parens haskell
opChar = "^;"
reservedOp2 :: String -> CharParser st()
reservedOp2 name = try (string name >> notFollowedBy (oneOf opChar) >> whiteSpace)
term = parens relexpr
<|> Var <$> word
<?> "term"
table = [ [postfix "^" Conv]
, [binary ";" Comp AssocLeft]
]
prefix name fun = Prefix $ reservedOp2 name >> return fun
binary name fun = Infix $ reservedOp2 name >> return fun
postfix name fun = Postfix $ reservedOp2 name >> return fun
relexpr :: Parser RT
relexpr = buildExpressionParser table term <?> "expression"
Votre définition de 'term' est-elle correcte? Ne devrait-il pas ressembler à parens relexpr <|> ... mot Var ... > "terme" '? (Commentaire sur 'binary' et assoc supprimés) – ErikR
@ user5402 Je pense que le terme est correctement défini, le problème est dans le reservedOp2. C'est le code complet. – Wazed