Permalink
Browse files

Added URI example

  • Loading branch information...
1 parent 2d495cc commit ace8c8261317cc7b3f921df22ac2ed49b605ffc8 @mjackson committed Mar 18, 2011
Showing with 237 additions and 0 deletions.
  1. +179 −0 examples/uri.citrus
  2. +58 −0 examples/uri_test.rb
View
179 examples/uri.citrus
@@ -0,0 +1,179 @@
+require 'ipv4address'
+require 'ipv6address'
+
+# A grammar for URI's that conforms to RFC 3986.
+grammar UniformResourceIdentifier
+ include IPv4Address
+ include IPv6Address
+
+ # URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+ rule URI
+ scheme ":" hier-part ("?" query)? ("#" fragment)?
+ end
+
+ # hier-part = "//" authority path-abempty
+ # / path-absolute
+ # / path-rootless
+ # / path-empty
+ rule hier-part
+ "//" authority path-abempty | path-absolute | path-rootless | path-empty
+ end
+
+ # URI-reference = URI / relative-ref
+ rule URI-reference
+ URI | relative-ref
+ end
+
+ # absolute-URI = scheme ":" hier-part [ "?" query ]
+ rule absolute-URI
+ scheme ":" hier-part ("?" query)?
+ end
+
+ # relative-ref = relative-part [ "?" query ] [ "#" fragment ]
+ rule relative-ref
+ relative-part ("?" query)? ("#" fragment)?
+ end
+
+ # relative-part = "//" authority path-abempty
+ # / path-absolute
+ # / path-noscheme
+ # / path-empty
+ rule relative-part
+ "//" authority path-abempty | path-absolute | path-noscheme | path-empty
+ end
+
+ # scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+ rule scheme
+ ALPHA (ALPHA | DIGIT | "+" | "-" | ".")*
+ end
+
+ # authority = [ userinfo "@" ] host [ ":" port ]
+ rule authority
+ (userinfo "@")? host (":" port)?
+ end
+
+ # userinfo = *( unreserved / pct-encoded / sub-delims / ":" )
+ rule userinfo
+ (unreserved | pct-encoded | sub-delims | ":")*
+ end
+
+ # host = IP-literal / IPv4address / reg-name
+ rule host
+ IP-literal | IPv4address | reg-name
+ end
+
+ # port = *DIGIT
+ rule port
+ DIGIT*
+ end
+
+ # IP-literal = "[" ( IPv6address / IPvFuture ) "]"
+ rule IP-literal
+ "[" (IPv6address | IPvFuture) "]"
+ end
+
+ # IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
+ rule IPvFuture
+ "v" HEXDIG+ "." (unreserved | sub-delims | ":")+
+ end
+
+ # reg-name = *( unreserved / pct-encoded / sub-delims )
+ rule reg-name
+ (unreserved | pct-encoded | sub-delims)*
+ end
+
+ # path = path-abempty ; begins with "/" or is empty
+ # / path-absolute ; begins with "/" but not "//"
+ # / path-noscheme ; begins with a non-colon segment
+ # / path-rootless ; begins with a segment
+ # / path-empty ; zero characters
+ rule path
+ path-abempty | path-absolute | path-noscheme | path-rootless | path-empty
+ end
+
+ # path-abempty = *( "/" segment )
+ rule path-abempty
+ ("/" segment)*
+ end
+
+ # path-absolute = "/" [ segment-nz *( "/" segment ) ]
+ rule path-absolute
+ "/" (segment-nz ("/" segment)*)?
+ end
+
+ # path-noscheme = segment-nz-nc *( "/" segment )
+ rule path-noscheme
+ segment-nz-nc ("/" segment)*
+ end
+
+ # path-rootless = segment-nz *( "/" segment )
+ rule path-rootless
+ segment-nz ("/" segment)*
+ end
+
+ # path-empty = 0<pchar>
+ rule path-empty
+ ''
+ end
+
+ # segment = *pchar
+ rule segment
+ pchar*
+ end
+
+ # segment-nz = 1*pchar
+ rule segment-nz
+ pchar 1*
+ end
+
+ # segment-nz-nc = 1*( unreserved / pct-encoded / sub-delims / "@" )
+ # ; non-zero-length segment without any colon ":"
+ rule segment-nz-nc
+ (unreserved | pct-encoded | sub-delims | "@") 1*
+ end
+
+ # pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
+ rule pchar
+ unreserved | pct-encoded | sub-delims | ":" | "@"
+ end
+
+ # query = *( pchar / "/" / "?" )
+ rule query
+ (pchar | "/" | "?")*
+ end
+
+ # fragment = *( pchar / "/" / "?" )
+ rule fragment
+ (pchar | "/" | "?")*
+ end
+
+ # pct-encoded = "%" HEXDIG HEXDIG
+ rule pct-encoded
+ "%" HEXDIG HEXDIG
+ end
+
+ # unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
+ rule unreserved
+ ALPHA | DIGIT | "-" | "." | "_" | "~"
+ end
+
+ # reserved = gen-delims / sub-delims
+ rule reserved
+ gen-delims | sub-delims
+ end
+
+ # gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@"
+ rule gen-delims
+ ":" | "/" | "?" | "#" | "[" | "]" | "@"
+ end
+
+ # sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
+ # / "*" / "+" / "," / ";" / "="
+ rule sub-delims
+ "!" | "$" | "&" | "'" | "(" | ")" | "*" | "+" | "," | ";" | "="
+ end
+
+ rule ALPHA
+ [a-zA-Z]
+ end
+end
View
58 examples/uri_test.rb
@@ -0,0 +1,58 @@
+examples = File.expand_path('..', __FILE__)
+$LOAD_PATH.unshift(examples) unless $LOAD_PATH.include?(examples)
+
+# This file contains a suite of tests for the UniformResourceIdentifier grammar
+# found in uri.citrus.
+
+require 'citrus'
+Citrus.require 'uri'
+require 'test/unit'
+
+class UniformResourceIdentifierTest < Test::Unit::TestCase
+ U = UniformResourceIdentifier
+
+ def test_uri
+ match = U.parse('http://www.example.com')
+ assert(match)
+ end
+
+ def test_uri_with_query_string
+ match = U.parse('http://www.example.com/?q=some+query')
+ assert(match)
+ end
+
+ def test_authority
+ match = U.parse('michael@', :root => :authority)
+ assert(match)
+ end
+
+ def test_host
+ match = U.parse('127.0.0.1', :root => :host)
+ assert(match)
+
+ match = U.parse('[12AD:34FC:A453:1922::]', :root => :host)
+ assert(match)
+ end
+
+ def test_userinfo
+ match = U.parse('michael', :root => :userinfo)
+ assert(match)
+
+ assert_raise(Citrus::ParseError) do
+ U.parse('michael@', :root => :userinfo)
+ end
+ end
+
+ def test_ipliteral
+ match = U.parse('[12AD:34FC:A453:1922::]', :root => :'IP-literal')
+ assert(match)
+ end
+
+ def test_ipvfuture
+ match = U.parse('v1.123:456:789', :root => :IPvFuture)
+ assert(match)
+
+ match = U.parse('v5A.ABCD:1234', :root => :IPvFuture)
+ assert(match)
+ end
+end

0 comments on commit ace8c82

Please sign in to comment.