definition
module RefactoringsService

imports
  SemanticServices
  BuildersService

exports
  
  syntax
  
    "refactorings" <SectionName-LEX> <LAYOUT?-CF> <SemanticRule*-CF> -> <Section-CF> {cons("Refactorings")}

    "refactorings" -> <ReservedName-CF>
  
  context-free syntax
  	
  	"pp-table" ":" StrategoCall -> SemanticRule {cons("PPTable")}
  	"pretty-print" ":" StrategoCall -> SemanticRule {cons("PrettyPrint")}
    "refactoring"  SemanticNode* ":" String "="   StrategoCall BuilderOption* -> SemanticRule {cons("Refactoring")}

module BuildersService

imports
  SemanticServices

exports
  
  syntax
  
    "builders" <SectionName-LEX> <LAYOUT?-CF> <SemanticRule*-CF> -> <Section-CF> {cons("Builders")}

    "builders" -> <ReservedName-CF>
  
    "analysis" <SectionName-LEX> <LAYOUT?-CF> <SemanticRule*-CF> -> <Section-CF> {cons("Builders"), deprecated("Use 'builders' instead")}

    "analysis" -> <ReservedName-CF>

  context-free syntax
    
    "observer" ":" StrategoCall                           -> SemanticRule {cons("SemanticObserver")}
    "builder"  ":" String "=" StrategoCall BuilderOption* -> SemanticRule {cons("Builder")}
    "builder" "caption" ":" PropertyValue                 -> SemanticRule {cons("BuilderCaption")}
    
    "(openeditor)" -> BuilderOption {cons("OpenEditor")}
    "(realtime)"   -> BuilderOption {cons("RealTime")}
    "(persistent)" -> BuilderOption {cons("Persistent")}
    "(meta)"       -> BuilderOption {cons("Meta")}
    "(cursor)"     -> BuilderOption {cons("Cursor")}
    "(source)"     -> BuilderOption {cons("Source")}

module CompletionsService

imports
  SemanticServices

exports

  sorts
    CompletionPart CompletionAnno

  syntax
  
    "completions" <SectionName-LEX> <LAYOUT?-CF> <SemanticRule*-CF> -> <Section-CF> {cons("Completions")}

    "completions" -> <ReservedName-CF>

  context-free syntax

    "completion" "proposer" ":" StrategoCall -> SemanticRule {cons("CompletionProposer")}

    "completion" "lexical" ":" PropertyValue -> SemanticRule {cons("IdentifierLexical"), deprecated("Use 'identifier lexical' instead")}

    "identifier" "lexical" ":" PropertyValue -> SemanticRule {cons("IdentifierLexical")}

    "completion" "keyword" ":" PropertyValue CompletionAnno -> SemanticRule {cons("CompletionKeyword")}
    
    "completion" "template" ":" CompletionPart CompletionPart* CompletionAnno -> SemanticRule {cons("CompletionTemplate")}
    
    %% Deprecated: conflicts with content completion
    "completion" "template" ":" Id CompletionPart+ CompletionAnno -> SemanticRule {cons("CompletionTemplate"), avoid, deprecated("Add quotes to the starting literal")}
    
    "completion" "template" ":" Sort "=" CompletionPart CompletionPart* CompletionAnno -> SemanticRule {cons("CompletionTemplateWithSort")}
    
    %% Used as content completion triggers
    "completion" "template" ":" PropertyValue CompletionPart* CompletionAnno -> SemanticRule {cons("CompletionTemplate"), recover, avoid}
    "completion" "template" ":" Sort "=" PropertyValue CompletionPart* CompletionAnno -> SemanticRule {cons("CompletionTemplateWithSort"), recover, avoid}

    "completion" "trigger" ":" PropertyValue CompletionAnno -> SemanticRule {cons("CompletionTrigger")}
  
  context-free syntax
  
    "completions" -> StrategoCall {reject}
    "completion"  -> StrategoCall {reject}
    "identifier"  -> StrategoCall {reject}
    "observer"    -> StrategoCall {reject}
    "builder"     -> StrategoCall {reject}
    "occurrence"  -> StrategoCall {reject}
    ReservedName  -> StrategoCall {reject}
    
    String      -> CompletionPart
    Placeholder -> CompletionPart {cons("Placeholder")}

                 -> CompletionAnno {cons("None")}
    "(disabled)" -> CompletionAnno {cons("Disable")}
    "(disable)"  -> CompletionAnno {cons("Disable"), deprecated("Use (disabled) instead")}
    "(blank)"    -> CompletionAnno {cons("Blank")}
    "(blank)"    -> PropertyValue {reject}
    "(disable)"  -> PropertyValue {reject}
    "completion" -> PropertyValue {reject}
    "template"   -> PropertyValue {reject}
    "trigger"    -> PropertyValue {reject}
    "identifier" -> PropertyValue {reject}

  lexical syntax
    
    "<" PlaceholderChar* ">" -> Placeholder
    ~[\>\n]                  -> PlaceholderChar
    


