Ocaml词法分析器/解析器规则



我用ocaml写了一个程序,给定一个中音表达式,如1 + 2,输出前缀表示法:+ 1 2

我的问题是我找不到一种方法来制定这样的规则:所有的值,操作符和括号应该总是由至少一个空格分隔:1+ 1将是错误的1+ 1 ok。我不希望使用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"

另外,如果你有一些关于代码的提示,或者如果你注意到一些程序风格的错误,那么我会很感激你让我知道。谢谢!

Genlex提供了一个现成的词法分析器,它尊重OCaml的词法约定,特别是忽略您提到的位置中的空格。我不认为你可以在它的基础上实现你想要的东西(它不是一个灵活的解决方案,而是一个让原型工作的快速方法)。

如果您想继续编写流解析器,您可以为它编写自己的词法分析器:定义token类型,并将char Stream.t lex为token Stream.t,然后您可以按照自己的意愿进行解析。否则,如果您不想使用Camlp4,则可以尝试使用LR解析器生成器,例如menhir(更好的ocamlyacc)。

相关内容

  • 没有找到相关文章

最新更新