Syntax 如何为给定的语法定义创建OCaml定义?
我是OCaml的新手。我有如下语法定义:Syntax 如何为给定的语法定义创建OCaml定义?,syntax,ocaml,definition,Syntax,Ocaml,Definition,我是OCaml的新手。我有如下语法定义: <program>::= | <instruction <program>> | "end" <instruction>::= | "move" | "left" | "right" | "repeat" <program> := | |“结束” ::= |“移动” |“左” |“对” |“重复” 如何为它编写OCaml定义?例如:“let p=…”通常,当你给某人一个语法时,你应该指定
<program>::=
| <instruction <program>>
| "end"
<instruction>::=
| "move"
| "left"
| "right"
| "repeat" <program>
:=
|
|“结束”
::=
|“移动”
|“左”
|“对”
|“重复”
如何为它编写OCaml定义?例如:“let p=…”通常,当你给某人一个语法时,你应该指定它是用什么语言写的,例如EBNF。你的例子对我来说不是一个有效的BNF 尽管如此,如果我正确理解了您的定义,那么
程序
和指令
将映射到以下OCaml类型:
type program =
| Instruction of instruction
| End
and instruction =
| Move
| Left
| Right
| Repeat of program
为了将任意字符串转换为上述定义的程序类型的值,需要编写解析器。OCaml中编写解析器的一种常用方法是使用ocamlex
和ocamlyacc
工具。但是这个简单的语法可以手动解析。以下函数将解析令牌列表并输出程序:
let rec parse = function
| ["instruction"; "move" ] -> Instruction Move
| ["instruction"; "left" ] -> Instruction Left
| ["instruction"; "right"] -> Instruction Right
| "instruction" :: "repeat" :: tokens -> Instruction (Repeat (parse tokens))
| ["end"] -> End
| [] -> invalid_arg "Unexpected end of stream"
| token :: _ -> invalid_arg ("Unexpected token: " ^ token)
标记列表应该由所谓的标记器(或lexer)生成,该函数接受字符串并将其拆分为标记列表。可以使用Str
库编写简单的标记器:
let tokenizer = Str.(split (regex " +"))
作为旁注:Str
库默认情况下不会加载到toplevel。为了加载它,您需要向toplevel发出以下指令(包括#符号):
你应该解释你真正想要什么。此语法树的数据结构定义,或此语法的解析器,或两者?到目前为止,您尝试了什么?我认为该指令实际上代表了一系列指令。这意味着你的文章有了实质性的改变,所以我没有编辑它。我也这么认为,但我不会解决OP的全部问题,我的目标是给出一个起点。
#use "topfind";;
#require "str";;