1

对不起愚蠢的问题。

我有某种 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")
);

从这个模式中,我只需要一些信息。我不关心主键、索引、“非空”。只是表名、字段名和类型。

我写了以下丑陋的代码,但不起作用: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)

但无法弄清楚,如何正确解析创建表表达式中的字段部分。我应该如何检测字段声明的结束?

4

1 回答 1

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)

谢谢大家的帮助。

于 2013-11-21T04:08:49.873 回答