refactored to add lexemes

This commit is contained in:
macocianradu
2021-10-16 18:22:36 +02:00
parent 4b49051b61
commit 51c625b74b
8 changed files with 76 additions and 212 deletions

View File

@@ -28,9 +28,7 @@ library
Model.Enum Model.Enum
Model.Function Model.Function
Model.Type Model.Type
Parser.Expression
Parser.Enum Parser.Enum
Parser.Expr
Parser.Expression Parser.Expression
Parser.Function Parser.Function
Parser.General Parser.General

View File

@@ -16,45 +16,24 @@ data Condition =
MakeCondition { MakeCondition {
conditionDescription :: Maybe String, conditionDescription :: Maybe String,
conditionStatement :: Expression conditionStatement :: Expression
-- conditionStatement :: String
} }
| MakePostCondition { | MakePostCondition {
conditionDescription :: Maybe String, conditionDescription :: Maybe String,
conditionStatement :: Expression conditionStatement :: Expression
-- conditionStatement :: String
} }
deriving (Show) deriving (Show)
data Expression = --String deriving (Show) data Expression = Variable String
Variable String | Int String
| Literal String | Real String
| ExpressionList [Expression] | Boolean String
| InnerType Expression Expression | Empty
| Parens Expression
| Or Expression Expression | List [Expression]
| And Expression Expression | Function String [Expression]
| Not Expression | PrefixExp String Expression
| PostfixExp String Expression
| Exists Expression | InfixExp String Expression Expression
| IsAbsent Expression
| Contains Expression Expression
| Disjoint Expression Expression
| Count Expression
| OnlyExists Expression
| OnlyElement Expression
| Equals Expression Expression
| Different Expression Expression
| GreaterStrict Expression Expression
| SmallerStrict Expression Expression
| GreaterOrEqual Expression Expression
| SmallerOrEqual Expression Expression
| Sum Expression Expression
| Subtract Expression Expression
| Product Expression Expression
| Division Expression Expression
| IfSimple Expression Expression | IfSimple Expression Expression
| IfElse Expression Expression Expression | IfElse Expression Expression Expression
deriving (Show) deriving (Show)

View File

@@ -14,41 +14,30 @@ enumParser =
eName <- enumNameParser eName <- enumNameParser
eDescription <- descriptionParser eDescription <- descriptionParser
values <- many enumValueParser values <- many enumValueParser
_ <- spaceConsumer
return (MakeEnum eName (Just eDescription) values) return (MakeEnum eName (Just eDescription) values)
--parseTest enumValueParser "D displayName \"day\" <\"Day\">" --parseTest enumValueParser "D displayName \"day\" <\"Day\">"
enumValueParser :: Parser EnumValue enumValueParser :: Parser EnumValue
enumValueParser = enumValueParser =
do do
vName <- enumValueNameParser vName <- nameParser
dName <- enumValueDisplayNameParser dName <- enumValueDisplayNameParser
vDescription <- descriptionParser vDescription <- descriptionParser
return (MakeEnumValue vName (Just vDescription) (Just dName)) return (MakeEnumValue vName (Just vDescription) (Just dName))
enumValueNameParser :: Parser String
enumValueNameParser =
do
name <- nameParser
_ <- spaceConsumer
return name
enumValueDisplayNameParser :: Parser String enumValueDisplayNameParser :: Parser String
enumValueDisplayNameParser = enumValueDisplayNameParser =
do do
_ <- string "displayName \"" _ <- lexeme $ string "displayName"
name <- anySingle `manyTill` char '"' _ <- char '"'
_ <- spaceConsumer lexeme $ anySingle `manyTill` char '"'
return name
enumNameParser :: Parser String enumNameParser :: Parser String
enumNameParser = enumNameParser =
do do
_ <- string "enum" _ <- lexeme $ string "enum"
_ <- spaceConsumer
name <- nameParser name <- nameParser
_ <- char ':' _ <- lexeme $ char ':'
_ <- spaceConsumer
return name return name
periodEnum :: EnumType periodEnum :: EnumType

View File

@@ -1,3 +0,0 @@
module Parser.Expr where
import Parser.General

View File

