definition
module xml-attribute
imports xml-names xml-text

exports

  context-free syntax

    QName "=" AttValue -> Attribute {cons("Attribute")}

  syntax

    "\"" DoubleQuotedPart* "\"" -> <AttValue-CF> {cons("DoubleQuoted")}
    "'"  SingleQuotedPart* "'" -> <AttValue-CF> {cons("SingleQuoted")}

    FooDoubleQuotedText -> DoubleQuotedPart {cons("Literal")}
    FooSingleQuotedText -> SingleQuotedPart {cons("Literal")}

    <DoubleQuotedText-LEX> -> FooDoubleQuotedText
    <SingleQuotedText-LEX> -> FooSingleQuotedText

    <Ref-CF> -> DoubleQuotedPart
    <Ref-CF> -> SingleQuotedPart

  lexical syntax

    ~[\&\<\"]+ -> DoubleQuotedText
    ~[\&\<\']+ -> SingleQuotedText

  lexical restrictions

    DoubleQuotedText -/- ~[\&\<\"]
    SingleQuotedText -/- ~[\&\<\']

module xml-text
exports

  lexical syntax
    [\ \t\n\13] -> WhiteSpaceChar

  syntax

    CharDataPart+ -> CharData {cons("Text")}

    FooCharDataText -> CharDataPart {cons("Literal")}
    <Ref-CF> -> CharDataPart
    "<![CDATA[" <CData-LEX> "]]>" -> CharDataPart {cons("CDATASection")}

    <CharDataText-LEX> -> FooCharDataText

  lexical syntax

    ~[\<\&]+ -> CharDataText

  lexical restrictions

    CharDataText -/- ~[\<\&]

  syntax

    "&#"  <NatConst-LEX> ";" -> <DecCharRef-CF> {cons("DecCharRef")}
    "&#x" <HexConst-LEX> ";" -> <HexCharRef-CF> {cons("HexCharRef")}
    "&"   <NCName-LEX>   ";" -> <EntityRef-CF>  {cons("EntityRef")}

  context-free syntax

    DecCharRef -> CharRef
    HexCharRef -> CharRef
    CharRef    -> Ref
    EntityRef  -> Ref

  lexical syntax

    [0-9]+       -> NatConst
    [0-9a-fA-F]+ -> HexConst

  lexical syntax

    (~[\]] | CloseBracket | TwoCloseBrackets )* -> CData

    "]"  -> CloseBracket
    "]]" -> TwoCloseBrackets

  lexical restrictions

    CloseBracket     -/- [\]]
    TwoCloseBrackets -/- [\>]
    CharDataToken    -/- ~[\<\&\]\ \t\n\13]

module xml-external

exports
  context-free syntax
    "SYSTEM" SystemLit           -> ExternalID {cons("SystemExternalID")}
    "PUBLIC" PublicLit SystemLit -> ExternalID {cons("PublicExternalID")}
    "PUBLIC" PublicLit           -> PublicID   {cons("PublicID")  }

  lexical syntax

    "\"" ~[\"]* "\""     -> SystemLit
    "'"  ~[\']* "'"     -> SystemLit
    "\"" PubIDChar* "\"" -> PublicLit
    "'"  PubIDChar* "'" -> PublicLit

    [a-zA-Z0-9] -> PubIDChar
    [\ \n\13\-\'\(\)\+\,\.\/\:\=\?\;\!\*\#\@\$\_\%] -> PubIDChar


module xml-pi
imports xml-names

exports
  context-free syntax
    "<?" PITarget PIChars "?>" -> PI {cons("PI")}

  lexical syntax
    NCName -> PITarget
    [Xx][Mm][Ll] -> PITarget {reject}

    ( ~[\?\>] | ( [\?] ~[\>] ) )* -> PIChars



module xml-prolog
imports xml-whitespace xml-names xml-comments xml-pi xml-external

exports
  context-free syntax

    XMLDecl? Misc* DocTypePrologue? -> Prologue {cons("Prologue")}
    Misc* -> Epilogue {cons("Epilogue")}
    Comment -> Misc {cons("Comment")}
    PI      -> Misc

  context-free syntax

    "<?xml" VersionInfo EncodingDecl? StandaloneDecl? "?>" -> XMLDecl {cons("XMLDecl")}

    "standalone" "=" StandaloneValue -> StandaloneDecl {cons("StandaloneDecl")}
    "version"    "=" VersionValue    -> VersionInfo    {cons("VersionDecl")}
    "encoding"   "=" EncodingValue   -> EncodingDecl   {cons("EncodingDecl")}

    "\"" YesNo "\"" -> StandaloneValue {cons("Standalone")}
    "'"  YesNo "'" -> StandaloneValue {cons("StandaloneSingle")}

    "\"" EncodingName "\"" -> EncodingValue {cons("Encoding")}
    "'"  EncodingName "'" -> EncodingValue {cons("EncodingSingle")}

    "\"" VersionNum "\"" -> VersionValue {cons("Version")}
    "'"  VersionNum "'"  -> VersionValue {cons("VersionSingle")}

  context-free syntax

    DocTypeDecl Misc* -> DocTypePrologue {cons("DocTypePrologue")}

    "<!DOCTYPE" QName ExternalID ">" -> DocTypeDecl {cons("DocTypeDecl")}

  lexical syntax

    [a-zA-Z0-9\_\.\:\-]+ -> VersionNum
    [A-Za-z] [A-Za-z0-9\.\_\-]* -> EncodingName

    "yes" -> YesNo
    "no"  -> YesNo


module xml-document
imports xml-prolog xml-whitespace xml-names xml-comments xml-text xml-attribute

exports
  sorts Document Element Content
  context-free syntax

    Prologue Element Epilogue -> Document {cons("Document")}

    "<" QName Attribute* "/>" -> Element {cons("EmptyElement")}

    Element -> Content
    Comment -> Content {cons("Comment")}
    PI      -> Content
  syntax

    CharData      -> <Content-CF>
    CDataSection  -> <Content-CF>

    "<"
    <LAYOUT?-CF> <QName-CF> <LAYOUT?-CF> <Attribute*-CF> <LAYOUT?-CF>
      ">" <Content-CF>* "</"
    <LAYOUT?-CF> <QName-CF> <LAYOUT?-CF>
    ">"  -> <Element-CF> {cons("Element")}

module xml-names

exports
  context-free syntax
    Qualifier? NCName -> QName     {cons("QName")}
    NCName ":"        -> Qualifier {cons("Prefix")}

  lexical syntax
    [A-Za-z\_] [A-Za-z0-9\.\-\_]* -> NCName

  lexical restrictions
    NCName -/- [A-Za-z0-9\.\-\_]

module xml-comments

exports
  lexical syntax
    "<!--" (~[\-] | Dash)* "-->" -> Comment
    "-" -> Dash

  lexical restrictions

    Dash -/- [\-]

module xml-whitespace

exports
  lexical syntax
    [\ \t\n\13] -> LAYOUT

  context-free restrictions
    LAYOUT? -/- [\ \t\n\13]

module xml-lexical
imports xml-whitespace xml-comments xml-names



module xml
imports xml-lexical xml-document
hiddens
  context-free start-symbols Document Content Attribute