我正在学习如何解析简单的程序。
这是我的雷克萨斯。
{
open Parser
exception SyntaxError of string
}
let white = [' ' '\t']+
let blank = ' '
let identifier = ['a'-'z']
rule token = parse
| white {token lexbuf} (* skip whitespace *)
| '-' { HYPHEN }
| identifier {
let buf = Buffer.create 64 in
Buffer.add_string buf (Lexing.lexeme lexbuf);
scan_string buf lexbuf;
let content = (Buffer.contents buf) in
STRING(content)
}
| _ { raise (SyntaxError "Unknown stuff here") }
and scan_string buf = parse
| ['a'-'z']+ {
Buffer.add_string buf (Lexing.lexeme lexbuf);
scan_string buf lexbuf
}
| eof { () }我的“最后”:
type t =
String of string
| Array of t list我的解析器:
%token <string> STRING
%token HYPHEN
%start <Ast.t> yaml
%%
yaml:
| scalar { $1 }
| sequence {$1}
;
sequence:
| sequence_items {
Ast.Array (List.rev $1)
}
;
sequence_items:
(* empty *) { [] }
| sequence_items HYPHEN scalar {
$3::$1
};
scalar:
| STRING { Ast.String $1 }
;目前,我希望解析普通的“字符串”,即some text或“strings”的“数组”,即- item1 - item2。
当我用Menhir编译解析器时,我得到:
Warning: production sequence -> sequence_items is never reduced.
Warning: in total, 1 productions are never reduced.我对解析很陌生。为什么这一点从未减少过?
发布于 2017-09-29 09:14:38
声明到解析器的入口点称为main。
%start <Ast.t> main但我无法在代码中看到main的产生。也许入口点应该是yaml?如果改变了-错误仍然存在吗?
另外,尝试将EOF令牌添加到lexer和入门级产品中,如下所示:
parse_yaml: yaml EOF { $1 }例如,参见这里:https://github.com/Virum/compiler/blob/28e807b842bab5dcf11460c8193dd5b16674951f/grammar.mly#L56
下面链接到真实世界OCaml也讨论了如何使用EOL-我认为这将解决您的问题。
顺便说一句,用OCaml编写YAML解析器真的很酷。如果开源的话,它对社区将是非常有用的。注意,YAML是缩进敏感的,所以要用Menhir解析它,您需要通过lexer生成某种类型的INDENT和DEDENT标记。而且,YAML是JSON的一个严格的超集,这意味着从JSON子集开始,然后扩展它,这可能(或者不)是有意义的。Real OCaml展示了如何使用Menhir编写JSON解析器:
https://dev.realworldocaml.org/16-parsing-with-ocamllex-and-menhir.html
https://stackoverflow.com/questions/46485117
复制相似问题