@@ -3,47 +3,29 @@
module Parser.Expression where module Parser.Expression where
import Parser.General import Parser.General
import Model.Function
import qualified Data.Text as Text import qualified Data.Text as Text
import Text.Megaparsec import Text.Megaparsec
import Text.Megaparsec.Char import Text.Megaparsec.Char
data Expression = Variable String
| Int String
| Real String
| Boolean String
| Empty
| Parens Expression
| List [Expression]
| Function String [Expression]
| PrefixExp String Expression
| PostfixExp String Expression
| InfixExp String Expression Expression
| IfSimple Expression Expression
| IfElse Expression Expression Expression
deriving (Show)
expressionParser :: Parser Expression expressionParser :: Parser Expression
expressionParser = expressionParser =
choice [ ifParser, choice [ ifParser,
try functionParser, try functionCallParser,
eqParser] eqParser]
-------------------------------------------- --------------------------------------------
-- Command Structures ---------------------- -- Command Structures ----------------------
-------------------------------------------- --------------------------------------------
functionParser :: Parser Expression functionCallParser :: Parser Expression
functionParser = functionCallParser =
do do
f <- pascalNameParser f <- lexeme pascalNameParser
_ <- spaceConsumer _ <- lexeme $ char '('
_ <- char '(' ats <- many $ try (expressionParser >>= \ats -> lexeme $ char ',' >> return ats)
ats <- many $ try (expressionParser >>= \ats -> spaceConsumer >> char ',' >> spaceConsumer >> return ats) lat <- optional $ lexeme expressionParser
lat <- optional expressionParser _ <- lexeme $ char ')'
_ <- spaceConsumer
_ <- char ')'
_ <- spaceConsumer
case lat of case lat of
Nothing -> return $ Function f [] Nothing -> return $ Function f []
Just at -> return $ Function f (ats ++ [at]) Just at -> return $ Function f (ats ++ [at])
@@ -51,16 +33,11 @@ functionParser =
ifParser :: Parser Expression ifParser :: Parser Expression
ifParser = ifParser =
do do
_ <- string "if" _ <- lexeme $ string "if"
_ <- spaceConsumer condition <- lexeme $ between (char '(') (char ')') expressionParser <|> expressionParser
condition <- between (char '(') (char ')') expressionParser <|> expressionParser _ <- lexeme $ string "then"
_ <- spaceConsumer
_ <- string "then"
_ <- spaceConsumer
expr <- expressionParser expr <- expressionParser
_ <- spaceConsumer els <- observing $ lexeme $ string "else"
els <- observing $ string "else"
_ <- spaceConsumer
case els of case els of
Left _ -> return (IfSimple condition expr) Left _ -> return (IfSimple condition expr)
Right _ -> expressionParser >>= \expr2 -> return (IfElse condition expr expr2) Right _ -> expressionParser >>= \expr2 -> return (IfElse condition expr expr2)
@@ -75,38 +52,29 @@ parens = between (char '(') (char ')')
listParser :: Parser Expression listParser :: Parser Expression
listParser = listParser =
do do
_ <- char '[' _ <- lexeme $ char '['
_ <- spaceConsumer expressions <- many $ try (expressionParser >>= \ex -> lexeme $ char ',' >> return ex)
expressions <- many $ try (expressionParser >>= \ex -> spaceConsumer >> char ',' >> spaceConsumer >> return ex)
_ <- spaceConsumer
lastExpr <- try expressionParser lastExpr <- try expressionParser
_ <- spaceConsumer _ <- lexeme $ char ']'
_ <- char ']'
_ <- spaceConsumer
return $ List (expressions ++ [lastExpr]) return $ List (expressions ++ [lastExpr])
variableParser :: Parser Expression variableParser :: Parser Expression
variableParser = variableParser =
do do
var <- camelNameParser var <- camelNameParser
_ <- spaceConsumer
inner <- many innerVariableParser inner <- many innerVariableParser
return $ Variable (var ++ concatMap ("->" ++) inner) return $ Variable (var ++ concatMap ("->" ++) inner)
innerVariableParser :: Parser String innerVariableParser :: Parser String
innerVariableParser = innerVariableParser =
do do
_ <- string "->" _ <- lexeme $ string "->"
_ <- spaceConsumer camelNameParser
var <- camelNameParser
_ <- spaceConsumer
return var
integerParser :: Parser Expression integerParser :: Parser Expression
integerParser = integerParser =
do do
nr <- some digitChar nr <- lexeme $ some digitChar
_ <- spaceConsumer
return $ Int $ show nr return $ Int $ show nr
decimalParser :: Parser Expression decimalParser :: Parser Expression
@@ -114,22 +82,19 @@ decimalParser =
do do
nr <- some digitChar nr <- some digitChar
_ <- char '.' _ <- char '.'
real <- many digitChar real <- lexeme $ many digitChar
_ <- spaceConsumer
return $ Real $ show nr ++ "." ++ real return $ Real $ show nr ++ "." ++ real
booleanParser :: Parser Expression booleanParser :: Parser Expression
booleanParser = booleanParser =
do do
bol <- string "True" <|> string "False" bol <- lexeme (string "True" <|> string "False")
_ <- spaceConsumer
return $ Boolean $ Text.unpack bol return $ Boolean $ Text.unpack bol
emptyParser :: Parser Expression emptyParser :: Parser Expression
emptyParser = emptyParser =
do do
_ <- string "empty" _ <- lexeme $ string "empty"
_ <- spaceConsumer
return Empty return Empty
terminalParser :: Parser Expression terminalParser :: Parser Expression
@@ -153,19 +118,14 @@ terminalParser =
prefixParser :: Parser Expression prefixParser :: Parser Expression
prefixParser = prefixParser =
do do
op <- choice $ fmap (try . string . Text.pack) prefixOperators op <- lexeme $ choice $ fmap (try . string . Text.pack) prefixOperators
_ <- spaceConsumer PrefixExp (Text.unpack op) <$> expressionParser
ex <- expressionParser
_ <- spaceConsumer
return $ PrefixExp (Text.unpack op) ex
eqParser :: Parser Expression eqParser :: Parser Expression
eqParser = eqParser =
do do
s <- sumParser s <- sumParser
_ <- spaceConsumer op <- lexeme $ observing (string "<=" <|> string "=" <|> string "<" <|> string ">" <|> string ">=")
op <- observing (string "<=" <|> string "=" <|> string "<" <|> string ">" <|> string ">=")
_ <- spaceConsumer
case op of case op of
Left _ -> return s Left _ -> return s
Right o -> eqParser >>= \ex -> return $ InfixExp (Text.unpack o) s ex Right o -> eqParser >>= \ex -> return $ InfixExp (Text.unpack o) s ex
@@ -174,9 +134,7 @@ sumParser :: Parser Expression
sumParser = sumParser =
do do
f <- factorParser f <- factorParser
_ <- spaceConsumer op <- lexeme $ observing (char '+' <|> char '-')
op <- observing (char '+' <|> char '-')
_ <- spaceConsumer
case op of case op of
Left _ -> return f Left _ -> return f
Right o -> sumParser >>= \ex -> return $ reverseExpression $ InfixExp [o] f ex Right o -> sumParser >>= \ex -> return $ reverseExpression $ InfixExp [o] f ex
@@ -185,9 +143,7 @@ factorParser :: Parser Expression
factorParser = factorParser =
do do
p <- powerParser p <- powerParser
_ <- spaceConsumer op <- lexeme $ observing (char '*' <|> char '/')
op <- observing (char '*' <|> char '/')
_ <- spaceConsumer
case op of case op of
Left _ -> return p Left _ -> return p
Right o -> factorParser >>= \ex -> return $ reverseExpression $ InfixExp [o] p ex Right o -> factorParser >>= \ex -> return $ reverseExpression $ InfixExp [o] p ex
@@ -196,9 +152,7 @@ powerParser :: Parser Expression
powerParser = powerParser =
do do
p <- postfixParser p <- postfixParser
_ <- spaceConsumer op <- lexeme $ observing $ char '^'
op <- observing $ char '^'
_ <- spaceConsumer
case op of case op of
Left _ -> return p Left _ -> return p
Right _ -> powerParser >>= \ex -> return $ InfixExp "^" p ex Right _ -> powerParser >>= \ex -> return $ InfixExp "^" p ex
@@ -207,9 +161,7 @@ postfixParser :: Parser Expression
postfixParser = postfixParser =
do do
t <- terminalParser t <- terminalParser
_ <- spaceConsumer op <- lexeme $ observing (string "exists" <|> string "is absent" <|> string "count" <|> string "only-element")
op <- observing (string "exists" <|> string "is absent" <|> string "count" <|> string "only-element")
_ <- spaceConsumer
case op of case op of
Left _ -> return t Left _ -> return t
Right o -> return $ PostfixExp (Text.unpack o) t Right o -> return $ PostfixExp (Text.unpack o) t
@@ -243,9 +195,9 @@ testArith5 = parseTest expressionParser "a + b - c * d ^ e"
testArith6 = parseTest expressionParser "1 - 2 - 3 - 4 - 5 - 6" testArith6 = parseTest expressionParser "1 - 2 - 3 - 4 - 5 - 6"
testList = parseTest expressionParser "[1, 2, 3]" testList = parseTest expressionParser "[1, 2, 3]"
testList2 = parseTest expressionParser "[1, 2 + 3, e]" testList2 = parseTest expressionParser "[1, 2 + 3, e]"
testFun = parseTest functionParser "Function()" testFun = parseTest functionCallParser "Function()"
testFun2 = parseTest functionParser "Function(e)" testFun2 = parseTest functionCallParser "Function(e)"
testFun3 = parseTest functionParser "Function(3, 3+2,e)" testFun3 = parseTest functionCallParser "Function(3, 3+2,e)"
testIf = parseTest expressionParser "if (Function(2 + 3, e)) then a + b - c * d ^ e -> x else not a exists" testIf = parseTest expressionParser "if (Function(2 + 3, e)) then a + b - c * d ^ e -> x else not a exists"
testEverything = parseTest expressionParser "if [1, Function(3)] then 1 - 2 - 3 * a -> b ^ c" testEverything = parseTest expressionParser "if [1, Function(3)] then 1 - 2 - 3 * a -> b ^ c"
testFail = parseTest expressionParser "if[1,as]thenxandoelseaora" testFail = parseTest expressionParser "if[1,as]thenxandoelseaora"

