Un peu de ménage

pull/1/head
Jean-Christophe Jameux 4 years ago
parent 943590c669
commit 9b76010418
  1. 10
      src/GenerateurDeProblemes.elm
  2. 90
      src/ParserExpressionMathematique.elm
  3. 282
      src/ParserMaths.elm

@ -12,7 +12,7 @@ import Fraction as F exposing (Fraction)
import Html exposing (Attribute, Html, button, div, iframe, input, p, section, textarea) import Html exposing (Attribute, Html, button, div, iframe, input, p, section, textarea)
import List as L import List as L
import Parser as P exposing (..) import Parser as P exposing (..)
import ParserMathsPratt as PM import ParserExpressionMathematique as Pem
import Random import Random
import Random.Extra import Random.Extra
import Random.List import Random.List
@ -455,14 +455,14 @@ voirTexteVariable txtvar =
Variable var -> Variable var ->
let let
expressionParseePotentielle = expressionParseePotentielle =
PM.parseMaths var Pem.parserExpressionMathematique var
in in
case expressionParseePotentielle of case expressionParseePotentielle of
Err erreur -> Err erreur ->
"L'expression est mal formée." "L'expression est mal formée."
Ok expressionParsee -> Ok expressionParsee ->
case Result.map F.teX <| PM.evaluer <| expressionParsee of case Result.map F.teX <| Pem.resultatFractionnaire <| expressionParsee of
Ok a -> Ok a ->
a a
@ -568,7 +568,7 @@ variableAremplacer =
aRemplacer : Parser Aremplacer aRemplacer : Parser Aremplacer
aRemplacer = aRemplacer =
succeed (\x y -> Aremplacer x (L.map (F.asciiMath << PM.evaluerBis) y)) succeed (\x y -> Aremplacer x (L.map (F.asciiMath << Pem.evaluerUnsafe) y))
|. espaces |. espaces
|= variable |= variable
{ start = Char.isAlpha { start = Char.isAlpha
@ -582,7 +582,7 @@ aRemplacer =
, separator = "," , separator = ","
, end = "" , end = ""
, spaces = espaces , spaces = espaces
, item = PM.expr , item = Pem.expressionMathematique
, trailing = P.Optional , trailing = P.Optional
} }

