<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body text="#000000" bgcolor="#c0c0c0">
Hi all - <br>
<br>
I'm poking around with Parsec and looking at getting this "toy SQL"
parser up and running. <br>
So, I'm keen to get feedback on whether I'm on the right track (or
off on a siding to nowhere..... ;) ) <br>
This is my first Parsec grammar, so I hope you'll be gentle......
:) <br>
<br>
( Note - I've put the whereStmt in parens as I want that to be an
optional statement. I'm not sure how <br>
to denote that in Parsec. ) <br>
<br>
Many thanks in advance - <br>
<br>
** Start of code ** <br>
-- toysql.hs <br>
-- This code is aimed at parsing phrases like the <br>
-- following - <br>
-- select * from mytable where city = "Sydney"; <br>
-- select foo, bar from mytable where var1 > 10; <br>
-- select baz from mytable; <br>
-- This code is released to the public domain. <br>
-- "Share and enjoy....." ;) <br>
<br>
module Main where <br>
<br>
import Text.ParserCombinators.Parsec<br>
<br>
sqlStmt = do{ createStmt<br>
; selectStmt <br>
; fromStmt<br>
; (whereStmt) <br>
; semicolon <br>
} <br>
<br>
createStmt = do{ CREATE <br>
; tablename <br>
; AS<br>
} <br>
<br>
tablename = identifier <br>
<br>
<br>
selectStmt = do{ SELECT <br>
; varStmt <br>
} <br>
<br>
varStmt = star <|> singlevar <|> varlist <br>
star = '*' <br>
singlevar = identifier <br>
varlist = sepBy singlevar (char ',') <br>
<br>
fromStmt = do{ FROM <br>
; tableStmt <br>
} <br>
<br>
tableStmt = singleTablestmt <|> multiTablestmt <br>
singleTablestmt = identifier <br>
multiTablestmt = sepBy identifier (char ',') <br>
<br>
whereStmt = do{ WHERE <br>
; condStmt <br>
} <br>
<br>
condStmt = multiCondstmt <|> singleCondstmt <br>
singleCondstmt = singleCondstmtnoparens <|>
singleCondstmtwithparens <br>
<br>
singleCondstmtnoparens = do{ <br>
; singlevar <br>
; OP <br>
; value <br>
} <br>
<br>
singleCondstmtwithparens = do( <br>
; char '(' <br>
; singleCondstmtnoparens <br>
; char ')' <br>
<br>
multiCondstmt = sepBy singleCondstmt ( AND <|> OR ) <br>
<br>
OP = ( '=' <|> '<' <|> '>' <|> "<="
<|> ">=" <|> "!=" ) <br>
semicolon = char ';'<br>
<br>
parseSQL :: String -> Either ParseError [[String]]<br>
parseSQL input = parse sqlFile "(unknown)" input<br>
<br>
** end of code ** <br>
<br>
<br>
</body>
</html>