Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_rdf.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197(*********************************************************************************)(* OCaml-RDF *)(* *)(* Copyright (C) 2012-2021 Institut National de Recherche en Informatique *)(* et en Automatique. All rights reserved. *)(* *)(* This program is free software; you can redistribute it and/or modify *)(* it under the terms of the GNU Lesser General Public License version *)(* 3 as published by the Free Software Foundation. *)(* *)(* This program 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 *)(* GNU General Public License for more details. *)(* *)(* You should have received a copy of the GNU General Public License *)(* along with this program; if not, write to the Free Software *)(* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA *)(* 02111-1307 USA *)(* *)(* Contact: Maxence.Guesdon@inria.fr *)(* *)(*********************************************************************************)(** OCaml syntax extension to check syntax of Sparql queries at compile time. *)moduleRe=StrexceptionErrorofLocation.t*stringletmkloc=Location.mklocletmknoloc=Location.mknoloclet()=Location.register_error_of_exn(funexn->matchexnwith|Error(loc,msg)->Some(Location.error~locmsg)|_->None)letlongident_of_string?locstr=letb=Lexing.from_stringstrinletb=matchlocwith|None->b|Someloc->letp=loc.Location.loc_startin{bwithLexing.lex_start_p=p;lex_curr_p=p}inParse.longidentbletlid_sprintf=Location.mknoloc(longident_of_string"Printf.sprintf")letlid_sparql_error=Location.mknoloc(longident_of_string"Rdf.Sparql.Error")letlid_sparql_parse_error=Location.mknoloc(longident_of_string"Rdf.Sparql.Parse_error")openPpxlibopenAst_helpermoduleLocation=Ppxlib_ast__Import.Locationletsparql_node="sparql"letre_fmt=Re.regexp"\\([^%]?\\)%\\([-+0# ]*[0-9]*\\(\\.[0-9]+\\)?[lLn]?\\(\\({term}\\)\\|[!%@,diXxoSsCcFfEeGgBbat]\\)\\)"letcheck_query_fmtlocfmt=letfs=letres=matchRe.matched_group4swith"{term}"->"<http://foo/bar>"|"d"|"i"->"0"|"s"->"string"|"S"->"\"String\""|"o"->"0"|"c"->"c"|"C"->"'C'"|"f"->"0.0"|"F"|"E"|"e"|"G"|"g"->"0.0e-0"|"X"->"ABCD123"|"x"->"abcd123"|"B"|"b"->"true"|"a"->"\"%a\""|"t"->"\"%t\""|"!"->""|"@"->"@"|"%"->"%"|","->""|_->"%"^(Re.matched_group2s)in(tryRe.matched_group1swith_->"")^resinletq=Re.global_substitutere_fmtffmtintryignore(Rdf.Sparql.query_from_stringq)withRdf.Sparql.Errore->letq=Re.global_replace(Re.regexp_string"\n")"\n "qinletmsg=Printf.sprintf"Checking syntax of query\n %s\n%s"q(Rdf.Sparql.string_of_errore)inraise(Error(loc,msg))letgen_code~loc~attrsfmtargs=letargs=(Nolabel,Exp.constant~loc(Pconst_string(fmt,loc,None)))::argsinletf=lete=Exp.apply~loc(Exp.ident(mknoloc(longident_of_string"Rdf.Sparql.query_from_string")))[Nolabel,Exp.ident(mknoloc(longident_of_string"_q"));]inletcase=letpat=Pat.constructlid_sparql_error(Some(Pat.constructlid_sparql_parse_error(Some(Pat.tuple[Pat.var(mknoloc"eloc");Pat.var(mknoloc"msg")]))))inlete=Exp.let_Nonrecursive[Vb.mk(Pat.var(mknoloc"msg"))(Exp.apply(Exp.identlid_sprintf)[Nolabel,Exp.constant(Pconst_string("%s\nin %s",Location.none,None));Nolabel,Exp.ident(mknoloc(longident_of_string"msg"));Nolabel,Exp.ident(mknoloc(longident_of_string"_q"));])](Exp.apply(Exp.ident(mknoloc(longident_of_string"raise")))[Nolabel,Exp.constructlid_sparql_error(Some(Exp.constructlid_sparql_parse_error(Some(Exp.tuple[Exp.ident(mknoloc(longident_of_string"eloc"));Exp.ident(mknoloc(longident_of_string"msg"));]))))])inExp.casepateinletbody=Exp.try_~loc~attrse[case]inExp.fun_NolabelNone(Pat.var(mknoloc"_q"))bodyinExp.apply~loc~attrs(Exp.ident(mknoloc(longident_of_string"Printf.ksprintf")))((Nolabel,f)::args);;letexpand~loc~pathe=matchmatche.pexp_descwith|Pexp_constant(Pconst_string(s,_,_))->Some(e.pexp_loc,s,[])|Pexp_apply({pexp_desc=Pexp_constant(Pconst_string(s,_,_));pexp_loc},args)->Some(pexp_loc,s,args)|_->Nonewith|None->Location.raise_errorf~loc:e.pexp_loc"Invalid payload for sparql extension"|Some(loc,fmt,args)->check_query_fmtlocfmt;letterms=ref[]inletn=ref(-1)inletfs=incrn;letg=Re.matched_group4sinmatchgwith"{term}"->terms:=!n::!terms;(Re.matched_group1s)^"%s"|_->Re.matched_stringsinletfmt=Re.global_substitutere_fmtffmtinletreciteri=function[]->[]|(l,e)::qwhenList.memi!terms->lete=Exp.apply(Exp.ident(mknoloc(longident_of_string"Rdf.Term.string_of_term")))[Nolabel,e]in(l,e)::iter(i+1)q|x::q->x::iter(i+1)qinletargs=iter0argsingen_code~loc:e.pexp_loc~attrs:e.pexp_attributesfmtargsletmy_extension=Extension.declaresparql_nodeExtension.Context.expressionAst_pattern.(single_expr_payload__)expandletrule=Ppxlib.Context_free.Rule.extensionmy_extensionlet()=Driver.register_transformation~rules:[rule]sparql_node