definition
module Stratego-Core-Modules
imports
  Stratego-Core-Identifiers
  Stratego-Core-Strategies
  Stratego-Core-Signatures

exports 
  sorts Module
  context-free syntax
    "module" ModName Decl* 	 -> Module {cons("Module")}
    "specification" Decl*	 -> Module {cons("Specification")}

  sorts Decl 
  context-free syntax
    "imports" ImportModName* 	-> Decl {cons("Imports")}
    "strategies" Def* 		-> Decl {cons("Strategies")}
    "signature" Sdecl*  	-> Decl {cons("Signature")}

  sorts ImportModName
  context-free syntax
    ModName              -> ImportModName {cons("Import")}
  syntax
    <ModName-CF> "/" "-" -> <ImportModName-CF> {cons("ImportWildcard")}

module Stratego-Core-Strategies
imports
  Stratego-Core-Terms
  Stratego-Core-Constants
  Stratego-Core-Signatures

exports
  sorts Def
  context-free syntax
    StrategyDef					 -> Def 
    Id						 -> SVar {cons("SVar")}
    "let" Def* "in" Strategy "end"		 -> Strategy {cons("Let")}
    SVar "(" {Strategy ","}* "|" {Term ","}* ")" -> Strategy {cons("CallT")}

    "call" "(" Term "|" {Strategy ","}* "|" {Term ","}* ")" -> Strategy {cons("CallDynamic")}


  sorts StrategyDef
  context-free syntax
    Id "(" {Typedid ","}* 
       "|" {Typedid ","}* ")" "=" Strategy -> StrategyDef {cons("SDefT")}

    "external"
    Id "(" {Typedid ","}* 
       "|" {Typedid ","}* ")" "=" Strategy -> StrategyDef {cons("ExtSDefInl")}

    "external"
    Id "(" {Typedid ","}* 
       "|" {Typedid ","}* ")"		   -> StrategyDef {cons("ExtSDef")}


  sorts Typedid
  context-free syntax
    ID ":" Type 			  -> Typedid {cons("VarDec")}


  sorts Strategy SVar StrategyParen StrategyMid 
  context-free syntax
    "(" Strategy ")"			  -> StrategyParen {cons("ParenStrat")}

    "fail" 				  -> Strategy {cons("Fail")}
    "id" 				  -> Strategy {cons("Id")}

    %% Match and build

    "?" Term 				  -> Strategy {cons("Match")}
    "!" Term 				  -> Strategy {cons("Build")}
    "{" {ID ","}* ":" Strategy "}" 	  -> Strategy {cons("Scope")}

    %% Combinators

    Strategy ";" Strategy 		  -> Strategy {cons("Seq"),right}
    Strategy "<" StrategyMid 
             "+" Strategy 		  -> Strategy {cons("GuardedLChoice"),right}
    Strategy 				  -> StrategyMid

    %% Primitives

    "prim" "(" String "," {Strategy ","}* "|" {Term ","}*")"  -> Strategy {cons("PrimT")}

    %% Traversal

    "some" "(" Strategy ")" 		  -> Strategy {cons("Some")}
    "one" "(" Strategy ")" 		  -> Strategy {cons("One")}
    "all" "(" Strategy ")" 		  -> Strategy {cons("All")}

  %% Priorities

  context-free priorities
    { "!" Term 				  -> Strategy {cons("Build")}
      "?" Term 				  -> Strategy {cons("Match")}
    }
  > Strategy ";" Strategy 		  -> Strategy {cons("Seq"),right}
  > {right: 
     Strategy "<" StrategyMid 
              "+" Strategy 		  -> Strategy {cons("GuardedLChoice"),right}
    }

  context-free syntax
    "import-term" "(" ModName ")" -> Strategy {cons("ImportTerm")}

module Stratego-Core-Terms
imports
  Stratego-Core-Identifiers
  Stratego-Core-Constants

exports
  sorts ID Var Wld
  context-free syntax
    Id 				-> Var  {cons("Var")}
    Id				-> ID
    %% ":" Var                  -> Var  {cons("SeqVar")}

  sorts Term PreTerm
  context-free syntax
    Var 			 -> PreTerm 
    Var 			 -> Term {prefer}

    "_" 			 -> Wld {cons("Wld")}
    Wld 			 -> PreTerm
    Wld 			 -> Term {prefer}

    Int 			 -> PreTerm {cons("Int")}
    Real 			 -> PreTerm {cons("Real")}
    String 			 -> PreTerm {cons("Str")}

    Id "(" {Term ","}* ")" 	 -> PreTerm {cons("Op")}
    String "(" {Term ","}* ")" 	 -> PreTerm {cons("OpQ")}
    Term "#" "(" Term ")" 	 -> PreTerm {cons("Explode")}

    PreTerm "{^" PreTerm "}"	 -> Term {cons("Anno")}

    Var "@" Term 		 -> Term {cons("As"),prefer}
    Var "@" PreTerm 		 -> PreTerm {cons("As")}

  context-free priorities
    Term "#" "(" Term ")" 	 -> PreTerm {cons("Explode")}
  > Var "@" Term 		 -> Term {cons("As")}

module Stratego-Core-Signatures
imports
  Stratego-Core-Identifiers
  Stratego-Core-Constants
