@@ -17,7 +17,7 @@ import System.Console.Readline
17lexer :: Token.TokenParser ()
17lexer :: Token.TokenParser ()
18lexer = Token.makeTokenParser tutD
18lexer = Token.makeTokenParser tutD
19 where tutD = emptyDef {
19 where tutD = emptyDef {
20− Token.reservedOpNames = ["join", "where", "union"],
20+ Token.reservedOpNames = ["join", "where", "union", "group", "ungroup"],
21 Token.reservedNames = [],
21 Token.reservedNames = [],
22 Token.identStart = letter,
22 Token.identStart = letter,
23 Token.identLetter = alphaNum}
23 Token.identLetter = alphaNum}
@@ -32,7 +32,7 @@ semi = Token.semi lexer
33--used in projection
33--used in projection
34attributeList :: Parser [AttributeName]
34attributeList :: Parser [AttributeName]
35−attributeList = braces (sepBy identifier comma)
35+attributeList = sepBy identifier comma
37makeRelation :: Parser RelationalExpr
37makeRelation :: Parser RelationalExpr
38makeRelation = do
38makeRelation = do
@@ -72,7 +72,7 @@ relTerm = parens relExpr
72 <|> relVarP
72 <|> relVarP
74projectOp = do
74projectOp = do
75− attrs <- attributeList
75+ attrs <- braces attributeList
76 return $ Project (S.fromList attrs)
76 return $ Project (S.fromList attrs)
78assignP = do
78assignP = do
@@ -91,10 +91,31 @@ renameP = do
91 reservedOp "rename"
91 reservedOp "rename"
92 (oldAttr, newAttr) <- braces renameClause
92 (oldAttr, newAttr) <- braces renameClause
93 return $ Rename oldAttr newAttr
93 return $ Rename oldAttr newAttr
96+ attrs <- braces attributeList
98+ newAttrName <- identifier
99+ return $ (attrs, newAttrName)
101+groupP :: Parser (RelationalExpr -> RelationalExpr)
104+ (groupAttrList, groupAttrName) <- parens groupClause
105+ return $ Group (S.fromList groupAttrList) groupAttrName
107+--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.
108+ungroupP :: Parser (RelationalExpr -> RelationalExpr)
110+ reservedOp "ungroup"
111+ rvaAttrName <- identifier
112+ return $ Ungroup rvaAttrName
95relOperators = [
115relOperators = [
96 [Postfix projectOp],
116 [Postfix projectOp],
97 [Postfix renameP],
117 [Postfix renameP],
98 [Infix (reservedOp "join" >> return Join) AssocLeft],
119 [Infix (reservedOp "join" >> return Join) AssocLeft],
99 [Infix (reservedOp "union" >> return Union) AssocLeft],
120 [Infix (reservedOp "union" >> return Union) AssocLeft],
100 [Prefix (try assignP)]
121 [Prefix (try assignP)]