0
我写在OCaml的一个程序,给予相同的1 + 2的中缀表达式,输出前缀表示法:+ 1 2ocaml的词法/语法规则
我的问题是我没有找到一种方法,使规则例如:所有的值,运算符和括号至少应该由一个空格隔开:1 + 1将是错误的1 + 1。我想不使用ocamlp4语法。
这里是代码:
open Genlex
type tree =
| Leaf of string
| Node of tree * string * tree
let my_lexer str =
let kwds = ["("; ")"; "+"; "-"; "*"; "/"] in
make_lexer kwds (Stream.of_string str)
let make_tree_from_stream stream =
let op_parser operator_l higher_perm =
let rec aux left higher_perm = parser
[<'Kwd op when List.mem op operator_l; right = higher_perm; s >]
-> aux (Node (left, op, right)) higher_perm s
| [< >]
-> left
in
parser [< left = higher_perm; s >] -> aux left higher_perm s
in
let rec high_perm l = op_parser ["*"; "/"] brackets l
and low_perm l = op_parser ["+"; "-"] high_perm l
and brackets = parser
| [< 'Kwd "("; e = low_perm; 'Kwd ")" >] -> e
| [< 'Ident n >] -> Leaf n
| [< 'Int n >] -> Leaf (string_of_int n)
in
low_perm stream
let rec draw_tree = function
| Leaf n -> Printf.printf "%s" n
| Node(fg, r, fd) -> Printf.printf "(%s " (r);
draw_tree fg;
Printf.printf " ";
draw_tree fd;
Printf.printf ")"
let() =
let line = read_line() in
draw_tree (make_tree_from_stream (my_lexer line)); Printf.printf "\n"
另外,如果你有一些提示有关代码或如果你注意到的前卫风格的一些错误,那么我会很高兴,你让它我知道。谢谢 !
嗯,我不想使用ocamlp4语法,因为它真的很可怕。我对ocaml的语法/哲学非常感兴趣。当你说你可以写自己的词法分析器,你的意思是我不应该使用make_lexer并写我自己的函数?感谢您的帮助! – axzwl 2013-05-06 05:13:56
是的,如果您想要对空格进行细致的处理,您应该编写自己的词法分析器函数。 Genlex只是这种功能的一个特定实例。但是你是否考虑过使用解析器生成器而不是手动编写? – gasche 2013-05-06 06:27:33
是的,我已经考虑过了,但是我想用ocamlp4的流感觉舒适,所以我只写了自己的解析器,并且记住它应该是一个很好的培训。 – axzwl 2013-05-06 15:59:43