module ReferencesService

imports
  SemanticServices

exports

  syntax
  
    "references" <SectionName-LEX> <LAYOUT?-CF> <SemanticRule*-CF> -> <Section-CF> {cons("References")}

    "references" -> <ReservedName-CF>

  context-free syntax
  
    "reference"  SemanticNode ":" StrategoCall StrategoCall -> SemanticRule {cons("ReferenceHoverRule"), deprecated}

    "reference"  SemanticNode ":" StrategoCall -> SemanticRule {cons("ReferenceRule")}

    "hover"      SemanticNode ":" StrategoCall -> SemanticRule {cons("HoverRule")}
  
    "occurrence" SemanticNode ":" StrategoCall -> SemanticRule {cons("OccurrenceRule")}
  
  context-free syntax
  
    "references" -> StrategoCall {reject}
    "reference"  -> StrategoCall {reject}
    "hover"      -> StrategoCall {reject}

module ColorerService

imports
  Common

exports

  sorts
  
    ColorRule Font Color ColorNode MaybeColor NoColor
    TokenKindName AttributeId Attribute

  syntax
  
    "colorer" <SectionName-LEX> <LAYOUT?-CF> <ColorRule*-CF> -> <Section-CF> {cons("Colorer")}
    
    "colorer" -> <ReservedName-CF>

  context-free syntax
  
    ColorNode ":" Attribute "(recursive)" -> ColorRule {cons("ColorRuleAll")} %% One rule to rule them all
    "environment" ColorNode ":" Attribute -> ColorRule {cons("ColorRuleAll")} %% One rule to rule them all
                  ColorNode ":" Attribute -> ColorRule {cons("ColorRule")}
    
    ColorNode ":" String "=" Attribute "(recursive)" -> ColorRule {cons("ColorRuleAllNamed")}
    "environment" ColorNode ":" String "=" Attribute -> ColorRule {cons("ColorRuleAllNamed")}
                  ColorNode ":" String "=" Attribute -> ColorRule {cons("ColorRuleNamed")}

    Color   MaybeColor Font -> Attribute {cons("Attribute")}
    AttributeId             -> Attribute {cons("AttributeRef")}
    
    Node          -> ColorNode
    TokenKindName -> ColorNode {cons("Token"), prefer}
    "token" Id    -> ColorNode {cons("Literal")}
    
    "(recursive)" -> ColorOption {cons("Recursive")}
    
    "identifier" -> TokenKindName {cons("TK_IDENTIFIER")}
    "number"     -> TokenKindName {cons("TK_NUMBER")}
    "layout"     -> TokenKindName {cons("TK_LAYOUT")}
    "string"     -> TokenKindName {cons("TK_STRING")}
    "keyword"    -> TokenKindName {cons("TK_KEYWORD")}
    "operator"   -> TokenKindName {cons("TK_OPERATOR")}
    "var"        -> TokenKindName {cons("TK_VAR")}
    "error"      -> TokenKindName {cons("TK_ERROR")}
    "unknown"    -> TokenKindName {cons("TK_UNKNOWN")}
    
                    -> Font {cons("NORMAL")}
    "bold"          -> Font {cons("BOLD")}
    "italic"        -> Font {cons("ITALIC")}
    "bold" "italic" -> Font {cons("BOLD_ITALIC")}
    "italic" "bold" -> Font {cons("BOLD_ITALIC")}

    %% TODO: Default "font" attribute? (would need disambiguation and merging support)
    %%
    %% "_" -> Font {cons("NORMAL")}
    
    "_"         -> Color {cons("ColorDefault")}
    Int Int Int -> Color {cons("ColorRGB")}
                -> NoColor {cons("NoColor")}
    Color       -> MaybeColor
    NoColor     -> MaybeColor

    AttributeId "=" Attribute -> ColorRule {cons("ColorDef")}
    
    Id             -> AttributeId          %% Standard color name (e.g., 'red')
    String         -> AttributeId          %% Descriptive color name (could be shown in IDE)
    "_"            -> AttributeId {reject}
    Font           -> AttributeId {reject}
    "rec"          -> AttributeId {reject}
    "environment"  -> AttributeId {reject}

