将字符串解析为AST

时间:2016-10-07 09:30:50

标签: parsing haskell grammar abstract-syntax-tree

试图将字符串解析为抽象语法树

这是我在BNF中使用的语法

<Block> ::= <Expr>;
<Expr> ::= <Number> | <App>
<App> ::= (<Expr>, <Expr>) <Func>
<Func> ::= + | - | * | \
<Number> ::= <Digit> | <Digit><Number>
<Digit> ::= 0 | 1 | .... | 9

我必须使用它:

data Ast = Number Integer | Func String | App Ast [Ast] | Block [Ast]

我写了一个tokenize方法(可能没有完全完成,但给出了正确的想法)

tokenize :: String -> [String]
tokenize [] = []
tokenize xs @ (x : xs')
    | x `elem` t = [x] : tokenize xs'
    | isDigit x = [y | y <- takeWhile isDigit xs] : (tokenize (dropWhile isDigit xs))
    | otherwise = tokenize xs'
        where t = ['+', '-', '*', '/', '(', ')', ';']

我坚持使用parseApp函数。对我来说,如何使用模式匹配并不是很明显,我也没有看到任何其他方法(使用我非常有限的haskell经验)

parse :: String -> Ast
parse xs = parseBlock (tokenize xs)

parseBlock :: [String] -> (Ast, [String]) 
parseBlock xss = let (a, b) = parseExpr (init xss) in (Block [a], b)

parseExpr :: [String] -> (Ast, [String]) 
parseExpr xss @ (xs : xss')
    | all isDigit xs = (Number (read xs :: Integer), xss')
    | otherwise = parseApp xss

parseApp :: [String] -> (Ast, [String])
parseApp xss = -- ...

如果输入字符串是

"((10, 2)- , (0, 2)-)+;"

它应该标记为

["(", "(", "10", ",", "2", ")", "-", ",", "(", "0", ",", "2", ")", "-", ")", "+", ";"]

那将成为

(Block [ App (Name "+") [App (Name "-") [Number 10, Number 2], App (Name "-") [Number 0, Number 2]]], []) 

这是一项任务,所以我不能改变类型等等。我应该假设给定的输入具有正确的语法。我在这里读过类似的线索,但答案似乎假设了更高层次的理解

0 个答案:

没有答案