@ -1,10 +1,8 @@
module ParserMathsPratt exposing module ParserExpressionMathematique exposing
( Expr(..) ( ExpressionMathematique(..)
, evaluer , evaluerUnsafe
, evaluerBis , expressionMathematique
, expr , parserExpressionMathematique
, montrerErreurs
, parseMaths
, resultatFractionnaire , resultatFractionnaire
) )
@ -15,34 +13,34 @@ import Pratt exposing (constant, infixLeft, infixRight, literal, postfix, prefix
import Set import Set
type Expr type ExpressionMathematique
= Entier Int = Entier Int
| Decimal Float | Decimal Float
| Oppose Expr | Oppose ExpressionMathematique
| Somme Expr Expr | Somme ExpressionMathematique ExpressionMathematique
| Difference Expr Expr | Difference ExpressionMathematique ExpressionMathematique
| Produit Expr Expr | Produit ExpressionMathematique ExpressionMathematique
| Quotient Expr Expr | Quotient ExpressionMathematique ExpressionMathematique
| Reste Expr Expr | Reste ExpressionMathematique ExpressionMathematique
| Exp Expr Expr | Exp ExpressionMathematique ExpressionMathematique
| Cos Expr | Cos ExpressionMathematique
| Sin Expr | Sin ExpressionMathematique
| Tan Expr | Tan ExpressionMathematique
| ArcCos Expr | ArcCos ExpressionMathematique
| ArcSin Expr | ArcSin ExpressionMathematique
| ArcTan Expr | ArcTan ExpressionMathematique
| Log Expr | Log ExpressionMathematique
| Ln Expr | Ln ExpressionMathematique
| Factorielle Expr | Factorielle ExpressionMathematique
| Degre Expr | Degre ExpressionMathematique
| Poly (List Expr) String | Poly (List ExpressionMathematique) String
| E | E
| Pi | Pi
parseMaths : String -> Result (List DeadEnd) Expr parserExpressionMathematique : String -> Result (List DeadEnd) ExpressionMathematique
parseMaths source = parserExpressionMathematique source =
run expr source run expressionMathematique source
montrerErreurs : String -> List DeadEnd -> String montrerErreurs : String -> List DeadEnd -> String
@ -75,8 +73,8 @@ montrerAttendu err =
"une expression" "une expression"
evaluerBis : Expr -> Fraction.Fraction evaluerUnsafe : ExpressionMathematique -> Fraction.Fraction
evaluerBis expression = evaluerUnsafe expression =
case resultatFractionnaire expression of case resultatFractionnaire expression of
Err _ -> Err _ ->
{ numerateur = 666, denominateur = 1 } { numerateur = 666, denominateur = 1 }
@ -85,11 +83,7 @@ evaluerBis expression =
a a
evaluer = resultatFractionnaire : ExpressionMathematique -> Fraction.Resultat
resultatFractionnaire
resultatFractionnaire : Expr -> Fraction.Resultat
resultatFractionnaire expression = resultatFractionnaire expression =
let let
f opperation a b = f opperation a b =
@ -124,14 +118,8 @@ resultatFractionnaire expression =
Err "BOOM" Err "BOOM"
expr : Parser Expr expressionMathematique : Parser ExpressionMathematique
expr = expressionMathematique =
succeed identity
|= mathExpression
mathExpression : Parser Expr
mathExpression =
Pratt.expression Pratt.expression
{ oneOf = { oneOf =
[ constant (keyword "E") E [ constant (keyword "E") E
@ -159,15 +147,11 @@ mathExpression =
, postfix 6 (symbol "!") Factorielle , postfix 6 (symbol "!") Factorielle
, postfix 6 (symbol "°") Degre , postfix 6 (symbol "°") Degre
] ]
, spaces = espaces , spaces = Parser.spaces
} }
espaces = expressionEntreParentheses : Pratt.Config ExpressionMathematique -> Parser ExpressionMathematique
Parser.chompWhile <| (==) ' '
expressionEntreParentheses : Pratt.Config Expr -> Parser Expr
expressionEntreParentheses config = expressionEntreParentheses config =
succeed identity succeed identity
|. symbol "(" |. symbol "("
@ -175,8 +159,8 @@ expressionEntreParentheses config =
|. symbol ")" |. symbol ")"
poly : Parser Expr polynome : Parser ExpressionMathematique
poly = polynome =
succeed Poly succeed Poly
|. keyword "Poly" |. keyword "Poly"
|. spaces |. spaces
@ -185,7 +169,7 @@ poly =
, separator = "," , separator = ","
, end = "]" , end = "]"
, spaces = spaces , spaces = spaces
, item = lazy (\_ -> mathExpression) , item = lazy (\_ -> expressionMathematique)
, trailing = Forbidden , trailing = Forbidden
} }
|. spaces |. spaces

