{"id":18772199,"url":"https://github.com/francescobarbieri/uri-parser","last_synced_at":"2026-01-27T16:01:43.260Z","repository":{"id":152852971,"uuid":"431829468","full_name":"francescobarbieri/uri-parser","owner":"francescobarbieri","description":"Surfing the Internet, but not only, requires skills to manipulate strings that represents Universal Resource Identifiers (URI). The purpose of this project is to create two libraries (Prolog and Lisp) that build structures that internally represents URIs starting from their representation as string.","archived":false,"fork":false,"pushed_at":"2022-03-01T12:16:57.000Z","size":1010,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-21T01:14:50.435Z","etag":null,"topics":["lisp","parser","prolog","uri","uri-parser"],"latest_commit_sha":null,"homepage":"","language":"Prolog","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/francescobarbieri.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-25T12:00:48.000Z","updated_at":"2024-12-10T11:29:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"4875a16e-14af-44ff-8255-75bf190d2c91","html_url":"https://github.com/francescobarbieri/uri-parser","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/francescobarbieri/uri-parser","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francescobarbieri%2Furi-parser","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francescobarbieri%2Furi-parser/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francescobarbieri%2Furi-parser/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francescobarbieri%2Furi-parser/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/francescobarbieri","download_url":"https://codeload.github.com/francescobarbieri/uri-parser/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/francescobarbieri%2Furi-parser/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28816353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T12:25:15.069Z","status":"ssl_error","status_checked_at":"2026-01-27T12:25:05.297Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["lisp","parser","prolog","uri","uri-parser"],"created_at":"2024-11-07T19:28:08.558Z","updated_at":"2026-01-27T16:01:43.244Z","avatar_url":"https://github.com/francescobarbieri.png","language":"Prolog","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Uri Parser\r\n\r\n## Introduction\r\n\r\nSurfing the Internet, but not only, requires skills to manipulate strings that represents Universal Resource Identifiers (URI). The purpose of this project is to create two libraries (Prolog and Lisp) that build structures that internally represents URIs starting from their representation as string.\r\n\r\n## URI Syntax\r\n\r\n```\r\nURI     ::= URI1 | URI2\r\nURI1    ::= scheme ':' [authority] [['/'] [path] ['?' query] ['#' fragment]]\r\nURI2    ::= scheme ':' scheme-syntax\r\n\r\nscheme      ::= \u003cidentifier\u003e\r\nauthority   ::= '//' [userinfo '@'] host [':' port]\r\nuserinfo    ::= \u003cidentifier\u003e\r\nhost        ::= \u003chost-identifier\u003e ['.' \u003chost-identifier\u003e]*\r\n            | IP-address\r\nport        ::= \u003cdigit\u003e+\r\nIP-address  ::= \u003cNNN.NNN.NNN.NNN\u003e (N is a digit)\r\npath        ::= \u003cidentifier\u003e ['/' \u003cidentifier\u003e]* ['/']\r\nquery       ::= \u003cchars without '#'\u003e+\r\nfragment    ::= \u003cchars\u003e+\r\n\r\n\u003cidentifier\u003e        ::= \u003cchars without '/', '?', '#', '@' and ':'\u003e+\r\n\u003chost-identifier\u003e   ::= \u003cchars without '.', '?', '#', '@' and ':'\u003e+\r\n\u003cdigit\u003e             ::= '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'\r\n\r\nscheme-syntax       ::= \u003cspecial-scheme - see below\u003e\r\n```\r\n\r\n### Special Scheme\r\n\r\nHere we define some special syntaxes to take into consideration. The syntax is specified for each desired pattern. Note that the \"normal\" syntax must be used whenever the scheme is not among those recognized as special: `mailto`, `news`, `tel`, `fax` and `zos`.\r\n\r\n#### Scheme 'mailto'\r\n\r\nIn this case only the `userinfo` and `host` fields of the structure must be filled.\r\n\r\n```\r\nscheme-syntax   ::= [userinfo ['@' host]]\r\n```\r\n\r\n#### Scheme 'news'\r\n\r\nIn this case only the `host` field must be filled.\r\n\r\n```\r\nscheme-syntax   ::= [host]\r\n```\r\n\r\n#### Scheme 'tel' and 'fax'\r\n\r\nFor the sake of simplicity, no checks on the consistency of the identifier associated with userinfo were considered, apart from compliance with the specific syntactic rules.\r\n\r\n```\r\nscheme-syntax   ::= [userinfo]\r\n```\r\n\r\n#### Scheme 'zos'\r\n\r\nThe zos scheme describes the names of data-sets on IBM mainframes. In this case the special syntax is a variation of the production of `URI1`, with the `path` field having a different structure which is checked differently. The other fields (`userinfo`, `host`, `port`, `query`, `fragment`) are to be recognized normally as in the production of `URI1`.\r\n\r\n```\r\npath        ::= \u003cid44\u003e ['(' \u003cid8\u003e ')']\r\nid44        ::= (\u003calphanum\u003e | '.')+\r\nid8         ::= (\u003calphanum\u003e)+\r\nalphanum    ::= \u003calphabetic characters and digits\u003e\r\n```\r\n\r\nThe length of `id44` is at most 44 and that of `id8` is at most 8. Furthermore, `id44` and `id8` must start with an alphabetic character; `id44` cannot end with a '.'\r\n\r\n#### Notes\r\n\r\nMany fields are optional. `Port` has '80' by default and must be rendered as a number.\r\nStarting from the given grammar, an URI can therefore be divided into the following components:\r\n\r\n1. Scheme\r\n2. Userinfo\r\n3. Host\r\n4. Port\r\n5. Path\r\n6. Query\r\n7. Fragment\r\n\r\nNote that the grammar admits URIs containing only the scheme (and the default `port` '80')\r\n\r\n## Prolog\r\n\r\nThere is a `uri_parse/2` predicate in prolog:\r\n\r\n```Prolog\r\nuri_parse(URIString, URI).\r\n```\r\n\r\nwhich is true if URIString can be unbundled into the compound term:\r\n\r\n```Prolog\r\nURI = uri(Scheme, Userinfo, Host, Port, Path, Query, Fragment).\r\n```\r\n\r\nThe `uri_display/1` and `uri_display/2` predicates have also been implemented which print a URI in text format and on file respectively.  \r\nSome examples:\r\n\r\n```Prolog\r\nuri_parse(\"http://facebook.com\", URI).\r\nURI = uri(http, [], 'facebook.com', 80, [], [], [])\r\n```\r\n\r\n```Prolog\r\nuri_parse(\"sftp://anon@facebook.com/foo/uri.pl\", URI).\r\nURI = uri(sftp, anon, 'facebook.com', 80, 'foo/uri.pl', [], [])\r\n```\r\n\r\nThe program is also able to correctly answer queries in which the terms are partially instantiated, such as:\r\n\r\n```Prolog\r\nuri_parse(\"http://facebook.com\", uri(https, _, _, _, _, _, _)).\r\nfalse\r\n```\r\n\r\n```Prolog\r\nuri_parse(\"http://facebook.com\", uri(_, _, Host, _, _, _, _)).\r\nHost = 'facebook.com'\r\n```\r\n\r\n## Lisp\r\n\r\nIn Common Lisp a `uri-parse` function has been implemented which receives a string as input and returns a \"structure\" with at least the 7 fields mentioned above. This structure is represented with a `defstruct`.  \r\nFurthermore, specific functions have been implemented to access the various components of the structure, in particular they are:\r\n\r\n```\r\nuri-parse:          string → uri-structure\r\nuri-scheme:         uri-structure → string\r\nuri-userinfo:       uri-structure → string\r\nuri-host:           uri-structure → string\r\nuri-port:           uri-structure → integer\r\nuri-path:           uri-structure → string\r\nuri-query:          uri-structure → string\r\nuri-fragment:       uri-structure → string\r\nuri-display:        uri-structure \u0026optional stream → T\r\n```\r\n\r\nExamples:\r\n\r\n```Lisp\r\n(defparameter uri (uri-parse \"http://facebook.com\"))\r\nURI\r\n```\r\n\r\n```Lisp\r\n(uri-scheme uri))\r\n\"http\"\r\n```\r\n\r\n```Lisp\r\n(uri-host uri))\r\n\"facebook.com\"\r\n```\r\n\r\n```Lisp\r\n(uri-query uri))\r\nNIL\r\n```\r\n\r\n```Lisp\r\n(uri-display uri))\r\nScheme:     \"http\"\r\nUserinfo:   NIL\r\nHost:       \"facebook.com\"\r\nPort:       80\r\nPath:       NIL\r\nQuery:      NIL\r\nFragment:   NIL\r\n```\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrancescobarbieri%2Furi-parser","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrancescobarbieri%2Furi-parser","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrancescobarbieri%2Furi-parser/lists"}