Platinum Partner

RELAX NG Long Grammar

I believe both this Relax-NG grammar and the shorter one were both derived from the specification, however, IIRC, there were two grammars in the spec, this one was designed to make it easier to convert to XML.


#!/usr/bin/env tt
# Author::    Daniel Brumbaugh Keeney (http://rubyforge.org/users/db-keen)
# Copyright:: 2008 Daniel Brumbaugh Keeney
# License::   GPLv3+
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# 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, see .

# http://relaxng.org/compact-20021121.html#formal-syntax
# http://relaxng.org/tutorial-20011203.html
grammar RelaxNGfromSpec

  include XmlNameSpaces

  rule top_level
    decl* top_level_body
  end

  rule decl
    "namespace" namespace_prefix  "="  namespace_uri_literal
  / "default"  "namespace"  namespace_prefix?  "="  namespace_uri_literal
  / "datatypes"  datatype_prefix:identifier_or_keyword  "="  literal
  end

  rule namespace_prefix
    !( "xmlns" space ) identifier_or_keyword
  end

  rule namespace_uri_literal
    literal /  "inherit"
  end

  rule top_level_body
    pattern / grammar { "" x "" }
  end

  rule grammar
    member*
  end

  rule member
    annotated_component / annotation_element_not_keyword
  end

  rule annotated_component
    annotations component { applyAnnotations(x, y) }
  end

  rule component
    start / define / include / div
  end

  rule start
    "start" assign_op  pattern
        {  y  }
  end

  rule define
    identifier assign_op pattern
        {  z  }
  end

  rule assign_op
      "="
    / "|=" { attribute(name("", "combine"), "choice") }
    / "&=" { attribute(name("", "combine"), "interleave") }
  end

  rule include
    "include"  any_uri_literal  opt_inherit optIncludeBody
        {  z  }
  end

  rule any_uri_literal
    literal
  end

  rule opt_inherit
    ε
        { makeNsAttribute(lookupDefault(environment)) }
    /  "inherit"  "="  identifier_or_keyword
        { makeNsAttribute(lookupPrefix(environment, x)) }
  end

  rule optIncludeBody
    ( "{"  includeBody  "}" )?
  end

  rule includeBody
    ( annotated_include_component / annotation_element_not_keyword )*
  end

  rule annotated_include_component
    annotations include_component:( start / define / include_div ) { applyAnnotations(x, y) }
  end

  rule div
    "div" "{" grammar "}" { 
x
} end rule include_div "div" "{" includeBody "}" {
x
} end rule pattern particle ( "|" particle )+ { applyAnnotations(anno, x ) } / particle ( "," particle )+ { applyAnnotations(anno, x ) } / particle ( "&" particle )+ { applyAnnotations(anno, x ) } / annotated_data_except { applyAnnotationsGroup(anno, x) } / particle end rule particle annotated_primary { applyAnnotationsGroup(anno, x) } / repeatedPrimary follow_annotations { (applyAnnotations(anno, x), y) } end # !TODO: run benchmarks to see if it's better to handle these in # the grammar, or via case node.text_value rule repeatedPrimary # annotated_primary "*" { x } #/ annotated_primary "+" { x } #/ annotated_primary "?" { x } annotated_primary [*+?] end rule annotated_primary lead_annotated_primary follow_annotations end rule annotated_data_except lead_annotated_data_except follow_annotations end rule lead_annotated_data_except annotations data_except { applyAnnotations(x, y) } end rule lead_annotated_primary annotations primary { applyAnnotations(x, y) } / annotations "(" pattern ")" end rule primary "element" name_class "{" pattern "}" { x y } / "attribute" name_class "{" pattern "}" { x y } / "mixed" "{" pattern "}" { x } / "list" "{" pattern "}" { x } / datatype_name optParams { y } / datatype_name datatype_value { y } / datatype_value { x } / "empty" { } / "notAllowed" { } / "empty" { } / ref { } / "parent" ref { } / "grammar" "{" grammar "}" { x } / "external" any_uri_literal opt_inherit { } end rule data_except datatype_name optParams "-" lead_annotated_primary { y z } end rule ref identifier end rule datatype_name CName { datatypeAttributes(lookupDatatypePrefix(environment, prefix(x)), localPart(x)) } / "string" { datatypeAttributes("", "string") } / "token" { datatypeAttributes("", "token") } end rule datatype_value literal end rule optParams ( "{" param+ "}" )? end rule param annotations identifier_or_keyword "=" literal { applyAnnotations(x, z ) } end rule name_class inner_name_class end rule inner_name_class annotated_simple_name_class { applyAnnotationsChoice(anno, x) } / name_class_choice { applyAnnotations(anno, x ) } / annotated_except_name_class { applyAnnotationsChoice(anno, x) } end rule name_class_choice annotated_simple_name_class "|" annotated_simple_name_class / annotated_simple_name_class "|" name_class_choice end rule annotated_except_name_class lead_annotated_except_name_class follow_annotations end rule lead_annotated_except_name_class annotations except_name_class { applyAnnotations(x, y) } end rule annotated_simple_name_class lead_annotated_simple_name_class follow_annotations end rule lead_annotated_simple_name_class annotations simple_name_class { applyAnnotations(x, y) } / annotations "(" inner_name_class(anno := x)y ")" end rule except_name_class nsName "-" lead_annotated_simple_name_class { y } / "*" "-" lead_annotated_simple_name_class { x } end rule simple_name_class identifier_or_keyword { x } / CName { localPart(x) } / nsName { } / "*" { } end rule follow_annotations ( ">>" annotation_element )* end rule annotations documentations ( "[" annotation_attributes annotation_element* "]" )? end rule annotation_attributes ε / foreign_attribute_name:prefixed_name "=" literal annotation_attributes { (attribute(x, y), z) } end rule annotation_element foreign_element_name annotation_attributes_content { element(environment, x, y) } end rule foreign_element_name identifier_or_keyword { name("", x) } / prefixed_name end rule annotation_element_not_keyword foreign_element_nameNotKeyword annotation_attributes_content { element(environment, x, y) } end rule foreign_element_nameNotKeyword identifier { name("", x) } / prefixed_name end rule annotation_attributes_content "[" nested_annotation_attributes annotationContent "]" end rule nested_annotation_attributes ε / anyAttributeName "=" literal nested_annotation_attributes { (attribute(x, y), z) } end rule anyAttributeName identifier_or_keyword { name("", x) } / prefixed_name end rule annotationContent ( nested_annotation_element / literal )* end rule nested_annotation_element any_element_name annotation_attributes_content { element(environment, x, y) } end rule any_element_name identifier_or_keyword / prefixed_name end rule prefixed_name CName { name(lookupPrefix(environment, prefix(x)), localPart(x)) } end rule documentations documentation* { (element(environment, documentationElementName(), text(x)), y) } end rule identifier_or_keyword NCName / keyword / "\" NCName end rule keyword "attribute" / "default" / "datatypes" / "div" / "element" / "empty" / "external" / "grammar" / "include" / "inherit" / "list" / "mixed" / "namespace" / "notAllowed" / "parent" / "start" / "string" / "text" / "token" end rule literal literal_segment ( "~" literal )? end rule escape_sequence "\" 'x'+ '{' code:[0123456789ABCDEFabcdef]+ '}' end rule identifier NCName - keyword / "\" NCName end rule CName NCName ":" NCName { qName(x, y) } end rule nsName NCName ":*" end rule literal_segment '"' contents:( !["\n] . )* '"' / "'" contents:( ['\n] . )* "'" / '"""' contents:( !'"""' . )* '"""' / "'''" contents:( !"'''" . )* "'''" end # !CHECK: is this right? rule documentation #documentation_line / documentation documentation_continuation documentation_line documentation_continuation* end rule documentation_line "##" '#'* ' '? contents:rest_of_line end rule documentation_continuation [\n\x0A] indent:[\x09\x20]* documentation_line end rule rest_of_line !( [\n\x0A]* . ) end rule separator [\x09\x0A\x20\n] / "#" ( ![\n\x0A#] . rest_of_line )? end end
{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}