Cha*_*ion 7 language-agnostic parsing functional-programming state-machine data-structures
给定LL(1)语法什么是以功能纯粹的方式生成不可变具体语法树的适当数据结构或算法?请随意用您喜欢的任何语言编写示例代码.
我的想法
symbol : either a token or a node
result : success or failure
token : a lexical token from source text
value -> string : the value of the token
type -> integer : the named type code of the token
next -> token : reads the next token and keeps position of the previous token
back -> token : moves back to the previous position and re-reads the token
node : a node in the syntax tree
type -> integer : the named type code of the node
symbols -> linkedList : the symbols found at this node
append -> symbol -> node : appends the new symbol to a new copy of the node
这是我一直在思考的一个想法.这里的主要问题是处理语法错误.我的意思是我可以停在第一个错误,但这似乎不对.
let program token =
sourceElements (node nodeType.program) token
let sourceElements node token =
let (n, r) = sourceElement (node.append (node nodeType.sourceElements)) token
match r with
| success -> (n, r)
| failure -> // ???
let sourceElement node token =
match token.value with
| "function" ->
functionDeclaration (node.append (node nodeType.sourceElement)) token
| _ ->
statement (node.append (node nodeType.sourceElement)) token
Run Code Online (Sandbox Code Playgroud)
请注意
我将提供一个很好的赏金给最好的答案,所以不要感到匆忙.简单地发布链接的答案对显示代码或包含详细解释的答案的权重较小.
最后的说明
我对这种东西真的很陌生,所以不要害怕称我为傻瓜.
Hei*_*mus 10
您想要将某些内容解析为抽象语法树.
在纯函数式编程语言Haskell中,您可以使用解析器组合器来表达您的语法.这是一个解析微小表达式语言的例子:
编辑使用monadic风格来匹配Graham Hutton的书
-- import a library of *parser combinators*
import Parsimony
import Parsimony.Char
import Parsimony.Error
(+++) = (<|>)
-- abstract syntax tree
data Expr = I Int
| Add Expr Expr
| Mul Expr Expr
deriving (Eq,Show)
-- parse an expression
parseExpr :: String -> Either ParseError Expr
parseExpr = Parsimony.parse pExpr
where
-- grammar
pExpr :: Parser String Expr
pExpr = do
a <- pNumber +++ parentheses pExpr -- first argument
do
f <- pOp -- operation symbol
b <- pExpr -- second argument
return (f a b)
+++ return a -- or just the first argument
parentheses parser = do -- parse inside parentheses
string "("
x <- parser
string ")"
return x
pNumber = do -- parse an integer
digits <- many1 digit
return . I . read $ digits
pOp = -- parse an operation symbol
do string "+"
return Add
+++
do string "*"
return Mul
Run Code Online (Sandbox Code Playgroud)
这是一个示例运行:
*Main> parseExpr "(5*3)+1"
Right (Add (Mul (I 5) (I 3)) (I 1))
Run Code Online (Sandbox Code Playgroud)
要了解有关解析器组合器的更多信息,请参阅Graham Hutton的书"Haskell中的编程"或"Real World Haskell"的第16章中的第8 章.
许多解析器组合器库可以与您打算使用不同的令牌类型一起使用.令牌流通常表示为令牌列表[Token].