View File

@@ -13,58 +13,42 @@ import Parser.General
functionParser :: Parser Function functionParser :: Parser Function
functionParser = functionParser =
do do
_ <- string "func" _ <- lexeme $ string "func"
_ <- spaceConsumer
fName <- pascalNameParser fName <- pascalNameParser
_ <- char ':' _ <- lexeme $ char ':'
_ <- spaceConsumer
fDescription <- descriptionParser fDescription <- descriptionParser
fInput <- inputAttributesParser fInput <- inputAttributesParser
fOutput <- outputAttributeParser fOutput <- outputAttributeParser
fAssignments <- many assignmentParser fAssignments <- many assignmentParser
_ <- spaceConsumer
return (MakeFunction fName (Just fDescription) fInput fOutput fAssignments) return (MakeFunction fName (Just fDescription) fInput fOutput fAssignments)
assignmentParser :: Parser (Expression, Expression) assignmentParser :: Parser (Expression, Expression)
assignmentParser = assignmentParser =
do do
_ <- string "assign-output" _ <- lexeme $ string "assign-output"
_ <- spaceConsumer
name <- expressionParser name <- expressionParser
_ <- spaceConsumer _ <- lexeme $ char ':'
_ <- char ':'
_ <- spaceConsumer
expr <- expressionParser expr <- expressionParser
_ <- spaceConsumer
return (name, expr) return (name, expr)
inputAttributesParser :: Parser [TypeAttribute] inputAttributesParser :: Parser [TypeAttribute]
inputAttributesParser = inputAttributesParser =
do do
_ <- string "inputs:" _ <- lexeme $ string "inputs:"
_ <- spaceConsumer many $ try attributeParser
inputs <- many $ try attributeParser
_ <- spaceConsumer
return inputs
outputAttributeParser :: Parser TypeAttribute outputAttributeParser :: Parser TypeAttribute
outputAttributeParser = outputAttributeParser =
do do
_ <- string "output:" _ <- lexeme $ string "output:"
_ <- spaceConsumer attributeParser
outputs <- attributeParser
_ <- spaceConsumer
return outputs
attributeParser :: Parser TypeAttribute attributeParser :: Parser TypeAttribute
attributeParser = attributeParser =
do do
nam <- camelNameParser nam <- camelNameParser
_ <- spaceConsumer
typ <- pascalNameParser <|> camelNameParser typ <- pascalNameParser <|> camelNameParser
_ <- spaceConsumer
crd <- cardinalityParser crd <- cardinalityParser
_ <- spaceConsumer
desc <- optional descriptionParser desc <- optional descriptionParser
return $ MakeTypeAttribute nam typ crd desc return $ MakeTypeAttribute nam typ crd desc

