Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file parse_js.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177(* Js_of_ocaml compiler
* Copyright (C) 2013 Hugo Heuzard
*)(* Yoann Padioleau
*
* Copyright (C) 2010 Facebook
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* version 2.1 as published by the Free Software Foundation, with the
* special exception on linking described in file license.txt.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the file
* license.txt for more details.
*)open!Stdlibletstrip_commentl=List.filter~f:(funx->not(Js_token.is_commentx))lletrecuntil_non_commentacc=function|[]->acc,None|x::xs->ifJs_token.is_commentxthenuntil_non_comment(x::acc)xselseacc,Some(x,xs)letadjust_tokens?(keep_comment=true)l=matchuntil_non_comment[]lwith|acc,Nonewhenkeep_comment->List.revacc|_,None->[]|past,Some(first,rest)->letopenJs_tokeninletfprevxacc=matchprev,xwith(* restricted productions *)(* 7.9.1 - 3 *)(* When, as the program is parsed from left to right, a token is encountered *)(* that is allowed by some production of the grammar, but the production *)(* is a restricted production and the token would be the first token for a *)(* terminal or nonterminal immediately following the annotation [no LineTerminator here] *)(* within the restricted production (and therefore such a token is called a restricted token), *)(* and the restricted token is separated from the previous token by at least *)(* one LineTerminator, then a semicolon is automatically inserted before the *)(* restricted token. *)|((T_RETURN_|T_CONTINUE_|T_BREAK_|T_THROW_),(T_SEMICOLON_|T_VIRTUAL_SEMICOLON_))->x::acc|(T_RETURN_|T_CONTINUE_|T_BREAK_|T_THROW_),_->letx'=Js_token.info_of_tokxinletprev'=Js_token.info_of_tokprevinifprev'.Parse_info.line<>x'.Parse_info.linethenx::Js_token.T_VIRTUAL_SEMICOLONx'::accelsex::acc|_,_->x::accinletrecauxprevacc=function|[]->List.revacc|e::l->letnprev,nacc=ifJs_token.is_commentethenifkeep_commentthenprev,e::accelseprev,accelsee,fpreveaccinauxnprevnacclinletpast=ifkeep_commentthenpastelse[]inauxfirst(first::past)resttypelexer=Js_token.tokenlistletlexer_aux?(rm_comment=true)lines_infolexbuf=letreclooplexbufextralines_infoprevacc=lettokinfolexbuf=letpi=Parse_info.t_of_lexbuflines_infolexbufinletpi=matchprevwith|None->{piwithParse_info.fol=Sometrue}|Someprev->letprev_pi=Js_token.info_of_tokprevinifprev_pi.Parse_info.line<>pi.Parse_info.linethen{piwithParse_info.fol=Sometrue}elsepiinmatchextrawith|None->pi|Some(file,offset)->letsrc=Parse_info.relative_pathlines_infofilein{piwithParse_info.src;name=Somefile;line=pi.Parse_info.line-offset}inlett=Js_lexer.initialtokinfoprevlexbufinmatchtwith|Js_token.EOF_->List.revacc|_->letextra=matchtwith|Js_token.TComment(ii,cmt)whenString.is_prefixcmt~prefix:"#"->(letlexbuf=Lexing.from_stringcmtintryletfile,line=Js_lexer.poslexbufinmatchextrawith|None->Some(file,ii.Parse_info.line-(line-2))|Some(_,offset)->Some(file,ii.Parse_info.line-(line-2)+offset)with_->extra)|_->extrainletprev=ifJs_token.is_commenttthenprevelseSometinlooplexbufextralines_infoprev(t::acc)inlettoks=looplexbufNonelines_infoNone[]in(* hack: adjust tokens *)adjust_tokens~keep_comment:(notrm_comment)toksletlexer_from_file?rm_commentfile:lexer=letlines_info=Parse_info.make_lineinfo_from_filefileinletic=open_infileinletlexbuf=Lexing.from_channelicinletlexer=lexer_aux?rm_commentlines_infolexbufinclose_inic;lexerletlexer_from_channel?rm_commentci:lexer=letlines_info,str=Parse_info.make_lineinfo_from_channelciinletlexbuf=Lexing.from_stringstrinlexer_aux?rm_commentlines_infolexbufletlexer_from_string?rm_comment?offsetstr:lexer=letlines_info=Parse_info.make_lineinfo_from_string?offsetstrinletlexbuf=Lexing.from_stringstrinlexer_aux?rm_commentlines_infolexbufletlexer_mapf=List.map~fletlexer_foldfaccl=List.fold_left~f~init:acclletlexer_filterfl=List.filter~flletlexer_from_listl=adjust_tokenslexceptionParsing_errorofParse_info.ttypest={mutablerest:Js_token.tokenlist;mutablecurrent:Js_token.token;mutablepassed:Js_token.tokenlist;mutableeof:bool}letparse_auxthe_parsertoks=letstate=matchtokswith|[]->{rest=[];passed=[];current=Js_token.EOFParse_info.zero;eof=false}|hd::_->{rest=toks;passed=[];current=hd;eof=false}inletlexer_fun_lb=matchstate.restwith|[]whennotstate.eof->state.eof<-true;letinfo=Js_token.info_of_tokstate.currentinJs_token.EOFinfo|[]->assertfalse|x::tl->state.rest<-tl;state.current<-x;state.passed<-x::state.passed;xinletlexbuf=Lexing.from_string""intrythe_parserlexer_funlexbufwithJs_parser.Error|Parsing.Parse_error->letpi=Js_token.info_of_tokstate.currentinraise(Parsing_errorpi)letparselex=parse_auxJs_parser.programlexletparse_exprlex=parse_auxJs_parser.standalone_expressionlex