module languages/casl/syntax/BasicItems

%% written/changed by Bjarke Wedemeijer (January 1998)
%% adapted by Mark van den Brand (Juni 1999)
%% adapted by Mark van den Brand (November 2000)

imports languages/casl/syntax/Lexical
exports
  sorts
	Basic-Spec Sort-S Op-S Pred-S Op-Type Pred-Type
%%    Basic-Item Basic-Spec Sig-Items Var-Decl Datatype-Decl
%%    Formula Sort-Item Op-Item Pred-Item Op-Type Op-Attr Op-Head
%%    Term Terms Some-Sorts Arg-Decl Pred-Type Pred-Head
%%    Alternative Component Quantifier Formula-1 Formula-2 Formula-3
%%    MixFix QualPredName QualVarName QualOpName Atom Op-Name 
%%    Pred-Name Formula-2-or Labelled-Op-Item Labelled-Pred-Item
%%    Formula-2-and Labelled-Formula LabelAnnot Var-S Axiom-S
%%    Sort-S Op-S Pred-S Datatype-S Opt-Semi

  lexical syntax
	"."|[\183] -> Dot	

  context-free syntax

%% Basic-Items section
    "{" "}"         -> Basic-Spec
    Ann Basic-Item+ -> Basic-Spec

    Sig-Items				             -> Basic-Item 
    "free" Data-Item                                 -> Basic-Item
    "generated" Data-Item                            -> Basic-Item 
    "generated" "{" Sig-Items+ "}" Opt-Semi          -> Basic-Item 
    Var-S {Var-Decl ";"}+ Opt-Semi                   -> Basic-Item
    "forall" {Var-Decl ";"}+ Ann Dot-Item	     -> Basic-Item 
    Dot Ann Formula Opt-Semi                         -> Basic-Item

    Dot Ann {Formula (Ann Dot)}+ Opt-Semi            -> Dot-Item 

%% old style
    Axiom-S Ann {Formula (";" Ann)}+ Opt-Semi        -> Basic-Item 

%% Sig-Items
    Sort-S Ann {Sort-Item (";" Ann)}+ Opt-Semi      -> Sig-Items
    Op-S   Ann {Op-Item   (";" Ann)}+ Opt-Semi      -> Sig-Items
    Pred-S Ann {Pred-Item (";" Ann)}+ Opt-Semi      -> Sig-Items
    Data-Item                                       -> Sig-Items

%% Data-Item (abbreviation)
    Datatype-S Ann {Datatype-Decl (";" Ann)}+ Opt-Semi  -> Data-Item

%% Sort-Item
    {Sort ","}+                               -> Sort-Item
    {Sort ","}+ "<" Sort                      -> Sort-Item
    Sort "=" "{" Var ":" Sort Dot Formula "}" -> Sort-Item
    Sort "=" {Sort "="}+                      -> Sort-Item

%% Op-Item 
    {Op-Name ","}+ ":" Op-Type                    -> Op-Item
    {Op-Name ","}+ ":" Op-Type "," {Op-Attr ","}+ -> Op-Item 
    Op-Name Op-Head "=" Term                      -> Op-Item

%% Op-Type
    Some-Sorts "->" Sort  -> Op-Type
    Sort                  -> Op-Type
    Some-Sorts "->?" Sort -> Op-Type
    "?" Sort              -> Op-Type

%% Sorts
    {Sort "*"|[\215]}+ -> Some-Sorts

%% Op-Attr
    "assoc"                 -> Op-Attr
    "comm"                  -> Op-Attr
    "idem"                  -> Op-Attr
    "unit" Term             -> Op-Attr

%% Op-Head
    "(" {Arg-Decl ";"}+ ")" ":" Sort     -> Op-Head
    ":" Sort                             -> Op-Head
    "(" {Arg-Decl ";"}+ ")" ":" "?" Sort -> Op-Head
    ":" "?" Sort                         -> Op-Head

%% Arg-Decl
    {Var ","}+ ":" Sort -> Arg-Decl

%% Pred-Item
    {Pred-Name ","}+ ":" Pred-Type    -> Pred-Item
    Pred-Name Pred-Head "<=>" Formula -> Pred-Item
    Pred-Name "<=>" Formula           -> Pred-Item

%% Pred-Type
    Some-Sorts -> Pred-Type
    "(" ")"    -> Pred-Type

%% Pred-Head
    "(" {Arg-Decl ";"}+ ")" -> Pred-Head

%% Datatype-Decl
    Sort "::=" Ann {Alternative ("|" Ann)}+  -> Datatype-Decl

