123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154typelocation=Lexing.position*Lexing.positionletupdate_loc?filenamelexbuf=letpos=lexbuf.Lexing.lex_curr_pinletnew_file=matchfilenamewith|None->pos.Lexing.pos_fname|Somes->sinlexbuf.Lexing.lex_curr_p<-{poswithLexing.pos_fname=new_file;Lexing.pos_lnum=pos.Lexing.pos_lnum+1;Lexing.pos_bol=pos.Lexing.pos_cnum;}moduletypeE=sigtypetvalto_string:t->stringendmoduletypeERROR=sigtypebracket=|Round|Square|Curlytypelex_error=|Unstarted_comment|Unstarted_bracket|Mismatch_parenthesesofbracket|Unclosed_comment|Expectofstring|Bad_tokentypesynt_errortypeerror=|SyntErrorofsynt_error|LexErroroflex_error|SysErrorofstring(** The exception that should be raised when an error occur *)exceptionErrorof(error*location)(** [error_msg e ~filename] returns a string describing the error
[e] while the file [filename] is being processed *)valerror_msg:?filename:string->(error*location)->stringvalempty_bracket_stack:(bracket*location)listvalpush_bracket:bracket->location->(bracket*location)list->(bracket*location)listvalpop_bracket:bracket->location->(bracket*location)list->(bracket*location)listvalcheck_brackets:(bracket*location)list->unitendmoduleMake(E:E)=structtypebracket=|Round|Square|Curlyletkind_to_char=function|Round->'('|Square->'['|Curly->'{'typelex_error=|Unstarted_comment|Unstarted_bracket|Mismatch_parenthesesofbracket|Unclosed_comment|Expectofstring|Bad_tokenletlex_error_to_string=function|Unstarted_comment->"Syntax error: No comment opened before this closing of comment"|Unstarted_bracket->"Syntax error: No bracket opened before this right bracket"|Unclosed_comment->"Syntax error: Unclosed comment"|Mismatch_parenthesesk->Printf.sprintf"Syntax error: Unclosed parenthesis '%c'"(kind_to_chark)|Expects->Printf.sprintf"Syntax error: %s expected"s|Bad_token->"Lexing error: no such token allowed"typesynt_error=E.ttypeerror=|SyntErrorofsynt_error|LexErroroflex_error|SysErrorofstringexceptionErrorof(error*location)letcompute_comment_for_location(pos1,pos2)=letline2=pos2.Lexing.pos_lnuminletcol2=pos2.Lexing.pos_cnum-pos2.Lexing.pos_bolinletpos1=pos1inletline1=pos1.Lexing.pos_lnuminletcol1=pos1.Lexing.pos_cnum-pos1.Lexing.pos_bolinifline1=line2thenPrintf.sprintf"line %d, characters %d-%d"line2col1col2elsePrintf.sprintf"line %d, character %d to line %d, character %d"line1col1line2col2leterror_msg?filename(err,loc)=letinput=matchfilenamewith|None->""|Somef->Printf.sprintf"File \"%s\","finletmsg=matcherrwith|LexErrore->lex_error_to_stringe|SysErrore->e|SyntErrore->E.to_stringeinPrintf.sprintf"%s%s\n%s"input(compute_comment_for_locationloc)msgletempty_bracket_stack=[]letpush_bracketbrlocstack=(br,loc)::stackletpop_bracketbrlstack=matchstackwith|[]->raise(Error(LexErrorUnstarted_bracket,l))|(k,_)::tlwhenk=br->tl|(k,l)::_->raise(Error(LexError(Mismatch_parenthesesk),l))letcheck_bracketsstack=matchstackwith|[]->()|(k,loc)::_->raise(Error(LexError(Mismatch_parenthesesk),loc))end