.net 缩短递归下降解析器中的活动模式
我想用类型.net 缩短递归下降解析器中的活动模式,.net,parsing,linked-list,f#,pattern-matching,.net,Parsing,Linked List,F#,Pattern Matching,我想用类型tokenlist->Ast*tokenlist构建活动模式 我有一个简单的Pascal语法:=“program”“;”。。通过将代码重新建模到此语法,我必须制作程序、标识符和块模式,如: let rec (|Program|_|) tokens = match tokens with | Token.Program :: tokens -> match tokens with | Identifier (identifier, t
tokenlist->Ast*tokenlist
构建活动模式
我有一个简单的Pascal语法:=“program”“;”。
。通过将代码重新建模到此语法,我必须制作程序
、标识符
和块
模式,如:
let rec (|Program|_|) tokens =
match tokens with
| Token.Program :: tokens ->
match tokens with
| Identifier (identifier, tokens) ->
match tokens with
| Semicolon :: tokens ->
match tokens with
| Block (block, tokens) ->
match tokens with
| Dot :: tokens -> Some (Ast.Program (identifier, block), tokens)
| _ -> failwithf "Expected %A" Dot
| _ -> failwith "Expected Block"
| _ -> failwithf "Expected %A" Semicolon
| _ -> failwith "Expected Identifier"
| _ -> failwithf "Expected %A" Token.Program
and (|Identifier|_|) tokens =
match tokens with
| Token.Identifier identifier :: tokens ->
Some (Ast.Identifier identifier, tokens)
| _ -> failwith "Expected Identifier"
...
因为有许多重复选项None
,我尝试将模式缩短为:
type rec (|Program|_|) tokens =
match tokens with
| Token.Program :: Identifier (ident, Semicolon :: Block (block, Dot :: rest)) ->
Some (Ast.Program (identifier, block), rest)
| _ -> None
新模式能如预期的那样工作吗?如何使活动模式变短,但在输入错误时也返回错误
此外,我还了解到FParsec用于解析和保留错误,我如何才能生成类似于FParsec的简单计算表达式。简单的方法就是将所有内容展平:
let rec private (|Program|_|) tokens =
match tokens with
| Token.Program ::Identifier (identifier, Semicolon :: Block (block,Dot :: tokens) ) ->Some (Ast.Program (identifier, block), tokens)
| Token.Program ::Identifier (identifier, Semicolon :: Block (block,_) ) ->failwith "Expected %A" Dot
| Token.Program ::Identifier (identifier, Semicolon ::_ ) ->failwith "Expected %A" Block
....
对于编写计算表达式,这是您最好的指南。而且,您的AST设计在我看来有点奇怪。为什么
标识符
和块
联合案例“在”它们内部吸收了以下标记,而程序
标记却没有?我希望看到更像将令牌与标识符ident::tokens
匹配,即标识符
大小写仅“吸收”标识符的名称。以下所有标记都“在”标识符案例中是没有意义的。我不知道我是否清楚地表达了我想说的话;你明白我的意思吗,或者我应该尝试重新表述吗?@rmunn所有活动模式都会吸收代币并返回剩余的代币。因为我从他们那里读到的应该是typetokenlist->Ast*tokenlist
。但是,你的标识符
令牌违反了这个规则。创建Identifier
的任何函数都应该有一个签名,如令牌列表->标识符*令牌列表
,但它的签名是令牌列表->标识符
。其余的令牌已被标识符令牌的后半部分吸收,这不是它应该如何进行的。@rmun也许您应该再次检查签名,我添加了标识符图案以获得清晰的视觉效果,它返回Ast.Identifier*Token list
。您知道如何快速查找或阻止标识符吗?e、 g.当我有type Token=|字符串标识符
时,我想宣布“预期标识符”,并且failwithf“预期%A”(标识符“)
将无法按预期工作。无法立即想到任何事情