%% Alternative
    Op-Name"(" {Component ";"}+ ")"     -> Alternative
    Op-Name"(" {Component ";"}+ ")" "?" -> Alternative
    Op-Name                             -> Alternative
    Sort-S {Sort ","}+                  -> Alternative

%% Component
    {Op-Name ","}+ ":" Sort  -> Component
    {Op-Name ","}+ ":?" Sort -> Component
    Sort                     -> Component

%% Var-Decl
    {Var ","}+  ":" Sort -> Var-Decl

%% Var-S
    "var" -> Var-S
    "vars" -> Var-S

%% Axiom-S
    "axiom"  -> Axiom-S
    "axioms" -> Axiom-S

%% Sort-S
    "sort"  -> Sort-S
    "sorts" -> Sort-S

%% Op-S
    "op"  -> Op-S
    "ops" -> Op-S

%% Pred-S
    "pred"  -> Pred-S
    "preds" -> Pred-S

%% Datatype-S
    "type"  -> Datatype-S
    "types" -> Datatype-S

%% Opt-Semi
    ";"? Ann               -> Opt-Semi

%% Formula


    Formula "/\\" Formula                 -> Formula {left} 
    Formula "\\/" Formula                 -> Formula {left} 
    Formula "=>" Formula                  -> Formula {right}
    Formula "if" Formula                  -> Formula {left}
    Formula "<=>" Formula                 -> Formula {non-assoc}

    Formula "/\\" Formula-Quant                 -> Formula {prefer}
    Formula "\\/" Formula-Quant                 -> Formula {prefer}
    Formula "=>" Formula-Quant                  -> Formula {prefer}
    Formula "if" Formula-Quant                  -> Formula {prefer}
    Formula "<=>" Formula-Quant                 -> Formula {non-assoc}
    Quantifier {Var-Decl ";"}+ Dot Formula -> Formula {avoid}
    Quantifier {Var-Decl ";"}+ Dot Formula -> Formula-Quant

    "not"|[\172] Formula       -> Formula
    "not"|[\172] Formula-Quant -> Formula {prefer}
    "(" Formula ")"            -> Formula
    Atom                       -> Formula

    "true"                          -> Atom
    "false"                         -> Atom
    "def" Term                      -> Atom
    Term "=e="|"=" Term             -> Atom
    Term "in" Sort                  -> Atom
    Term                            -> Atom

%% Quantifier
    "forall"     -> Quantifier
    "exists"     -> Quantifier
    "exists" "!" -> Quantifier


%% Terms
    {Term ","}+ -> Terms

%% Term
    MixFix+     -> Term
    Term "when" Formula "else" Term     -> Term {right}

%% MixFix
    No-Bracket-Token                    -> MixFix
    Literal				-> MixFix
    Place                               -> MixFix
    QualPredName                        -> MixFix
    QualVarName                         -> MixFix
    QualOpName                          -> MixFix
    MixFix ":"|"as" Sort                -> MixFix
    "(" Terms ")"                       -> MixFix
    "[" Terms? "]"                      -> MixFix
    "{" Terms? "}"                      -> MixFix

%% QualPredName 
    "(" "pred" Pred-Name ":" Pred-Type ")" -> QualPredName

%% QualVarName
    "(" "var" Var ":" Sort ")"          -> QualVarName

%% QualOpName
    "(" "op"  Op-Name ":" Op-Type ")"   -> QualOpName

%% Various small definitions
    Token-Id  -> Sort
    "<"       -> Sort {reject}

    Id        -> Op-Name

    Id        -> Pred-Name

    Simple-Id -> Var

  context-free priorities
    MixFix+     -> Term >
    Term "when" Formula "else" Term     -> Term

  context-free priorities
    Atom                       -> Formula
    >
    "not"|[\172] Formula       -> Formula 
    >
    {
    Formula "/\\" Formula                 -> Formula  
    Formula "\\/" Formula                 -> Formula 
    } 
    >
    {
    Formula "=>" Formula                  -> Formula 
    Formula "if" Formula                  -> Formula 
    Formula "<=>" Formula                 -> Formula 
    }
    >
    {
    Formula "/\\" Formula-Quant                 -> Formula
    Formula "\\/" Formula-Quant                 -> Formula
    }
    >
    {
    Formula "=>" Formula-Quant                  -> Formula
    Formula "if" Formula-Quant                  -> Formula
    Formula "<=>" Formula-Quant           -> Formula
    }
    >
    Quantifier {Var-Decl ";"}+ Dot Formula -> Formula