module OutlinerService

imports
  Common
  %% TODO: Maybe -- StrategoMix[StrategoExpr]

exports

  sorts
    OutlineRule Pattern Term PreTerm

  syntax
  
    "outliner" <SectionName-LEX> <LAYOUT?-CF> <OutlineRule*-CF> -> <Section-CF> {cons("Outliner")}
    
    "outliner" -> <ReservedName-CF>

  context-free syntax

    Node                 -> OutlineRule {cons("OutlineRule"), prefer}

module FoldingService

imports
  Common

exports

  sorts
    FoldingRule FoldingAnno

  syntax
  
    "folding" <SectionName-LEX> <LAYOUT?-CF> <FoldingRule*-CF> -> <Section-CF> {cons("Folding")}
    
    "folding" -> <ReservedName-CF>
  
  context-free syntax
    
    %% TODO: Reconsider "all" keyword for siblings; we already have list sorts using '*'
    
          Node FoldingAnno -> FoldingRule {cons("FoldRule")}
    "all" Node FoldingAnno -> FoldingRule {cons("FoldRuleAll")}

    "(disable)"  -> FoldingAnno {cons("Disable"), deprecated("Use (disabled) instead")}
    "(disabled)" -> FoldingAnno {cons("Disable")}
    "(folded)"   -> FoldingAnno {cons("Folded")}
                 -> FoldingAnno {cons("None")}

module SemanticServices

imports
  Common LanguageDescription

