Parsing 通过将.mly和.mll分开来检索解析的一部分
我正在编写一个前端来解析一组txt文件,每个文件包含一组程序,例如一个txt文件如下所示:Parsing 通过将.mly和.mll分开来检索解析的一部分,parsing,ocaml,lexical-analysis,ocamllex,ocamlyacc,Parsing,Ocaml,Lexical Analysis,Ocamllex,Ocamlyacc,我正在编写一个前端来解析一组txt文件,每个文件包含一组程序,例如一个txt文件如下所示: Sub procedure1 ... End Sub Sub procedure2 ... End Sub ... %start main %type <Syntax.ev> main %% main: procedure_declarations EOF { List.rev $1 } procedure_declarations: /* empty */ { [] } | pr
Sub procedure1
...
End Sub
Sub procedure2
...
End Sub
...
%start main
%type <Syntax.ev> main
%%
main: procedure_declarations EOF { List.rev $1 }
procedure_declarations:
/* empty */ { [] }
| procedure_declarations procedure_declaration { $2 :: $1 }
procedure_declaration:
SUB name = procedure_name EOS
body = procedure_body
END SUB EOS
{ { procedure_name = name; procedure_body = body } }
...
%start main
%type <Syntax.procedure_declaration> main
%%
main: procedure_declaration EOF { $1 };
...
syntax.ml包含:
type ev = procedure_declaration list
type procedure_declaration =
{ procedure_name : string; procedure_body : procedure_body }
type procedure_body = ...
...
parser.mly看起来像:
Sub procedure1
...
End Sub
Sub procedure2
...
End Sub
...
%start main
%type <Syntax.ev> main
%%
main: procedure_declarations EOF { List.rev $1 }
procedure_declarations:
/* empty */ { [] }
| procedure_declarations procedure_declaration { $2 :: $1 }
procedure_declaration:
SUB name = procedure_name EOS
body = procedure_body
END SUB EOS
{ { procedure_name = name; procedure_body = body } }
...
%start main
%type <Syntax.procedure_declaration> main
%%
main: procedure_declaration EOF { $1 };
...
由于以前parser.mly中的大部分内容都应该移到parser_pd.mly中,parser.mly现在应该比以前轻得多,看起来像:
%start main
%type <Syntax.ev> main
%%
main: procedure_declarations EOF { List.rev $1 }
procedure_declarations:
/* empty */ { [] }
| procedure_declarations procedure_declaration { $2 :: $1 }
procedure_declaration:
SUB name = procedure_name EOS
??????
END SUB EOS
{ { procedure_name = name;
procedure_body = Parser_pd.main (Lexer_pd.token ??????) } }
procedure_declaration:
SUB combined = procedure_name EOS /* nothing here */ EOS
{ { procedure_name = fst combined; procedure_body = snd combined; } }
procedure_name:
id = IDENT {
let lexbuf = _menhir_env._menhir_lexbuf in
(id, Parser_pd.main Lexer_pd.token lexbuf)
}
问题是我不知道怎么写这个??????部分和lexer.mll,它应该是轻的,因为它只读取令牌END、SUB和EOS,并让内容由lexer_pd.mll处理。可能需要Lexing模块的一些功能
希望我的问题是清楚的。。。有人能帮忙吗 您写入要检索过程\u声明的解析, 但是在您的代码中,您只想检索一个过程体,所以我 假设那是你想要的 用我自己的话来说,你需要在没有 告诉嵌入语法嵌入哪个语法。问题不在这里 你的问题,因为你幸运地有一个非常友好的语法 在LALR1中,您需要一个前瞻标记来决定 要遵守哪条规则。您的语法如下所示:
procedure_declaration:
SUB procedure_name EOS
procedure_body
END SUB EOS
您可以将过程\u名称和过程\u正文组合在一起,这样您的规则和
语义操作将如下所示:
%start main
%type <Syntax.ev> main
%%
main: procedure_declarations EOF { List.rev $1 }
procedure_declarations:
/* empty */ { [] }
| procedure_declarations procedure_declaration { $2 :: $1 }
procedure_declaration:
SUB name = procedure_name EOS
??????
END SUB EOS
{ { procedure_name = name;
procedure_body = Parser_pd.main (Lexer_pd.token ??????) } }
procedure_declaration:
SUB combined = procedure_name EOS /* nothing here */ EOS
{ { procedure_name = fst combined; procedure_body = snd combined; } }
procedure_name:
id = IDENT {
let lexbuf = _menhir_env._menhir_lexbuf in
(id, Parser_pd.main Lexer_pd.token lexbuf)
}
Parser_pd将包含以下规则:
main: procedure_body END SUB { $1 }
您很可能希望在Parser_pd中使用END SUB,因为procedure_body是
可能不会自我界定
请注意,在解析
过程名称标识符,因为这是您的前瞻。如果你叫它
在EOS中,为时已晚,解析器将从中提取令牌
尸体,已经。第二个EOS是末端接头后的EOS
_menhir_env这件事显然是一个只适用于menhir的黑客。
如果你使用它,你可能需要另一个黑客来让menhir-Inferre工作,
因为这并不期望用户引用它,所以符号不会
在范围内。那就是:
%{
type menhir_env_hack = { _menhir_lexbuf : Lexing.lexbuf }
let _menhir_env = { _menhir_lexbuf = Lexing.from_function
(* Make sure this lexbuf is never actually used. *)
(fun _ _ -> assert false) }
%}