View File

@@ -13,41 +13,33 @@ type Parser = Parsec Void Text
spaceConsumer :: Parser () spaceConsumer :: Parser ()
spaceConsumer = L.space space1 (L.skipLineComment "//") (L.skipBlockComment "/*" "*/") spaceConsumer = L.space space1 (L.skipLineComment "//") (L.skipBlockComment "/*" "*/")
symbol :: Text -> Parser Text lexeme :: Parser a -> Parser a
symbol = L.symbol spaceConsumer lexeme = L.lexeme spaceConsumer
descriptionParser :: Parser String descriptionParser :: Parser String
descriptionParser = descriptionParser =
do do
_ <- string "<\"" _ <- string "<\""
description <- anySingle `manyTill` string "\">" lexeme $ anySingle `manyTill` string "\">"
_ <- spaceConsumer
return description
pascalNameParser :: Parser String pascalNameParser :: Parser String
pascalNameParser = pascalNameParser =
do do
first <- upperChar first <- upperChar
rest <- many (letterChar <|> digitChar <|> char '_') rest <- lexeme $ many (letterChar <|> digitChar <|> char '_')
_ <- spaceConsumer
return (first : rest) return (first : rest)
camelNameParser :: Parser String camelNameParser :: Parser String
camelNameParser = camelNameParser =
do do
first <- lowerChar first <- lowerChar
rest <- many (letterChar <|> digitChar <|> char '_') rest <- lexeme $ many (letterChar <|> digitChar <|> char '_')
_ <- spaceConsumer
return (first : rest) return (first : rest)
nameParser :: Parser String nameParser :: Parser String
nameParser = nameParser =
do do
first <- letterChar <|> char '_' first <- letterChar <|> char '_'
rest <- many (letterChar <|> digitChar <|> char '_') rest <- lexeme $ many (letterChar <|> digitChar <|> char '_')
_ <- spaceConsumer return (first:rest)
return (first:rest)
untilParser :: String -> Parser String
untilParser x = try (anySingle `manyTill` string (pack x))