exports

  sorts
    SemanticRule SemanticNode StrategoId StrategoCall OnSaveAnno

  lexical syntax

    [a-zA-Z\_] [a-zA-Z0-9\'\-\_]* -> StrategoId
  
    "_"  -> SemanticNode

  lexical restrictions
  
    StrategoId -/- [a-zA-Z0-9\'\-\_]

  context-free syntax
     
     Node -> SemanticNode
    "provider"     PropertyValue -> SemanticRule {cons("SemanticProvider"), deprecated("Use 'provider :'")}
    "provider" ":" PropertyValue -> SemanticRule {cons("SemanticProvider")}

    "on" "save" ":" StrategoCall OnSaveAnno -> SemanticRule {cons("OnSave")}

             StrategoId -> StrategoCall {cons("Strategy")}
    "id" "." StrategoId -> StrategoCall {cons("Attribute")}
    
                        -> OnSaveAnno {cons("None")}

module LanguageDescription

imports
	Common SemanticServices

exports
  
  sorts
  
    LanguageProperty PropertyValue NoContinuation PropertyValues URL
    FenceDef BlockCommentDef IndentDef
  
  syntax
  
    "language" <SectionName-LEX> <LAYOUT?-CF> <LanguageProperty*-CF> -> <Section-CF> {cons("Language")}
    
    "language" -> <ReservedName-CF>
  
  lexical syntax
    
    ~[\ \t\n\r\,\:\"\=]+ -> PropertyValue {avoid}

    ~[\ \t\n\r\,\/\:]+ "://" ~[\ \t\n\r]+ -> URL
  
  lexical restrictions
  
  	PropertyValue -/- ~[\ \t\n\r\,\:\"\=]
  	URL           -/- ~[\ \t\n\r]
  
  context-free syntax
  
    { PropertyValue ","}* -> PropertyValues {cons("Values")}
    String                -> PropertyValue
  
  	%% General language properties
  
    "name"            ":" PropertyValue  -> LanguageProperty {cons("LanguageName")}
    "id"              ":" PropertyValue  -> LanguageProperty {cons("LanguageId")}
    "extensions"      ":" PropertyValues -> LanguageProperty {cons("Extensions")}
    "description"     ":" PropertyValue  -> LanguageProperty {cons("Description")}
    "table"           ":" PropertyValue  -> LanguageProperty {cons("Table")}
    "table" "provider" ":" StrategoCall  -> LanguageProperty {cons("TableProvider")}
    "start" "symbols" ":" Sort*          -> LanguageProperty {cons("StartSymbols")}
    "start" "symbols" ":" PropertyValues -> LanguageProperty {cons("StartSymbols"), avoid}
    "url"             ":" URL            -> LanguageProperty {cons("URL")}
    "extends"         ":" PropertyValues -> LanguageProperty {cons("Extends")}
    "aliases"         ":" PropertyValues -> LanguageProperty {cons("Aliases")} %% deprecated
    "unmanaged" "table" ":" Id "*"       -> LanguageProperty {cons("UnmanagedTablePrefix")}
   
     %% Syntax properties
     
     "line"  "comment" ":" PropertyValue      -> LanguageProperty {cons("LineCommentPrefix")}
     "block" "comment" ":" BlockCommentDef    -> LanguageProperty {cons("BlockCommentDefs")}
     "fences"          ":" FenceDef*          -> LanguageProperty {cons("FenceDefs")}
     "indent" "after"  ":" IndentDef*         -> LanguageProperty {cons("IndentDefs")}
     "identifier" "lexical" ":" PropertyValue -> LanguageProperty {cons("IdentifierLexical")}
     
     PropertyValue PropertyValue  PropertyValue -> BlockCommentDef {cons("BlockCommentDef")}
     PropertyValue NoContinuation PropertyValue -> BlockCommentDef {cons("BlockCommentDef")}
                                                -> NoContinuation {cons("NoContinuation")}
     
     PropertyValue PropertyValue -> FenceDef {cons("FenceDef")}
     PropertyValue               -> IndentDef {cons("IndentDef")}
     
     %% Avoid ambiguities with fencedef pairs
     "fences"     -> PropertyValue {reject}
     "identifier" -> PropertyValue {reject}
     "indent"     -> PropertyValue {reject}
     "fences"     -> PropertyValue {reject}
     "line"       -> PropertyValue {reject}
     "block"      -> PropertyValue {reject}

module Common

exports

  sorts
    Id IdStar Int STRING CHAR BACKSLASH String Node Sort Constructor ConstructorId
    ReservedName SectionName ModuleName Section Eof
    Ws ShortCom LongCom CommChar

  lexical syntax
  
    [a-zA-Z][a-zA-Z0-9\'\-\_]*     -> Id
    [a-zA-Z][a-zA-Z0-9\'\-\_]* "*" -> IdStar
    "-"? [0-9]+                    -> Int
    "\"" StringChar* "\""          -> STRING
    ~[\"\n\\]                      -> StringChar
    "\\\""                         -> StringChar
    BACKSLASH                      -> StringChar
    "\\"                           -> BACKSLASH
    
    ~[\n\r]*                       -> SectionName

    [\t\ \n\r]               -> Ws
    "//" ~[\n]* ([\n] | Eof) -> ShortCom
    "/*" CommChar* "*/"      -> LongCom
    ~[\*]                    -> CommChar
    Asterisk                 -> CommChar
    "*"                      -> Asterisk
    Ws                       -> LAYOUT
    ShortCom                 -> LAYOUT
    LongCom                  -> LAYOUT
                             -> Eof
  
  lexical restrictions
  
    Int         -/- [0-9]
    Id          -/- [a-zA-Z0-9\'\-\_]
    SectionName -/- ~[\n\r]
    Asterisk    -/- [\/]
    BACKSLASH   -/- [\"]
    Eof         -/- ~[]

  context-free restrictions

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

  context-free syntax
  
    Id     -> Sort {cons("Sort")}
    Id "*" -> Sort {cons("ListSort")}
    STRING -> String {cons("String")}
    
    %% nice, but makes C-SGLR fail to parse create-builders-desciptor.str properly
    %%        -> String {recover, avoid, ast("String(\"\")")}

    Sort "." "_" -> Sort {bracket}
    
    "_" "." ConstructorId -> Constructor {cons("ConstructorOnly")}
                       Id -> ConstructorId {cons("Constructor")}
    
    Sort                   -> Node
    Constructor            -> Node
    Sort "." ConstructorId -> Node {cons("SortAndConstructor")}
    
    ReservedName -> Node       {reject}
    ReservedName -> ModuleName {reject}

module EditorService

imports
  Common
  LanguageDescription
  FoldingService
  OutlinerService
  ColorerService
  ReferencesService
  CompletionsService
  BuildersService
  RefactoringsService

hiddens

  context-free start-symbols
    Module

exports

  sorts
    Module FileName ModuleName Imports Import

  lexical syntax
  
    [a-zA-Z0-9\-\_\.]+ -> FileName
    {FileName "/"}+    -> ModuleName
  
  lexical restrictions
  
  	FileName    -/- [a-zA-Z0-9\-\_\.]

  context-free syntax
  	
    "module" ModuleName Imports Section* -> Module {cons("Module")}
    "imports" Import+                    -> Imports {cons("Imports")}
                                         -> Imports {cons("NoImports")}

    ModuleName            -> Import {cons("Import")}
    ModuleName "[" Id "]" -> Import {cons("ImportRenamed")}

module EditorServicesRenamed
imports EditorService
          [ Import           => EditorServiceImport
            Imports          => EditorServiceImports
            Module           => EditorServiceModule
            FileName         => EditorServiceFileName
            BuilderOption    => EditorServiceBuilderOption
            CompletionAnno   => EditorServiceCompletionAnno
            CompletionPart   => EditorServiceCompletionPart
            PlaceholderChar  => EditorServicePlaceholderChar
            Placeholder      => EditorServicePlaceholder
            AttributeId      => EditorServiceAttributeId
            MaybeColor       => EditorServiceMaybeColor
            NoColor          => EditorServiceNoColor
            Color            => EditorServiceColor
            Font             => EditorServiceFont
            TokenKindName    => EditorServiceTokenKindName
            ColorNode        => EditorServiceColorNode
            Attribute        => EditorServiceAttribute
            ColorRule        => EditorServiceColorRule
            OutlineRule      => EditorServiceOutlineRule
            FoldingAnno      => EditorServiceFoldingAnno
            FoldingRule      => EditorServiceFoldingRule
            IndentDef        => EditorServiceIndentDef
            FenceDef         => EditorServiceFenceDef
            NoContinuation   => EditorServiceNoContinuation
            BlockCommentDef  => EditorServiceBlockCommentDef
            LanguageProperty => EditorServiceLanguageProperty
            PropertyValues   => EditorServicePropertyValues
            URL              => EditorServiceURL
            PropertyValue    => EditorServicePropertyValue
            ReservedName     => EditorServiceReservedName
            Section          => EditorServiceSection
            OnSaveAnno       => EditorServiceOnSaveAnno
            StrategoCall     => EditorServiceStrategoCall
            SemanticRule     => EditorServiceSemanticRule
            SemanticNode     => EditorServiceSemanticNode
            StrategoId       => EditorServiceStrategoId
            ModuleName       => EditorServiceModuleName
            Node             => EditorServiceNode
            ConstructorId    => EditorServiceConstructorId
            Constructor      => EditorServiceConstructor
            String           => EditorServiceString
            Sort             => EditorServiceSort
            Eof              => EditorServiceEof
            Asterisk         => EditorServiceAsterisk
            CommChar         => EditorServiceCommChar
            LongCom          => EditorServiceLongCom
            ShortCom         => EditorServiceShortCom
            Ws               => EditorServiceWs
            SectionName      => EditorServiceSectionName
            BACKSLASH        => EditorServiceBACKSLASH
            StringChar       => EditorServiceStringChar
            STRING           => EditorServiceSTRING
            Int              => EditorServiceInt
            IdStar           => EditorServiceIdStar
            Id               => EditorServiceId ]
