Code source du site TeacherCorner.lamdera.app, contenant une suite d'outils permettant d'automatiser la production de documents pédagogiques.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
TeacherCorner/src/ParserExpressionMathematiqu...

180 lines
5.0 KiB

module ParserExpressionMathematique exposing
( ExpressionMathematique(..)
, evaluerUnsafe
, expressionMathematique
, parserExpressionMathematique
, resultatFractionnaire
)
import Fraction
import Maybe as M
import Parser exposing (..)
import Pratt exposing (constant, infixLeft, infixRight, literal, postfix, prefix)
import Set
type ExpressionMathematique
= Entier Int
| Decimal Float
| Oppose ExpressionMathematique
| Somme ExpressionMathematique ExpressionMathematique
| Difference ExpressionMathematique ExpressionMathematique
| Produit ExpressionMathematique ExpressionMathematique
| Quotient ExpressionMathematique ExpressionMathematique
| Reste ExpressionMathematique ExpressionMathematique
| Exp ExpressionMathematique ExpressionMathematique
| Cos ExpressionMathematique
| Sin ExpressionMathematique
| Tan ExpressionMathematique
| ArcCos ExpressionMathematique
| ArcSin ExpressionMathematique
| ArcTan ExpressionMathematique
| Log ExpressionMathematique
| Ln ExpressionMathematique
| Factorielle ExpressionMathematique
| Degre ExpressionMathematique
| Poly (List ExpressionMathematique) String
| E
| Pi
parserExpressionMathematique : String -> Result (List DeadEnd) ExpressionMathematique
parserExpressionMathematique source =
run expressionMathematique source
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"
evaluerUnsafe : ExpressionMathematique -> Fraction.Fraction
evaluerUnsafe expression =
case resultatFractionnaire expression of
Err _ ->
{ numerateur = 666, denominateur = 1 }
Ok a ->
a
resultatFractionnaire : ExpressionMathematique -> Fraction.Resultat
resultatFractionnaire expression =
let
f opperation a b =
Fraction.map2 opperation (resultatFractionnaire a) (resultatFractionnaire b)
in
case expression of
Somme a b ->
f Fraction.somme a b
Difference a b ->
f Fraction.difference a b
Produit a b ->
f Fraction.produit a b
Quotient a b ->
f Fraction.quotient a b
Exp a b ->
f Fraction.exp a b
Oppose a ->
Result.map Fraction.oppose (resultatFractionnaire a)
Entier n ->
Fraction.fraction n 1
Poly a_i x ->
Err "Les polynômes ne sont pas encore pris en charge."
_ ->
Err "BOOM"
expressionMathematique : Parser ExpressionMathematique
expressionMathematique =
Pratt.expression
{ oneOf =
[ constant (keyword "E") E
, constant (keyword "Pi") Pi
, literal (map Entier int)
, prefix 3 (symbol "-") Oppose
, expressionEntreParentheses
, prefix 3 (symbol "+") identity
, prefix 5 (keyword "Cos") Cos
, prefix 5 (keyword "Sin") Sin
, prefix 5 (keyword "Tan") Tan
, prefix 5 (keyword "ArcCos") ArcCos
, prefix 5 (keyword "ArcSin") ArcSin
, prefix 5 (keyword "ArcTan") ArcTan
, prefix 5 (keyword "Log") Log
, prefix 5 (keyword "Ln") Ln
]
, andThenOneOf =
[ infixLeft 1 (symbol "+") Somme
, infixLeft 1 (symbol "-") Difference
, infixLeft 2 (symbol "*") Produit
, infixLeft 2 (symbol "%") Reste
, infixLeft 2 (symbol "/") Quotient
, infixRight 4 (symbol "^") Exp
, postfix 6 (symbol "!") Factorielle
, postfix 6 (symbol "°") Degre
]
, spaces = Parser.spaces
}
expressionEntreParentheses : Pratt.Config ExpressionMathematique -> Parser ExpressionMathematique
expressionEntreParentheses config =
succeed identity
|. symbol "("
|= Pratt.subExpression 0 config
|. symbol ")"
polynome : Parser ExpressionMathematique
polynome =
succeed Poly
|. keyword "Poly"
|. spaces
|= sequence
{ start = "["
, separator = ","
, end = "]"
, spaces = spaces
, item = lazy (\_ -> expressionMathematique)
, trailing = Forbidden
}
|. spaces
|= variable
{ start = \_ -> True
, inner = \_ -> False
, reserved = Set.fromList []
}