/*Copyright 2009--2017 Rene Vestergaard
 * 
 * This file is part of CEqEA. 
 * 
 * CEqEA is free software: you can redistribute it and/or modify it under 
 * the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * CEqEA is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public 
 * License along with CEqEA, possibly as <CEqEA-dir>/COPYING.  
 * If not, see <http://www.gnu.org/licenses/>. 
 */
 
//overall structure
parseModalities 				
  : ( mdltDfltSchm
    | schema
    | mdltDfltInfl
    | influence
    | mdltDfltSeed
    | seed
    )*
    EOF		
  ;


//basics
name 		
  : NAME
  | NMBR						
  ;

endptBase	
  : APPRX		
  | ENDPT		
  | CSLSS			
  ;
  
cstnBase	
  : PUSH			
  | PULL			
  | PUSHPULL			
  ;
  
mdtnTrBase
  : EXPLCT			
  | (DNMC|IMPLCT) (SUPPLY DOT? NMBR)?					
  ;

mdtnBase										
  : STPWS		 
  | RESID 	(SUPPLY DOT? NMBR)?
  		( | /*only in influence*/ mdfr_stts)
	  	( /*dynamic*/ | SQNC_OPEN mdtnStatSqnc SQNC_CLSE)									
  ;
  
mdtnStatSqnc	
  : (GRT_THN mdtnStatStt | mdtnStatStt GRT_THN)? 
    ( (LSS_THN mdtnStatStt | mdtnStatStt LSS_THN)
      (GRT_THN mdtnStatStt | mdtnStatStt GRT_THN) )*
    (LSS_THN mdtnStatStt | mdtnStatStt LSS_THN)?
  ;
  
mdtnStatStt	
  : name DOT name (SHARP NMBR)?
  ;


rgltnBase	
  : NMBR
  | INTRINSIC	
  | INCIDENTL  	
  | EXTRINSIC
  ;
  
cmpstnBase	
  : CHRNT 		
  | MIXED		
  ;

sltnBase	
  : EMPTY		
  | FIXED  		
  | APPEAR			
  | APPEAR_OK		
  | VANISH			
  | VANISH_OK		
  | CHANGE			
  | CHANGE_OK	
  ;


/*OBJ_CNDNSD, OBJ_MDLTS_SPCFD were internalized in CEq_b_syntax --- ignore them here;* 
 *the remaining entries provide the details that CEq_b_syntax preserved as mdltChar  */
schema	
  : SCHM_CNDNSD	SCHM_MDLTS_SPCFD 
  			( endptSchm
  			| cstnSchm
  			| mdtnSchm
  			| rgltnSchm
  			| cmpstnSchm
  			| sltnSchm
  			)*							
  ;


schmMdltQlfr						
  :		( LSS_THN	DFLT		
  		  GRT_THN
  		| LSS_THN	( slctr_sbst	/*only for schmMdltInSitu*/
  				| slctr_lctn	/*only for schmMdltInSitu*/
  				| slctr_role
  				| slctr_ordr
  				| slctr_plrt
  				)*		
  		  GRT_THN
  		| LSS_THN	( slctr_sbst	/*only for schmMdltInSitu*/
  				| slctr_lctn	/*only for schmMdltInSitu*/
  				| slctr_plrt
  				)*
  				SUBJ		
  				( slctr_sbst	/*only for schmMdltInSitu*/
  				| slctr_lctn	/*only for schmMdltInSitu*/
  				| slctr_plrt
  				)*
  		  GRT_THN
  		)
  ;

schmMdlt				
  : schmMdltQlfr*	
  ;

schmMdltInSitu		
  : ( qlfr_situ		/*only for chrncSchm*/				
    | schmMdltQlfr								
    )*												
  ;

endptSchm	
  : endptBase schmMdlt
  ;

cstnSchm	
  : cstnBase schmMdlt
  ;
  
mdtnSchm	
  : mdtnBase schmMdlt
  ;

rgltnSchm	
  : rgltnBase schmMdltInSitu
  ;
  
cmpstnSchm	
  : cmpstnBase schmMdltInSitu
  ;

sltnSchm	
  : sltnBase	
  ;

//default occurrences
mdltDfltSchm
  : endptDfltSchm
  | cstnDfltSchm
  | mdtnDfltSchm
  | rgltnDfltSchm
  | cmpstnDfltSchm
  | sltnDfltSchm
  ;

  