exports
  sorts Sdecl
  context-free syntax
    "sorts" Sort* 		-> Sdecl {cons("Sorts")}
    "constructors" Opdecl* 	-> Sdecl {cons("Constructors")}

  sorts Sort
  context-free syntax
    LCID 			 -> Sort {cons("SortVar")}
    UCID 			 -> Sort {cons("SortNoArgs")}
    Id "(" {Sort ","}* ")" 	 -> Sort {cons("Sort")}

  sorts Opdecl
  context-free syntax
    Id     ":" Type 		-> Opdecl {cons("OpDecl")}
    String ":" Type 		-> Opdecl {cons("OpDeclQ")}
           ":" Type 		-> Opdecl {cons("OpDeclInj")}

  context-free syntax
    "external" Id     ":" Type 	-> Opdecl {cons("ExtOpDecl")}
    "external" String ":" Type 	-> Opdecl {cons("ExtOpDeclQ")}
    "external"        ":" Type 	-> Opdecl {cons("ExtOpDeclInj")}

  sorts Type ArgType ConstType FunType RetType
  context-free syntax
    Sort	                -> ConstType {cons("ConstType")}
    {ArgType "*"}+ "->" RetType -> FunType {cons("FunType")}
    "(" Type ")"                -> ArgType {bracket}
    ConstType			-> ArgType
    Type	                -> RetType
    FunType			-> RetType {reject}

    FunType			-> Type
    ConstType			-> Type

  %%%
   %% Restriction is required for the Sort* in Sdecl: List(a) is
   %% ambiguous.
   %%%
  context-free restrictions
    Sort -/- [\(]

module Stratego-Core-Layout
exports
  sorts Ws ShortCom LongCom CommChar Asterisk Eof 
  lexical syntax
    [\t\ \n\r]			-> Ws

    "//" ~[\n]* ([\n] | Eof)	-> ShortCom
    "/*" CommChar* "*/"	-> LongCom
				-> Eof  

    ~[\*]     -> CommChar

    "*"       -> Asterisk
    Asterisk  -> CommChar

  lexical restrictions
    Asterisk -/- [\/]
    Eof      -/- ~[]

  lexical syntax
    ShortCom 	-> LAYOUT
    LongCom 	-> LAYOUT
    Ws 		-> LAYOUT

  context-free restrictions
    LAYOUT? -/- [\ \t\n\r]
    LAYOUT? -/- [\/].[\*]
    LAYOUT? -/- [\/].[\/]

module Stratego-Core-Identifiers
exports
  sorts ModName ModNamePart
  lexical syntax
    {ModNamePart "/"}+ -> ModName
    [a-zA-Z\.\_] [a-zA-Z0-9\'\.\-\_]* -> ModNamePart
  lexical restrictions
    ModName -/- [a-zA-Z0-9\'\.\-\_]
  lexical syntax
    "imports" 		-> ModName {reject}
    "overlays" 		-> ModName {reject}
    "rules" 		-> ModName {reject}
    "signature" 	-> ModName {reject}
    "strategies" 	-> ModName {reject}

  sorts Id LId LCID UCID Wld
  lexical syntax
    [a-zA-Z\_] [a-zA-Z0-9\'\-\_]*     -> Id
    [a-zA-Z\_] [a-zA-Z0-9\'\-\_]* "*" -> LId
    [\'] [a-z]+                       -> Id

    [a-z] [a-zA-Z0-9\'\-\_]*  -> LCID
    [A-Z] [a-zA-Z0-9\'\-\_]*  -> UCID

  lexical restrictions
    Id   -/- [a-zA-Z0-9\'\-\_\*]
    LId  -/- [a-zA-Z0-9\'\-\_]
    LCID -/- [a-zA-Z0-9\'\-\_]
    UCID -/- [a-zA-Z0-9\'\-\_]

  lexical syntax
    "_"     -> Id {reject}
    "'"     -> Id {reject}

    Keyword -> Id   {reject}
    Keyword -> LId  {reject}
    Keyword -> LCID {reject}
    Keyword -> UCID {reject}

  lexical restrictions
    "all"
    "case" %% not reserved kw
    "constructors"
    "else" %% not reserved kw
    "end" %% not reserved kw
    "external" %% not reserved kw
    "fail"
    "id"
    "if" %% not reserved kw
    "in"
    "imports" %% not reserved kw
    "let"
    "module"
    "not"
    "one"
    "overlays"
    "otherwise" %% not reserved kw
    "prim"
    "rec" %% not reserved kw
    "rules"
    "script"
    "signature"
    "some"
    "sorts"
    "strategies"
    "stratego"
    "switch" %% not reserved kw
    "test"
    "then" %% not reserved kw
    "where"
    "import-term"
      -/- [a-zA-Z0-9\'\-\_]
  
  context-free restrictions
    Wld -/- [a-zA-Z0-9\'\-\_]

  sorts Keyword
  lexical syntax
    "all"               -> Keyword
    "constructors" 	-> Keyword
    "fail" 		-> Keyword
    "id" 		-> Keyword
    "in" 		-> Keyword
    "let" 		-> Keyword
    "module" 		-> Keyword
    "not" 		-> Keyword
    "one" 		-> Keyword
    "overlays" 		-> Keyword
    "prim" 		-> Keyword
    "rules" 		-> Keyword
    "script" 		-> Keyword
    "signature" 	-> Keyword
    "some" 		-> Keyword
    "sorts" 		-> Keyword
    "strategies" 	-> Keyword
    "stratego" 		-> Keyword
    "test" 		-> Keyword
    "where" 		-> Keyword
    "import-term"	-> Keyword


module Stratego-Core-Constants
exports
  sorts Int Real String StrChar
  lexical syntax
    [\-]? [0-9]+ 		-> Int
    [\-]? [0-9]+ [\.] [0-9]+ 	-> Real
    "\"" StrChar* "\"" 		-> String
    ~[\"\\] 			-> StrChar
    [\\] [\"tnr\\] 		-> StrChar


module Stratego-Core
imports Stratego-Core-Constants 
	Stratego-Core-Identifiers 
	Stratego-Core-Layout
	Stratego-Core-Signatures 
	Stratego-Core-Terms
	Stratego-Core-Strategies 
	Stratego-Core-Modules

hiddens
  context-free start-symbols Module