@ -1,282 +0,0 @@
module ParserMaths exposing (evaluer, evaluerBis, expr, montrerErreurs, parseMaths)
import Fraction as F exposing (Fraction, Resultat, fraction, map2)
import Maybe as M
import Parser exposing (..)
import Set
montrerErreurs : String -> List DeadEnd -> String
montrerErreurs source errs =
case List.head errs of
Nothing ->
""
Just firstErr ->
source
++ "\n"
++ String.repeat (firstErr.col - 1) " "
++ "^"
++ "\nL'algorithme attendait :"
++ String.join
" ou "
(List.map montrerAttendu errs)
montrerAttendu : DeadEnd -> String
montrerAttendu err =
case err.problem of
ExpectingNumber ->
"un nombre entier"
ExpectingSymbol s ->
"un \"" ++ s ++ "\""
_ ->
"une expression"
evaluerBis : Expr -> Fraction
evaluerBis expression =
case evaluer expression of
Err _ ->
{ numerateur = 666, denominateur = 1 }
Ok a ->
a
evaluer : Expr -> Resultat
evaluer expression =
case expression of
Add a b ->
map2 F.somme (evaluer a) (evaluer b)
Sub a b ->
map2 F.difference (evaluer a) (evaluer b)
Mul a b ->
map2 F.produit (evaluer a) (evaluer b)
Div a b ->
map2 F.quotient (evaluer a) (evaluer b)
Exp a b ->
map2 F.exp (evaluer a) (evaluer b)
Neg a ->
Result.map F.oppose (evaluer a)
Grouping l ->
evaluer l
Entier n ->
F.fraction n 1
Poly a_i x ->
Err "Les polynômes ne sont pas encore pris en charge."
type Expr
= Add Expr Expr
| Sub Expr Expr
| Mul Expr Expr
| Div Expr Expr
| Exp Expr Expr
| Neg Expr
| Entier Int
| Grouping Expr
| Poly (List Expr) String
parseMaths : String -> Result (List DeadEnd) Expr
parseMaths source =
run expr source
expr : Parser Expr
expr =
add
type Operator
= MulOp
| DivOp
| AddOp
| SubOp
| ExpOp
type Operand
= NoOperand
| Operand Operator Expr
{-| En quelque sorte, décurryfie une expression binaire
binary e\_1 (Operand MulOp e\_2) == Mul e\_1 e\_2
-}
binary : Expr -> Operand -> Expr
binary a b =
case b of
NoOperand ->
a
Operand op e ->
case op of
MulOp ->
Mul a e
DivOp ->
Div a e
AddOp ->
Add a e
SubOp ->
Sub a e
ExpOp ->
Exp a e
add : Parser Expr
add =
succeed
foldBinary
|= mul
|. spaces
|= loop [] addHelper
--
foldBinary : Expr -> List Operand -> Expr
foldBinary left operands =
List.foldr
(\operand expression -> binary expression operand)
left
operands
addHelper : List Operand -> Parser (Step (List Operand) (List Operand))
addHelper operands =
oneOf
[ succeed (\right -> Loop (Operand AddOp right :: operands))
|. symbol "+"
|. spaces
|= lazy (\_ -> mul)
, succeed (\right -> Loop (Operand SubOp right :: operands))
|. symbol "-"
|. spaces
|= lazy (\_ -> mul)
, succeed ()
|> map (\_ -> Done operands)
]
mul : Parser Expr
mul =
succeed
foldBinary
|= exp
|. spaces
|= loop [] mulHelper
mulHelper : List Operand -> Parser (Step (List Operand) (List Operand))
mulHelper operands =
oneOf
[ succeed (\right -> Loop (Operand MulOp right :: operands))
|. symbol "*"
|. spaces
|= lazy (\_ -> exp)
, succeed (\right -> Loop (Operand DivOp right :: operands))
|. symbol "/"
|. spaces
|= lazy (\_ -> exp)
, succeed ()
|> map (\_ -> Done operands)
]
exp : Parser Expr
exp =
succeed
binary
|= primary
|. spaces
|= oneOf
[ succeed (Operand ExpOp)
|. symbol "^"
|. spaces
|= lazy (\_ -> exp)
, succeed NoOperand
]
primary : Parser Expr
primary =
succeed
(\op literal ->
case op of
Nothing ->
literal
Just _ ->
Neg literal
)
|= oneOf
[ succeed Just
|= symbol "-"
, succeed Nothing
]
|= oneOf
[ grouping
, poly
, nombre
]
nombre : Parser Expr
nombre =
succeed Entier
|= number
{ int = Just identity
, hex = Nothing
, octal = Nothing
, binary = Nothing
, float = Nothing
}
poly : Parser Expr
poly =
succeed Poly
|. keyword "Poly"
|. spaces
|= sequence
{ start = "["
, separator = ","
, end = "]"
, spaces = spaces
, item = lazy (\_ -> expr)
, trailing = Forbidden
}
|. spaces
|= variable
{ start = \_ -> True
, inner = \_ -> False
, reserved = Set.fromList []
}
grouping : Parser Expr
grouping =
succeed Grouping
|. symbol "("
|. spaces
|= lazy (\_ -> expr)
|. spaces
|. symbol ")"
Loading…
Cancel
Save