endptDfltSchm
  : TRMNTN (LSS_THN SCHM GRT_THN)? ASSIGN endptSchm
  ;
  
cstnDfltSchm
  : CSTN (LSS_THN SCHM GRT_THN)? ASSIGN cstnSchm 
  ;
  
mdtnDfltSchm
  : MDTN (LSS_THN SCHM GRT_THN)? ASSIGN mdtnSchm
  ;
  
rgltnDfltSchm
  : RGLTN (LSS_THN SCHM GRT_THN)? ASSIGN ( CHMSTRY | rgltnSchm+ )
  ;       

cmpstnDfltSchm
  : INSTNTTN (LSS_THN SCHM GRT_THN)? ASSIGN cmpstnSchm 
  ;
  
  
sltnDfltSchm
  : SLTN (LSS_THN SCHM GRT_THN)? ASSIGN sltnSchm
  ;



/*INFL_CNDNSD was internalized in CEq_b_syntax --- ignore it, the ., and order of entries;*
 *mdltInfl is the real point of interest for the present grammar                          *
 *also, rglt stipulates where further modalities may have been inlined                    */
influence	
  : INFL_CNDNSD . infl rglt?  
  ;

infl        
  : (PSTV|NGTV) NAME* mdltInfl rglt
  ;


/*ignore order of entries below; it merely reflects internal concerns;   */
/*only point of interest is that strong inhibition may inline modalities*/
rglt	
  : RGLT_INHBTN rglt rglt
  | RGLT_DSJNCT rglt*
  | RGLT_CNJNCT rglt*
  | RGLT_STRONG rglt NAME* rglt? COL_SEP? mdltInfl				
  | RGLT_ENTT
  | DEFERRED
  ;
  

/*INFL_MDLTS_SPCFD was internalized in CEq_b_syntax --- ignore it here*/
mdltInfl	
  : (INFL_MDLTS_SPCFD 
  	( endptInfl
    	| cstnInfl
    	| mdtnInfl
    	| rgltnInfl
    	| cmpstnInfl
    	| sltnInfl
    	)*
    )?					
  ;	
  
endptInfl	
  : endptBase	
  ;


cstnInfl						
  : cstnBase mdfr_range?									
  ;
  

mdtnInfl					
  : mdtnBase qlfr_ordr*		
  ;


rgltnInfl			
  : rgltnBase mdfr_stts? mdfr_range? qlfr_rlOrSbLc*											
  ;
  
cmpstnInfl			
  : cmpstnBase mdfr_schms? mdfr_range? qlfr_sbLc*											
  ;
 
sltnInfl			
  : sltnBase mdfr_schms? mdfr_range?									
  ;
  
//default occurrences
mdltDfltInfl
  : endptDfltInfl
  | cstnDfltInfl
  | mdtnDfltInfl
  | rgltnDfltInfl
  | cmpstnDfltInfl
  | sltnDfltInfl
  ;

  
endptDfltInfl
  : TRMNTN LSS_THN INFL GRT_THN ASSIGN endptInfl?
  ;
  
cstnDfltInfl	
  : CSTN LSS_THN INFL GRT_THN ASSIGN cstnInfl? 
  ;
  
mdtnDfltInfl
  : MDTN LSS_THN INFL GRT_THN ASSIGN mdtnInfl?
  ;
  
rgltnDfltInfl
  : RGLTN LSS_THN INFL GRT_THN ASSIGN rgltnInfl?
  ;       

cmpstnDfltInfl
  : CMPSTN LSS_THN INFL GRT_THN ASSIGN cmpstnInfl?
  ;  
  
sltnDfltInfl
  : SLTN LSS_THN INFL GRT_THN ASSIGN sltnInfl?
  ;
  

/*SEED_CNDNSD was internalized in CEq_b_syntax --- ignore it, order of entries, and COL_SEP  *
 *note mainly that several different set of modality overrides may be specified for each seed*/
seed	
 : SEED_CNDNSD
 	QUOTTN (name DOT name)+ QUOTTN			 
	( (channel)? COL_SEP? mdltSeed (RGLT_DSJNCT mdltSeed)* 
 	| EXCL )											
 ;
  
channel
  : CHANNEL PAR_OPEN name PAR_CLSE	
  ;
  
mdltSeed												
  : ( connectSeed
    | cstnSeed
    | mdtnSeed
    | rgltnSeed
    | cmpstnSeed
    | sltnSeed
    | maxVisitsSeed
    | killVisitsSeed
    )*			
  ;

