Daniel@0: # module uripattern Daniel@0: Daniel@0: by Samer Abdallah, UCL, 2014 Daniel@0: Daniel@0: Daniel@0: This directory contains several alternative implementations of a small URI grammar Daniel@0: which supports both generation and parsing (pattern-matching) of URIs. Daniel@0: Daniel@0: There are two variants of the language. The earlier design is quite flexible but Daniel@0: leads to heavily non-deterministic parsing, which is perhaps not what one wants Daniel@0: for URI computations which might potentially be called very frequently. The later Daniel@0: design reduces or eliminates this non-determinism, depending on the implementatation. Daniel@0: Daniel@0: ### Grammar Daniel@0: Daniel@0: We describe the pattern grammar in terms of an algebraic datatype for the pattern language. Daniel@0: Daniel@0: Daniel@0: uri_pattern ---> prefix:uri_part Daniel@0: ; uri_part. Daniel@0: Daniel@0: P :: prefix :- rdf_current_prefix(P). % any registered prefix atom Daniel@0: M :: macro_invocation :- uripattern:def(M,_). Daniel@0: Daniel@0: uri_part ---> \macro_invocation Daniel@0: ; uri_part/uri_part % slash separated concatenation Daniel@0: ; uri_part+uri_part % direct concatenation Daniel@0: ; num(number) % decimal repn of number Daniel@0: ; enc(atomic) % HTML form-encoded atom Daniel@0: ; atm(atomic) % any atomic value Daniel@0: ; Daniel@0: . Daniel@0: Daniel@0: The more deterministic grammar removes direct concatenation and arbitrary atom parsing Daniel@0: but adds a tail/1 functor to capture all the remaining characters in the URI: Daniel@0: Daniel@0: uri_part ---> \macro_invocation Daniel@0: ; uri_part/uri_part % slash separated concatenation Daniel@0: ; num(number) % decimal repn of number Daniel@0: ; enc(atomic) % HTML form-encoded atom Daniel@0: ; tail(atomic) % matches rest of URI Daniel@0: ; Daniel@0: . Daniel@0: Daniel@0: This grammar as written is not quite strict enough to enforce the rule that any tail/1 Daniel@0: term must be the last thing in the pattern. The implementations are slightly less strict Daniel@0: than this this specification. Daniel@0: Daniel@0: Daniel@0: ### Example Daniel@0: Daniel@0: Given the following declarations: Daniel@0: Daniel@0: :- rdf_register_prefix(eg,'http://wwww.example.org/'). Daniel@0: uripattern:def(matrix(X,Y),num(X)/num(Y)). Daniel@0: Daniel@0: Then URIs can be generated as follows: Daniel@0: Daniel@0: pattern_uri(eg:home,A). Daniel@0: ~> A='http://www.example.org/home' Daniel@0: pattern_uri(eg:files/tail('home/chomsky/.profile'),A). Daniel@0: ~> A='http://www.example.org/files/home/chomsky/.profile' Daniel@0: pattern_uri(eg:people/enc('Chomsky, N')/pets,A). Daniel@0: ~> A='http://www.example.org/people/Chomsky%2c%20N/pets' Daniel@0: pattern_uri(eg:chessboard/matrix(3,6),A). Daniel@0: ~> A='http://www.example.org/chessboard/3/6' Daniel@0: Daniel@0: URIs can also be parsed, eg as follows Daniel@0: Daniel@0: pattern_uri(eg:files/tail(Path), 'http://www.example.org/files/home/chomsky/.profile'). Daniel@0: ~> Path= Daniel@0: pattern_uri(eg:people/enc(Name)/pets, 'http://www.example.org/people/Chomsky%2c%20N/pets'). Daniel@0: ~> Name='Chomsky, N' Daniel@0: pattern_uri(eg:chessboard/matrix(X,Y), 'http://www.example.org/chessboard/3/6'). Daniel@0: ~> X=3, Y=6 Daniel@0: Daniel@0: Daniel@0: ### Implementations Daniel@0: Daniel@0: There are several implementations: Daniel@0: Daniel@0: uripattern\_constraint : Works by splicing atoms and uses delayed goals to handle arbitrary modes. Daniel@0: Daniel@0: uripattern\_string : Works by splicing strings. Daniel@0: Daniel@0: uripattern\_atom : Works by splicing atoms. Daniel@0: Daniel@0: uripattern\_dcg : Converts URI to and from a list of codes and uses a DCG. Daniel@0: Daniel@0: uripattern\_detdcg : A more deterministic DCG Daniel@0: Daniel@0: uripattern\_detstring : A more deterministic version of string splicing. Daniel@0: Daniel@0: