使用attoparsec解析逗号分隔的字符串

时间:2013-11-20 13:05:16

标签: parsing haskell attoparsec

抱歉愚蠢的问题。

我有一些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表达式中的字段部分。我该如何检测现场结束​​声明?

1 个答案:

答案 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)

谢谢大家的帮助。

相关问题