connectSeed	
  : NO_OUTGO	
  | NO_INCOM	
  ;
    
cstnSeed			
  : cstnBase qlfr_cnnct*	
  ;

mdtnSeed		
  : mdtnTrBase mdfr_stts? qlfr_orLcCn*											
  ;

rgltnSeed		
  : rgltnBase mdfr_stts? qlfr_rlOrSbLcCn*											
  ;

cmpstnSeed		
  : cmpstnBase mdfr_schms? qlfr_sbLcCn*											
  ;

sltnSeed			
  : sltnBase mdfr_schms? qlfr_cnnct*											
  ;

maxVisitsSeed	
  : SILENCE PAR_OPEN NMBR PAR_CLSE	
  ;

killVisitsSeed	
  : EXPIRE PAR_OPEN NMBR NMBR PAR_CLSE	
  ;

mdltDfltSeed
  : connectDfltSeed
  | cstnDfltSeed
  | mdtnDfltSeed
  | rgltnDfltSeed
  | cmpstnDfltSeed
  | sltnDfltSeed
  | maxVisitsDfltSeed
  | killVisitsDfltSeed
  ;

connectDfltSeed
  : CONNECT LSS_THN SEED GRT_THN ASSIGN connectSeed?
  ;

cstnDfltSeed
  : CSTN LSS_THN SEED GRT_THN ASSIGN cstnSeed?
  ;
  
mdtnDfltSeed
  : MDTN LSS_THN SEED GRT_THN ASSIGN mdtnSeed?
  ;
  
rgltnDfltSeed
  : RGLTN LSS_THN SEED GRT_THN ASSIGN rgltnSeed?
  ;
  
cmpstnDfltSeed
  : CMPSTN LSS_THN SEED GRT_THN ASSIGN cmpstnSeed?
  ;
    
sltnDfltSeed
  : SLTN LSS_THN SEED GRT_THN ASSIGN sltnSeed?
  ;

maxVisitsDfltSeed
  : SILENCE LSS_THN SEED GRT_THN ASSIGN NMBR?
  ;

killVisitsDfltSeed
  : EXPIRE LSS_THN SEED GRT_THN ASSIGN (NMBR NMBR)?
  ;

//generic pieces of syntax
slctr_sbst
  : RCTN		
  | SLVNT		
  ;
  
slctr_lctn
  : SRCE		
  | SINK		
  ;

slctr_role	
  : MDTR		
  | INHB		
  ;
  
slctr_ordr
  : DRCT		
  | INDRCT		
  ; 

slctr_plrt
  : PSTV		
  | NGTV			
  ;

slctr_cnnct
  : INCOM		
  | OUTGO			
  ;


qlfr_lctn
  : LSS_THN	slctr_lctn GRT_THN
  ;

qlfr_ordr  
  : LSS_THN	slctr_ordr GRT_THN
  ;

qlfr_cnnct
  : LSS_THN	slctr_cnnct GRT_THN
  ;

qlfr_orLcCn 
  : LSS_THN		
  	( slctr_ordr
  	| slctr_lctn
  	| slctr_cnnct
  	)+
  	GRT_THN
  ;

qlfr_rlOrSbLc 
  : LSS_THN		
  	( slctr_role
  	| slctr_ordr
  	| slctr_sbst
  	| slctr_lctn
  	)+
  	GRT_THN
  ;

qlfr_rlOrSbLcCn 
  : LSS_THN		
  	( slctr_role
  	| slctr_ordr
  	| slctr_sbst
  	| slctr_lctn
  	| slctr_cnnct
  	)+
  	GRT_THN
  ;

qlfr_sbLc
  : LSS_THN 	
  	( slctr_sbst
  	| slctr_lctn
  	)+ 
  	GRT_THN
  ;

qlfr_sbLcCn
  : LSS_THN 	
  	( slctr_sbst
  	| slctr_lctn
  	| slctr_cnnct
  	)+ 
  	GRT_THN
  ;

qlfr_situ
  : LSS_THN 	SITU GRT_THN
  ;

mdfr_schms	
  : PAR_OPEN name* PAR_CLSE
  ;

mdfr_stts	
  : PAR_OPEN ( name | name DOT name )* PAR_CLSE
  ;

  
mdfr_range	
  : SQNC_OPEN 	
  	(name DOT name (SHARP NMBR)?)? 	
      	RANGE 		
      	(name DOT name (SHARP NMBR)?)?
    SQNC_CLSE					
  ;