module Stratego-Sugar-DynamicRules
imports
  Stratego-Core-Identifiers
  Stratego-Sugar-Strategies
  Stratego-Sugar-Rules

exports
 
  sorts ScopeLabels
  context-free syntax

    "{|" ScopeLabels ":" Strategy "|}" -> Strategy {cons("DynRuleScope")}

    {DynRuleScopeId ","}*   -> ScopeLabels
    "~" Term		    -> ScopeLabels {cons("ScopeLabels")}

  sorts DynRuleDef DynRuleId DynRuleScopeId RuleDec
  context-free syntax

    "rules" "(" DynRuleDef* ")" -> Strategy {cons("GenDynRules")}

    Id "+" Term                 -> DynRuleDef {cons("AddScopeLabel")} 
    DynRuleId ":-"  Term        -> DynRuleDef {cons("UndefineDynRule")}
    DynRuleId ":"   Rule        -> DynRuleDef {cons("SetDynRule")}
    DynRuleId ":+"  Rule        -> DynRuleDef {cons("AddDynRule")}
    DynRuleId ":"   Term        -> DynRuleDef {cons("SetDynRuleMatch")}

    DynRuleId ":="  Term        -> DynRuleDef {cons("DynRuleAssign")}
    DynRuleId ":+="  Term       -> DynRuleDef {cons("DynRuleAssignAdd")}

    DynRuleId ":"   Rule "depends" "on" Term -> DynRuleDef {cons("SetDynRuleDepends")}

    RuleDec "." Term            -> DynRuleId {cons("LabeledDynRuleId")}
    RuleDec "+" Term            -> DynRuleId {cons("AddLabelDynRuleId")}
    RuleDec                     -> DynRuleId {cons("DynRuleId")}

    Id "." Term                 -> DynRuleScopeId {cons("LabeledDynRuleScopeId")}
    Id                          -> DynRuleScopeId {cons("DynRuleScopeId")}

  context-free syntax

    Id                          -> RuleDec {cons("RDecNoArgs")}
    Id "(" {Typedid ","}* ")"   -> RuleDec {cons("RDec")}
    Id "(" {Typedid ","}* 
       "|" {Typedid ","}* ")"   -> RuleDec {cons("RDecT")}

  sorts RuleNames
  context-free syntax
    {Id ","}*				  -> RuleNames
    "~" Term				  -> RuleNames {cons("RuleNames")}

    "/" RuleNames "\\*" Strategy          -> Strategy {cons("DynRuleIntersectFix")}

  syntax
    %% no space after RuleNames
    "\\" <LAYOUT?-CF> <RuleNames-CF> "/*" <LAYOUT?-CF> <Strategy-CF>
      -> <Strategy-CF> {cons("DynRuleUnionFix")}

    %% 1 space after RuleNames
    "\\" <LAYOUT?-CF> <RuleNames-CF> " /*" <LAYOUT?-CF> <Strategy-CF>
      -> <Strategy-CF> {cons("DynRuleUnionFix")}

    %% no space after RuleNames
    "/"  <LAYOUT?-CF> <RuleNames-CF> <LAYOUT?-CF> "\\"
        <LAYOUT?-CF> <RuleNames-CF> "/*" <LAYOUT?-CF> <Strategy-CF>
      -> <Strategy-CF> {cons("DynRuleIntersectUnionFix")}

    %% 1 space after RuleNames
    "/"  <LAYOUT?-CF> <RuleNames-CF> <LAYOUT?-CF> "\\"
        <LAYOUT?-CF> <RuleNames-CF> " /*" <LAYOUT?-CF> <Strategy-CF>
      -> <Strategy-CF> {cons("DynRuleIntersectUnionFix")}


  context-free syntax
    Strategy "/" RuleNames"\\" Strategy  -> Strategy {cons("DynRuleIntersect"),right}
    Strategy "\\" RuleNames "/" Strategy  -> Strategy {cons("DynRuleUnion"),right}

    Strategy "/" RuleNames "\\" 
                 RuleNames "/"  Strategy  -> Strategy {cons("DynRuleIntersectUnion"),right}

  priorities
    <StrategyAngle-CF> <LAYOUT?-CF> <Term-CF> -> <Strategy-CF> {cons("BA")}
  > {

    %% no space after RuleNames
    "\\" <LAYOUT?-CF> <RuleNames-CF> "/*" <LAYOUT?-CF> <Strategy-CF>
      -> <Strategy-CF> {cons("DynRuleUnionFix")}

    %% 1 space after RuleNames
    "\\" <LAYOUT?-CF> <RuleNames-CF> " /*" <LAYOUT?-CF> <Strategy-CF>
      -> <Strategy-CF> {cons("DynRuleUnionFix")}

    %% no space after RuleNames
    "/"  <LAYOUT?-CF> <RuleNames-CF> <LAYOUT?-CF> "\\"
        <LAYOUT?-CF> <RuleNames-CF> "/*" <LAYOUT?-CF> <Strategy-CF>
      -> <Strategy-CF> {cons("DynRuleIntersectUnionFix")}

    %% 1 space after RuleNames
    "/"  <LAYOUT?-CF> <RuleNames-CF> <LAYOUT?-CF> "\\"
        <LAYOUT?-CF> <RuleNames-CF> " /*" <LAYOUT?-CF> <Strategy-CF>
      -> <Strategy-CF> {cons("DynRuleIntersectUnionFix")}

    }
  > <Strategy-CF> <LAYOUT?-CF> "=>" <LAYOUT?-CF> <Term-CF> -> <Strategy-CF> {cons("AM")}

  context-free priorities
    StrategyAngle Term 		          -> Strategy {cons("BA")}
  > "/" RuleNames "\\*" Strategy          -> Strategy {cons("DynRuleIntersectFix")}
  > Strategy "=>" Term 		  	  -> Strategy {cons("AM")}
  > Strategy "/" RuleNames "\\" Strategy  -> Strategy {cons("DynRuleIntersect"),right}
  > Strategy "\\" RuleNames "/" Strategy  -> Strategy {cons("DynRuleUnion"),right}
  > Strategy "/" RuleNames "\\" 
                 RuleNames "/"  Strategy  -> Strategy {cons("DynRuleIntersectUnion"),right}
  > Strategy ";" Strategy 		  -> Strategy {cons("Seq"),right}

