module Stratego-xml
imports xml StrategoMix[StrategoHost]
hiddens
  context-free start-symbols Module[[StrategoHost]]

exports

  %% Term Quotation
  context-free syntax
    "%>" Document "<%" -> Term[[StrategoHost]]     {cons("ToTerm"), avoid}

    "@>" Attribute  "<@" -> Term[[StrategoHost]]   {cons("ToTerm"), prefer}
    "@>" Attribute* "<@" -> Term[[StrategoHost]]   {cons("ToTerm")}

  syntax
    "%>" <Content-CF>  "<%" -> <Term[[StrategoHost]]-CF> {cons("ToTerm"), prefer}
    "%>" <Content-CF>* "<%" -> <Term[[StrategoHost]]-CF> {cons("ToTerm")}

    "%>" <Content-CF>* "<%" <LAYOUT?-CF> "::" <LAYOUT?-CF> "*" -> <Term[[StrategoHost]]-CF> {cons("ToTerm")}

  %% Congruence Quotation
  context-free syntax  
    "%>" Document "<%" -> Strategy[[StrategoHost]] {cons("ToStrategy"), avoid}

  syntax
    "%>" <Content-CF>  "<%" -> <Strategy[[StrategoHost]]-CF> {cons("ToStrategy"), prefer}
    "%>" <Content-CF>* "<%" -> <Strategy[[StrategoHost]]-CF> {cons("ToStrategy")}

  %% Content Anti Quotation
  context-free syntax

    "<%=" Term[[StrategoHost]]                 "%>" -> Content {cons("FromTerm")}
    "<%=" Term[[StrategoHost]] "::" "content"  "%>" -> Content {cons("FromTerm")}

    "<%"  Strategy[[StrategoHost]]                 "%>" -> Content {cons("FromApp")}
    "<%"  Strategy[[StrategoHost]] "::" "content"  "%>" -> Content {cons("FromApp")}

  syntax

    "<%=" <LAYOUT?-CF> <Term[[StrategoHost]]-CF>    <LAYOUT?-CF> "::" <LAYOUT?-CF> "*"        <LAYOUT?-CF> "%>" -> <Content-CF>* {cons("FromTerm")}
    "<%" <LAYOUT?-CF> <Strategy[[StrategoHost]]-CF> <LAYOUT?-CF> "::" <LAYOUT?-CF> "*"        <LAYOUT?-CF> "%>" -> <Content-CF>* {cons("FromApp")}
    "<%" <LAYOUT?-CF> <Strategy[[StrategoHost]]-CF> <LAYOUT?-CF> "::" <LAYOUT?-CF> "content*" <LAYOUT?-CF> "%>" -> <Content-CF>* {cons("FromApp")}

  %% Character Data Anti Quotation
  syntax

    "<%" <LAYOUT?-CF> <Strategy[[StrategoHost]]-CF> <LAYOUT?-CF> "::" <LAYOUT?-CF> "cdata" <LAYOUT?-CF> "%>"
      -> FooCharDataText {cons("FromApp")}

    "<%=" <LAYOUT?-CF> <Term[[StrategoHost]]-CF> <LAYOUT?-CF> "::" <LAYOUT?-CF> "cdata" <LAYOUT?-CF> "%>"
      -> FooCharDataText {cons("FromTerm")}

  %% Anti quotation for attributes
  context-free syntax

    "<@"  Strategy[[StrategoHost]]          "@>" -> Attribute  {cons("FromApp")}
    "<@"  Strategy[[StrategoHost]] "::" "*" "@>" -> Attribute* {cons("FromApp")}

    "<@="  Term[[StrategoHost]]          "@>" -> Attribute  {cons("FromTerm")}
    "<@="  Term[[StrategoHost]] "::" "*" "@>" -> Attribute* {cons("FromTerm")}

  syntax
    %% obsolete
    "<"  <Term[[StrategoHost]]-CF> -> <Attribute-CF>  {cons("FromTerm")}
    "<*" <Term[[StrategoHost]]-CF> -> <Attribute*-CF> {cons("FromTerm")}

  %% Attribute Value Anti Quotation
  context-free syntax

    "<@"  Strategy[[StrategoHost]] "@>" -> AttValue   {cons("FromApp")}
    "<@=" Term[[StrategoHost]]     "@>" -> AttValue   {cons("FromTerm")}

    %% obsolete
    "<%"  Strategy[[StrategoHost]] "%>" -> AttValue   {cons("FromApp")}
    "<%=" Term[[StrategoHost]]     "%>" -> AttValue   {cons("FromTerm")}

  %% Attribute Character Data Anti Quotation
  syntax

    "<%" <LAYOUT?-CF> <Strategy[[StrategoHost]]-CF> <LAYOUT?-CF> "%>"
      -> FooDoubleQuotedText {cons("FromApp")}

    "<%=" <LAYOUT?-CF> <Term[[StrategoHost]]-CF> <LAYOUT?-CF> "%>"
      -> FooDoubleQuotedText {cons("FromTerm")}

    "<%" <LAYOUT?-CF> <Strategy[[StrategoHost]]-CF> <LAYOUT?-CF> "::" <LAYOUT?-CF> "cdata" <LAYOUT?-CF> "%>"
      -> FooDoubleQuotedText {cons("FromApp")}

    "<" <Term[[StrategoHost]]-CF> -> FooDoubleQuotedText {cons("FromTerm")}

  %% Anti quotation for element. This anti quotation is only used if anti quotation
  %% is used for the root element of an document.
  context-free syntax

    "<%" Strategy[[StrategoHost]] "%>" -> Element {cons("FromApp"), avoid}

  %% Name Anti-Quotation
  syntax

    "<"   <Term[[StrategoHost]]-CF> -> <NCName-CF> {cons("FromTerm")}
    "~n:" <Term[[StrategoHost]]-CF> -> <NCName-CF> {cons("FromTerm")}

  variables
    "@"    [0-9]*     -> Attribute
    "att"  [0-9]*     -> Attribute
    "@"    [0-9]* "*" -> Attribute*
    "att"  [0-9]* "*" -> Attribute*
    "atts" [0-9]*     -> Attribute*
    "qn"   [0-9]*     -> QName {prefer}
