抱歉愚蠢的问题。
我有一些SQL模式,看起来像这样(例如):
create table test_table (
id integer not null,
title text,
primary key ("id")
);
create table test_table2 (
id integer not null,
subtitle text,
some_wierd_count integer not null,
primary key ("id")
);
从这个模式我只需要一些信息。我不关心主键,indeces,“not null”。只是表名,字段名称和类型。
我编写了以下丑陋的代码,但不起作用:http://code.sdfgh153.ru/gimme-models/src/1e5a17f2f8dbc225b0d26da405f5a1303f896ddb/src/GimmeModels/Schema/SQLSchema/Parser.hs?at=default
我认为这段代码应该填写以下类型:
data Schema = Schema { schemaTables :: [Table] } deriving (Show)
data Table = Table {
tableName :: String
, tableFields :: [Field]
} deriving (Show)
data Field = Field {
fieldName :: String
, fieldType :: String
} deriving (Show)
但是无法弄明白,如何正确解析create table表达式中的字段部分。我该如何检测现场结束声明?
答案 0 :(得分:1)
好的,用kqr的海带我终于意识到:我应该使用sepBy
组合子。我用语句声明解析表的最终代码:
tableParser :: P.Parser Table
tableParser = do
P.manyTill P.anyChar $ P.stringCI "create table"
P.skipWhile fieldGarbage
n <- P.takeWhile (not . fieldGarbage)
P.skipWhile fieldGarbage
P.char '('
fs <- fieldParser `P.sepBy` P.char ','
P.manyTill P.anyChar (P.char ';')
return $ Table (C.unpack n) fs
parseStr = do
P.skipWhile fieldGarbage
P.takeWhile (not . fieldGarbage)
fieldParser :: P.Parser Field
fieldParser = do
n <- parseStr
t <- parseStr
P.takeTill (\c -> c == ',' || c == ';')
return $ Field (C.unpack n) (C.unpack t)
谢谢大家的帮助。