parsing works with path expressions

This commit is contained in:
Macocian Adrian Radu
2022-05-15 01:51:49 +02:00
parent ee26710515
commit 47051dbbbd
16 changed files with 238 additions and 122 deletions

View File

@@ -12,7 +12,7 @@ import Text.Megaparsec.Char
-- |Parses a complete Rosetta expression into an Expression type
expressionParser :: Parser Expression
expressionParser =
expressionParser =
choice [ ifParser,
try functionCallParser,
eqParser]
@@ -46,7 +46,7 @@ ifParser =
case els of
Left _ -> return (IfSimple condition expr)
Right _ -> expressionParser >>= \expr2 -> return (IfElse condition expr expr2)
-- |Parses an expression between parentheses in Rosetta into an Expression
parens :: Parser a -> Parser a
parens = between (char '(') (char ')')
@@ -69,16 +69,7 @@ listParser =
variableParser :: Parser Expression
variableParser =
do
var <- camelNameParser
inner <- many innerVariableParser
return $ Variable (var ++ concatMap ("->" ++) inner)
-- |Parses an inner variable (a -> b) in Rosetta into an Expression
innerVariableParser :: Parser String
innerVariableParser =
do
_ <- lexeme $ string "->"
camelNameParser
Variable <$> camelNameParser
-- |Parses an integer in Rosetta into an Expression
integerParser :: Parser Expression
@@ -86,7 +77,7 @@ integerParser =
do
nr <- lexeme $ some digitChar
return $ Int nr
-- |Parses a real number in Rosetta into an Expression
decimalParser :: Parser Expression
decimalParser =
@@ -95,7 +86,7 @@ decimalParser =
_ <- char '.'
real <- lexeme $ many digitChar
return $ Real $ nr ++ "." ++ real
-- |Parses a boolean in Rosetta into an Expression
booleanParser :: Parser Expression
booleanParser =
@@ -105,7 +96,7 @@ booleanParser =
-- |Parses the empty statement in Rosetta into an Expression
emptyParser :: Parser Expression
emptyParser =
emptyParser =
do
_ <- lexeme $ string "empty"
return Empty
@@ -114,7 +105,7 @@ emptyParser =
terminalParser :: Parser Expression
terminalParser =
do
choice
choice
[ prefixParser,
parens expressionParser >>= \e -> return (Parens e),
listParser,
@@ -131,11 +122,11 @@ terminalParser =
-- |Parses an prefix function statement in Rosetta into an Expression
prefixParser :: Parser Expression
prefixParser =
prefixParser =
do
op <- lexeme $ choice $ fmap (try . string . Text.pack) prefixOperators
PrefixExp (Text.unpack op) <$> expressionParser
-- |List of prefix operators
prefixOperators :: [String]
prefixOperators = ["-", "not"]
@@ -166,44 +157,55 @@ sumParser =
-- |Parses a multiplication or division statement in Rosetta into an Expression
factorParser :: Parser Expression
factorParser =
do
factorParser =
do
p <- powerParser
op <- lexeme $ observing (char '*' <|> char '/')
case op of
Left _ -> return p
Right o -> factorParser >>= \ex -> return $ reverseExpression $ InfixExp [o] p ex
-- |Parses a boolean statement in Rosetta into an Expression
boolOpParser :: Parser Expression
boolOpParser =
do
p <- postfixParser
op <- lexeme $ observing (string "or" <|> string "and")
case op of
Left _ -> return p
Right o -> boolOpParser >>= \ex -> return $ InfixExp (Text.unpack o) p ex
-- |Parses a power statement in Rosetta into an Expression
powerParser :: Parser Expression
powerParser =
powerParser =
do
p <- boolOpParser
op <- lexeme $ observing $ char '^'
case op of
Left _ -> return p
Right _ -> powerParser >>= \ex -> return $ InfixExp "^" p ex
-- |Parses a boolean statement in Rosetta into an Expression
boolOpParser :: Parser Expression
boolOpParser =
do
p <- postfixParser
op <- lexeme $ observing (string "or" <|> string "and")
case op of
Left _ -> return p
Right o -> boolOpParser >>= \ex -> return $ InfixExp (Text.unpack o) p ex
-- |Parses a postfix function in Rosetta into an Expression
postfixParser :: Parser Expression
postfixParser =
postfixParser =
do
t <- terminalParser
t <- pathExpressionParser
op <- lexeme $ observing $ choice $ fmap (try . string . Text.pack) postfixFunctions
case op of
Left _ -> return t
Right o -> return $ PostfixExp (Text.unpack o) t
-- |Parses a path expression (a -> b) in Rosetta into an Expression
pathExpressionParser :: Parser Expression
pathExpressionParser =
do
var <- terminalParser
op <- lexeme $ observing $ string "->"
case op of
Left _ -> return var
Right _ -> pathExpressionParser >>= \ex -> return $ reverseExpression $ PathExpression var ex
-- |The list of existing postfix Rosetta functions
postfixFunctions :: [String]
postfixFunctions = ["exists", "is absent", "count", "only-element", "single exists", "multiple exists"]
@@ -217,6 +219,7 @@ reverseExpression :: Expression -> Expression
reverseExpression (InfixExp op t1 (InfixExp op2 t2 e))
| precedence op == precedence op2 = InfixExp op2 (reverseExpression (InfixExp op t1 t2)) e
| otherwise = InfixExp op t1 (InfixExp op2 t2 e)
reverseExpression (PathExpression e1 (PathExpression e2 e3)) = PathExpression (reverseExpression (PathExpression e1 e2)) e3
reverseExpression e = e

View File

@@ -20,15 +20,18 @@ functionParser =
fDescription <- optional descriptionParser
fInput <- inputAttributesParser
fOutput <- outputAttributeParser
MakeFunction (MakeFunctionSignature fName fDescription fInput fOutput) <$> assignmentParser
MakeFunction (MakeFunctionSignature fName fDescription fInput fOutput) <$> many assignmentParser
-- parseTest assignmentParser (Text.pack "assign-output observable -> exchangeRate -> from: from")
-- |Parses the output assignment statement from a function in Rosetta into an Expression
assignmentParser :: Parser Expression
assignmentParser :: Parser (Expression, Expression)
assignmentParser =
do
_ <- lexeme $ string "assign-output"
out <- expressionParser
_ <- lexeme $ char ':'
expressionParser
assignment <- expressionParser
return (out, assignment)
-- |Parses the input attributes from a function statement in Rosetta into a list of TypeAttributes
inputAttributesParser :: Parser [TypeAttribute]

View File

@@ -50,10 +50,9 @@ cardinalityParser = try parseBounded <|> try parseSemiBounded
conditionParser :: Parser Condition
conditionParser = do
_ <- lexeme $ string "condition"
name <- lexeme camelNameParser
_ <- lexeme $ char ':'
description <- optional descriptionParser
MakeCondition name description <$> expressionParser
_ <- lexeme $ char ':'
MakeCondition description <$> expressionParser
-- |Parses a bounded cardinality statement in Rosetta into a Cardinality
parseBounded :: Parser Cardinality