1module TutorialDInterpreter where
7import Text.Parsec.String
9import Text.Parsec.Language
10import qualified Text.Parsec.Token as Token
11import qualified Data.Set as S
12import qualified Data.HashSet as HS
13import qualified Data.Map as M
14import Control.Applicative (liftA)
15import Control.Monad.State
16import System.Console.Readline
18lexer :: Token.TokenParser ()
19lexer = Token.makeTokenParser tutD
20 where tutD = emptyDef {
21 Token.reservedOpNames = ["join", "where", "union", "group", "ungroup"],
22 Token.reservedNames = [],
23 Token.identStart = letter,
24 Token.identLetter = alphaNum}
26parens = Token.parens lexer
27reservedOp = Token.reservedOp lexer
28reserved = Token.reserved lexer
29braces = Token.braces lexer
30identifier = Token.identifier lexer
31comma = Token.comma lexer
32semi = Token.semi lexer
35attributeList :: Parser [AttributeName]
36attributeList = sepBy identifier comma
38makeRelation :: Parser RelationalExpr
41 attrs <- makeAttributes
42 return $ MakeStaticRelation attrs HS.empty
44--used in relation creation
45makeAttributes :: Parser Attributes
47 attrList <- braces (sepBy attributeAndType comma)
48 return $ M.fromList $ map toAttributeAssocList attrList
50 toAttributeAssocList attr@(Attribute attrName _) = (attrName, attr)
52attributeAndType :: Parser Attribute
54 attrName <- identifier
55 attrTypeName <- identifier
56 --convert type name into type
57 case tutDTypeToAtomType attrTypeName of
58 Just t -> return $ Attribute attrName t
59 Nothing -> fail (attrTypeName ++ " is not a valid type name.")
61--convert Tutorial D type to AtomType
62tutDTypeToAtomType :: String -> Maybe AtomType
63tutDTypeToAtomType tutDType = case tutDType of
64 "char" -> Just StringAtomType
65 "int" -> Just IntAtomType
68relVarP :: Parser RelationalExpr
69relVarP = liftA RelationVariable identifier
71relTerm = parens relExpr
76 attrs <- braces attributeList
77 return $ Project (S.fromList attrs)
80 relVarName <- identifier
82 return $ Assign relVarName
88 return $ (oldAttr, newAttr)
90renameP :: Parser (RelationalExpr -> RelationalExpr)
93 (oldAttr, newAttr) <- braces renameClause
94 return $ Rename oldAttr newAttr
97 attrs <- braces attributeList
99 newAttrName <- identifier
100 return $ (attrs, newAttrName)
102groupP :: Parser (RelationalExpr -> RelationalExpr)
105 (groupAttrList, groupAttrName) <- parens groupClause
106 return $ Group (S.fromList groupAttrList) groupAttrName
108--in "Time and Relational Theory" (2014), Date's Tutorial D grammar for ungroup takes one attribute, while in previous books, it take multiple arguments. Let us assume that nested ungroups are the same as multiple attributes.
109ungroupP :: Parser (RelationalExpr -> RelationalExpr)
112 rvaAttrName <- identifier
113 return $ Ungroup rvaAttrName
120 [Infix (reservedOp "join" >> return Join) AssocLeft],
121 [Infix (reservedOp "union" >> return Union) AssocLeft],
122 [Prefix (try assignP)]
125relExpr :: Parser RelationalExpr
126relExpr = buildExpressionParser relOperators relTerm
128multipleRelExpr :: Parser RelationalExpr
130 exprs <- sepBy1 relExpr semi
131 return $ MultipleExpr exprs
133parseString :: String -> Either RelationalError RelationalExpr
134parseString str = case parse multipleRelExpr "" str of
135 Left err -> Left $ ParseError (show err)
138example1 = "relA {a,b, c}"
139example2 = "relA join relB"
140example3 = "relA join relB {x,y,z}"
141example4 = "(relA) {x,y,z}"
142example5 = "relA union relB"
143example6 = "rv1 := true"
144example7 = "rv1 := relA union relB"
145example8 = "relA := true; relB := false"
146example9 = "relA := relation { SNO CHAR }"
148interpret :: RelVarContext -> String -> (Either RelationalError Relation, RelVarContext)
149interpret context tutdstring = case parseString tutdstring of
150 Left err -> (Left err, context)
151 Right parsed -> runState (eval parsed) context
153reprLoop :: RelVarContext -> IO ()
155 maybeLine <- readline "TutorialD: "
160 let (value, contextup) = interpret context line
163 putStrLn $ showRelation rel
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list