View File

@@ -13,83 +13,56 @@ typeParser =
do do
tName <- typeNameParser tName <- typeNameParser
tDescription <- descriptionParser tDescription <- descriptionParser
tAttributes <- many $ try typeAttributeParserWDesc <|> try typeAttributeParser tAttributes <- many $ try typeAttributeParser
_ <- spaceConsumer
return (MakeType tName (Just tDescription) tAttributes) return (MakeType tName (Just tDescription) tAttributes)
typeAttributeParserWDesc :: Parser TypeAttribute
typeAttributeParserWDesc =
do
(MakeTypeAttribute aName aType card Nothing) <- typeAttributeParser
descriptionParser >>= \aDescription -> return (MakeTypeAttribute aName aType card (Just aDescription))
typeAttributeParser :: Parser TypeAttribute typeAttributeParser :: Parser TypeAttribute
typeAttributeParser = typeAttributeParser =
do do
aName <- attributeNameParser aName <- camelNameParser
aType <- nameParser aType <- nameParser
_ <- spaceConsumer
card <- cardinalityParser card <- cardinalityParser
_ <- spaceConsumer desc <- optional descriptionParser
return (MakeTypeAttribute aName aType card Nothing) return (MakeTypeAttribute aName aType card desc)
cardinalityParser :: Parser Cardinality cardinalityParser :: Parser Cardinality
cardinalityParser = cardinalityParser =
do do
card <- parseExactlyOne <|> parseOneOrMore <|> parseZeroOrMore <|> parseZeroOrOne parseExactlyOne <|> parseOneOrMore <|> parseZeroOrMore <|> parseZeroOrOne
_ <- spaceConsumer
return card
parseOneOrMore :: Parser Cardinality parseOneOrMore :: Parser Cardinality
parseOneOrMore = parseOneOrMore =
do do
_ <- string "(1..*)" _ <- lexeme $ string "(1..*)"
return OneOrMore return OneOrMore
parseExactlyOne :: Parser Cardinality parseExactlyOne :: Parser Cardinality
parseExactlyOne = parseExactlyOne =
do do
_ <- string "(1..1)" _ <- lexeme $ string "(1..1)"
return ExactlyOne return ExactlyOne
parseZeroOrMore :: Parser Cardinality parseZeroOrMore :: Parser Cardinality
parseZeroOrMore = parseZeroOrMore =
do do
_ <- string "(0..*)" _ <- lexeme $ string "(0..*)"
return ZeroOrMore return ZeroOrMore
parseZeroOrOne :: Parser Cardinality parseZeroOrOne :: Parser Cardinality
parseZeroOrOne = parseZeroOrOne =
do do
_ <- string "(0..1)" _ <- lexeme $ string "(0..1)"
return ZeroOrOne return ZeroOrOne
attributeNameParser :: Parser String
attributeNameParser =
do
name <- camelNameParser
_ <- spaceConsumer
return name
enumValueDisplayNameParser :: Parser String
enumValueDisplayNameParser =
do
_ <- string "displayName \""
name <- anySingle `manyTill` char '"'
_ <- spaceConsumer
return name
typeNameParser :: Parser String typeNameParser :: Parser String
typeNameParser = typeNameParser =
do do
_ <- string "type" _ <- lexeme $ string "type"
_ <- spaceConsumer
name <- pascalNameParser name <- pascalNameParser
_ <- char ':' _ <- lexeme $ char ':'
_ <- spaceConsumer
return name return name
periodType :: Type periodType :: Type