123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251(*
* This file is part of the Watson Conversation Service OCaml API project.
*
* Copyright 2016-2017 IBM Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*)openSpel_topenSpel_sedlexer_jexceptionLexErrorofstringleterrordefaultmsg=Log.error"Spel parsing"defaultmsgletwarningdefaultmsg=Log.warning"Spel parsing"msg;defaulttypestate=BodyLexing|ExprLexing(** {6 Expression lexer} *)letexpr_lexerbufflb=Spel_sedlexer_j.tokenbufflbletmk_expr_lexer()=expr_lexer(Spel_util.string_buff())(** {6 lexing} *)letbody_lexerstbufflb=beginmatch!stwith|BodyLexing->lettk=Spel_sedlexer_j.bodybufflbinbeginmatchtkwith|Spel_parser_j.OPENEXPR_->st:=ExprLexing;tk|_->tkend|ExprLexing->lettk=Spel_sedlexer_j.tokenbufflbinbeginmatchtkwith|Spel_parser_j.CLOSEEXPR->st:=BodyLexing;tk|_->tkendendletmk_body_lexer()=body_lexer(refBodyLexing)(Spel_util.string_buff())(** {6 desugaring} *)letrecfold_exprfe=letdesc=beginmatche.expr_descwith|E_litl->E_litl|E_prop(e,s)->E_prop(fold_exprfe,s)|E_prop_catch(e,s)->E_prop_catch(fold_exprfe,s)|E_get(e1,e2)->E_get(fold_exprfe1,fold_exprfe2)|E_listel->E_list(List.map(fold_exprf)el)|E_new_array(t,ilo,elo)->beginmatchelowith|None->E_new_array(t,ilo,None)|Someel->E_new_array(t,ilo,Some(List.map(fold_exprf)el))end|E_new(t,el)->E_new(t,List.map(fold_exprf)el)|E_call(eo,s,el)->beginmatcheowith|None->E_call(None,s,List.map(fold_exprf)el)|Somee->E_call(Some(fold_exprfe),s,List.map(fold_exprf)el)end|E_call_catch(eo,s,el)->beginmatcheowith|None->E_call_catch(None,s,List.map(fold_exprf)el)|Somee->E_call_catch(Some(fold_exprfe),s,List.map(fold_exprf)el)end|E_op(op,el)->E_op(op,List.map(fold_exprf)el)|E_conditional(e1,e2,e3)->E_conditional(fold_exprfe1,fold_exprfe2,fold_exprfe3)|E_idents->E_idents(* WCS extensions *)|E_anything_else->E_anything_else|E_context->E_context|E_conversation_start->E_conversation_start|E_entities->E_entities|E_input->E_input|E_intents->E_intents|E_output->E_output|E_variables->E_variables|E_intents->E_intents|E_entity(s1,s2)->E_entity(s1,s2)(* Fallback *)|E_errors->E_errorsendinletdesc=fdescinletloc=e.expr_locinlettext=e.expr_textinSpel_util.mk_expr_fulldescloctextletrefresh_expr_texte=beginmatche.expr_textwith|None->()|Somet->e.expr_text<-Some(Spel_print.to_stringe)endletdesugar_spel=reffalseletdesugar_desce=beginmatchewith(* Shorthand syntax for variables *)|E_variable(v,None)->E_get(Spel_util.mk_exprE_context,Spel_util.mk_expr(E_lit(L_stringv)))|E_variable(v,Somes)->E_op(Op_eq,[Spel_util.mk_expr(E_get(Spel_util.mk_exprE_context,Spel_util.mk_expr(E_lit(L_stringv))));Spel_util.mk_expr(E_lit(L_strings))])|_->eendletdesugare=fold_exprdesugar_desceletresugar_spel=reffalseletresugar_desce=beginmatchewith(* Shorthand syntax for variables *)|E_get({expr_desc=E_context},{expr_desc=E_lit(L_strings)})->E_variable(s,None)(* XXX Keeps equality intact when resugaring
| E_op (Op_eq,
[{ expr_desc = E_get ({ expr_desc = E_context },
{ expr_desc = (E_lit (L_string v)) }) };
{ expr_desc = E_lit (L_string s) }]) ->
E_variable (v, Some s) XXX *)|_->eendletresugare=fold_exprresugar_desceletsugarere=lete=if!desugar_spelthendesugareelseeinlete=if!resugar_spelthenresugareelseeine(** {6 parsers} *)letfix_empty_conditionocond=beginmatchocondwith|Somecond->cond|None->Spel_util.mk_expr(E_lit(L_booleanfalse))endletexpression_from_filef=fix_empty_condition(Spel_util.uparse_fileSpel_parser_j.condition_main(mk_expr_lexer())f)letexpr_from_files=sugarer(expression_from_files)letexpression_from_strings=begintryletparsed=Spel_util.uparse_stringSpel_parser_j.condition_main(mk_expr_lexer())sinletast=fix_empty_conditionparsedinast.expr_text<-Somes;astwith|LexErrormsg->warning(Spel_util.mk_expr_text(E_errormsg)(Somes))(Format.sprintf"[%s] in expression: '%s'"msgs)|_->warning(Spel_util.mk_expr_text(E_error"Parse error in expression")(Somes))(Format.sprintf"error in expression: '%s'"s)endletexpr_from_strings=sugarer(expression_from_strings)letexpression_from_quoted_filef=Spel_util.uparse_fileSpel_parser_j.body_main(mk_body_lexer())fletquoted_expr_from_files=sugarer(expression_from_quoted_files)letexpression_from_quoted_strings=begintryletast=Spel_util.uparse_stringSpel_parser_j.body_main(mk_body_lexer())sinast.expr_text<-Somes;astwith|LexErrormsg->warning(Spel_util.mk_expr_text(E_errormsg)(Somes))(Format.sprintf"[%s] in text: '%s'"msgs)|_->warning(Spel_util.mk_expr_text(E_error"Parse error in text")(Somes))(Format.sprintf"in text: '%s'"s)endletquoted_expr_from_strings=sugarer(expression_from_quoted_strings)