123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293openReason_toolchain_confopenReason_errorsmoduleP=Reason_recover_parsermoduleLexer=Reason_lexer(* From Reason source text to OCaml AST
1. Make a lexbuf from source text
2. Reason_lexer:
a. Using OCamllex:
extract one token from stream of characters
b. post-process token:
- store comments separately
- insert ES6_FUN token
- insert completion identifier
3. Reason_parser, using Menhir:
A parser with explicit continuations, which take a new token and return:
- an AST when parse succeeded
- a new continuation if more tokens are needed
- nothing, if the parser got stuck (token is invalid in current state)
4. Reason_toolchain connect lexer and parser:
*)typetoken=Reason_parser.tokentypeinvalid_docstrings=Reason_lexer.invalid_docstringsletreclooplexerparser=lettoken=Lexer.tokenlexerinmatchP.stepparsertokenwith|P.Intermediateparser'->looplexerparser'|P.Error->(* Impossible to reach this case? *)let_,loc_start,loc_end=tokeninletloc={Location.loc_start;loc_end;loc_ghost=false}inraise_fatal_error(Parsing_error"Syntax error")loc|P.Success(x,docstrings)->(x,docstrings)letinitial_runentry_pointlexer=looplexer(P.initialentry_point(Lexer.lexbuflexer).Lexing.lex_curr_p)letimplementationlexer=initial_runReason_parser.Incremental.implementationlexerletinterfacelexer=initial_runReason_parser.Incremental.interfacelexerletcore_typelexer=initial_runReason_parser.Incremental.parse_core_typelexerlettoplevel_phraselexer=initial_runReason_parser.Incremental.toplevel_phraselexerletuse_filelexer=initial_runReason_parser.Incremental.use_filelexer(* Skip tokens to the end of the phrase *)letrecskip_phraselexer=trymatchLexer.tokenlexerwith|(Reason_parser.SEMI|Reason_parser.EOF),_,_->()|_->skip_phraselexerwithReason_error(Lexing_error(Unterminated_comment_|Unterminated_string|Unterminated_string_in_comment_|Illegal_character_),_)->skip_phraselexerletsafeguard_parsinglexbuffn=tryfn()with|Reason_error_aserrwhen!Location.input_name="//toplevel//"->skip_phrase(Lexer.initlexbuf);raiseerr|Location.Error_asx->letloc=Location.currlexbufinif!Location.input_name="//toplevel//"thenlet_=skip_phrase(Lexer.initlexbuf)inraise(Syntaxerr.Error(Syntaxerr.Otherloc))elseraisexletformat_interface_with_comments(signature,comments)formatter=letreason_formatter=Reason_pprint_ast.createFormatter()inreason_formatter#signaturecommentsformattersignatureletformat_implementation_with_comments(implementation,comments)formatter=letreason_formatter=Reason_pprint_ast.createFormatter()inreason_formatter#structurecommentsformatterimplementation