ocaml menhir 解析器生产从未减少
ocaml menhir parser production is never reduced
我正在学习如何解析简单的程序。
这是我的词法分析器。
{
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 { () }
我的"ast":
type t =
String of string
| Array of t list
我的解析器:
%token <string> STRING
%token HYPHEN
%start <Ast.t> yaml
%%
yaml:
| scalar { }
| sequence {}
;
sequence:
| sequence_items {
Ast.Array (List.rev )
}
;
sequence_items:
(* empty *) { [] }
| sequence_items HYPHEN scalar {
::
};
scalar:
| STRING { Ast.String }
;
我目前正处于要解析纯文本 'strings' 的阶段,即
some text
或 'arrays',共 'strings',即 - item1 - item2
。
当我用 Menhir 编译解析器时,我得到:
Warning: production sequence -> sequence_items is never reduced.
Warning: in total, 1 productions are never reduced.
我对解析还很陌生。为什么这从未减少?
您声明解析器的入口点称为 main
%start <Ast.t> main
但我在您的代码中看不到 main
产生式。也许入口点应该是yaml
?如果更改 - 错误是否仍然存在?
此外,尝试将 EOF
标记添加到您的词法分析器和入门级产品中,如下所示:
parse_yaml: yaml EOF { }
示例见此处:https://github.com/Virum/compiler/blob/28e807b842bab5dcf11460c8193dd5b16674951f/grammar.mly#L56
下面的 link to Real World OCaml 也讨论了如何使用 EOL——我想这会解决你的问题。
顺便说一下,您在 OCaml 中编写 YAML 解析器真是太棒了。如果开源,它将对社区非常有用。请注意,YAML 对缩进敏感,因此要使用 Menhir 解析它,您需要通过词法分析器生成某种 INDENT
和 DEDENT
标记。此外,YAML 是 JSON 的严格超集,这意味着从 JSON 子集开始然后扩展它可能(或可能不)有意义。 Real World OCaml 展示了如何使用 Menhir 编写 JSON 解析器:
https://dev.realworldocaml.org/16-parsing-with-ocamllex-and-menhir.html
我正在学习如何解析简单的程序。
这是我的词法分析器。
{
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 { () }
我的"ast":
type t =
String of string
| Array of t list
我的解析器:
%token <string> STRING
%token HYPHEN
%start <Ast.t> yaml
%%
yaml:
| scalar { }
| sequence {}
;
sequence:
| sequence_items {
Ast.Array (List.rev )
}
;
sequence_items:
(* empty *) { [] }
| sequence_items HYPHEN scalar {
::
};
scalar:
| STRING { Ast.String }
;
我目前正处于要解析纯文本 'strings' 的阶段,即
some text
或 'arrays',共 'strings',即 - item1 - item2
。
当我用 Menhir 编译解析器时,我得到:
Warning: production sequence -> sequence_items is never reduced.
Warning: in total, 1 productions are never reduced.
我对解析还很陌生。为什么这从未减少?
您声明解析器的入口点称为 main
%start <Ast.t> main
但我在您的代码中看不到 main
产生式。也许入口点应该是yaml
?如果更改 - 错误是否仍然存在?
此外,尝试将 EOF
标记添加到您的词法分析器和入门级产品中,如下所示:
parse_yaml: yaml EOF { }
示例见此处:https://github.com/Virum/compiler/blob/28e807b842bab5dcf11460c8193dd5b16674951f/grammar.mly#L56
下面的 link to Real World OCaml 也讨论了如何使用 EOL——我想这会解决你的问题。
顺便说一下,您在 OCaml 中编写 YAML 解析器真是太棒了。如果开源,它将对社区非常有用。请注意,YAML 对缩进敏感,因此要使用 Menhir 解析它,您需要通过词法分析器生成某种 INDENT
和 DEDENT
标记。此外,YAML 是 JSON 的严格超集,这意味着从 JSON 子集开始然后扩展它可能(或可能不)有意义。 Real World OCaml 展示了如何使用 Menhir 编写 JSON 解析器:
https://dev.realworldocaml.org/16-parsing-with-ocamllex-and-menhir.html