I've written a piece of tasks from the first chapter of SICP in haskell as the warm-up, read the sixth chapter of the first book of _darkus_
And by motifs I've gotten the following parser of pl/sql packages specifications:
terminal = (spaces . utoken)
where utoken t s | lower t == lower (take n s) = [(lower (drop n s),t)]
| otherwise = []
where n = length t
lower = map toLower
-- Разрешенные идентификаторы
ident = spaces ((satisfy isAlpha) <:*> zeroOrMore leastChars) <@ (map toLower)
where leastChars = choise [satisfy isAlpha,
satisfy isDigit,
symbol '.',
symbol '_']
comment = single_line_comment <|> multi_line_comment
where single_line_comment = pack (token "--")
(zeroOrMore (satisfy (\_->True)))
(zeroOrMore (symbol '\n'))
multi_line_comment = reverse . p
where p = pack (token "/*") (zeroOrMore (satisfy (\_->True))) (token "*/")
-- Базовые типы
pls_type = choise [terminal "integer",
terminal "varchar2",
terminal "number",
terminal "date",
field_type]
where field_type = ident <* spaces(symbol '%') <*> terminal "type"
-- Разделители
sep_semicolon = spaces (symbol ';')
sep_comma = spaces (symbol ',')
-- Общие части выражений
def_var = ident <*> ((param_type) <|> succeed "in") <*> spaces (pls_type)
where param_type = choise [terminal "in",
terminal "out",
(terminal "in" <*> terminal "out") <@ (\_ -> "in out")]
def_params = spaces ((parens var_list) <|> succeed [])
where var_list = (listOf def_var sep_comma) <|> succeed []
def_fun = ident <*> def_params
-- Спецификации
spec_procedure = terminal "procedure" *> def_fun <*> (succeed "None") <* sep_semicolon
spec_function = terminal "function" *> def_fun <*> terminal "return"
*> ident <* sep_semicolon
spec_declaration = spec_procedure <|> spec_function
spec_create_package = cr_or_repl <*> (terminal "package") *> ident <*> terminal "as"
*> zeroOrMore spec_declaration
<* terminal "end" <* sep_semicolon <* terminal "/"
where cr_or_repl = terminal "create" <:*> option (terminal "or" *> terminal"replace")
Evidently, parser in python intends to the same approach.
Now I have to look into the system of haskell types and classes to have a possibility of digestible using the parser results.
No comments:
Post a Comment