/*
  Copyright Dave Bone 1998 - 2014 
  All Rights Reserved. 
  No part of this document may be reproduced without written consent from the author.
	
FILE:		  lr1_k_phrase_th.lex
Dates:		  23 Mar 2004
Purpose:	  parse parse lr1 k phrase
              The keeps its own local symbol table: map and list.
              The terminal_def_phrase adds symbol to Yacco2's
              global symbol table.
Output:       lr1_k_phrase
*/
/@
@i "/usr/local/yacco2/copyright.w"
@** |lr1_k_phrase_th| thread.\fbreak
Parse lr1 k symbols phrase.
The |lr1_k_phrase_th| terminal keeps its own local symbol table: 
map and list.
It calls the common backend |term_def_ph| thread
extractor of symbol definition.
 \fbreak
Example of a lr1 k symbols vocabulary to parse:\fbreak
\listing{"/usr/local/yacco2/diagrams+etc/lrksym.txt"}
@/
fsm	
(fsm-id "lr1_k_phrase_th.lex"
,fsm-filename lr1_k_phrase_th
,fsm-namespace NS_lr1_k_phrase_th
,fsm-class Clr1_k_phrase_th{
  user-prefix-declaration
#include "lint_balls.h"
#include "identifier.h"
#include "term_def_ph.h"
#include "c_string.h"
#include "o2_sdc.h"
#include "cweb_or_c_k.h"
 ***
  user-declaration
    public:
    T_lr1_k_phrase* lr1_k_phrase_;
  ***
  constructor
    lr1_k_phrase_ = 0;
  ***
  op
    if(lr1_k_phrase_ != 0){
      delete lr1_k_phrase_;
      lr1_k_phrase_ = 0;
    }
    lr1_k_phrase_ = new T_lr1_k_phrase;
    lr1_k_phrase_->set_rc(*parser__->start_token__,__FILE__,__LINE__);
    AST* t = new AST(*lr1_k_phrase_);
    lr1_k_phrase_->phrase_tree(t);
  ***
}
,fsm-version "1.0",fsm-date "22 mar 2004",fsm-debug "false"
,fsm-comments "Parse lr1 k symbols phrase.")
parallel-parser	
(	
  parallel-thread-function
    TH_lr1_k_phrase_th
  ***
  parallel-la-boundary
    eolr
  ***
)
@"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T"
rules{
Rlr1_k_phrase  (){
  -> Rlint 
     Ropen_par 
       Rparameters  
     Rclose_par
     Rlint 
	Ropen_brace
		 Rsym_defs_phrase
		 Rt_sufx_phrase
		Rlint
	 Rclose_brace  
     {
    op
      Clr1_k_phrase_th* fsm = (Clr1_k_phrase_th*)rule_info__.parser__->fsm_tbl__;
      RSVP(fsm->lr1_k_phrase_);
      fsm->lr1_k_phrase_ = 0;
    ***
    }	
}

Ropen_par  (){
  ->  |?| { 
      op
        CAbs_lr1_sym* sym = new Err_no_open_parenthesis;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
  ->  "("
}

Rclose_par  (){
  ->  |?| { 
      op
        CAbs_lr1_sym* sym = new Err_no_close_parenthesis;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
  ->  ")"
}

Rparameters  (){
  -> Rlint
     Rfilename_phrase Rlint
     Rnamespace_phrase Rlint
}

Rfilename_phrase  (){
  -> Rfilename Rlint Rfilename_id 
}

Rfilename  (){
  ->  ||| "#file-name" NS_identifier::TH_identifier
  ->  ||| |?| NULL {
    op
      sf->p2__->set_auto_delete(true);
        CAbs_lr1_sym* sym = new Err_no_filename_present;
        sym->set_rc(*sf->p2__,__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
    ***
    }
  ->  |?| {
      op
        CAbs_lr1_sym* sym = new Err_no_filename_present;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
}

Rfilename_id  (){
  ->  ||| identifier NS_identifier::TH_identifier {
      op
        Clr1_k_phrase_th* fsm = (Clr1_k_phrase_th*)rule_info__.parser__->fsm_tbl__;
        fsm->lr1_k_phrase_->filename_id(sf->p2__);
      ***
      } 
  ->  ||| |?| NULL {
    op
      sf->p2__->set_auto_delete(true);
        CAbs_lr1_sym* sym = new Err_no_filename_id_present;
        sym->set_rc(*sf->p2__,__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
    ***
    }
  ->  |?| {
      op
        CAbs_lr1_sym* sym = new Err_no_filename_id_present;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
}

Rnamespace_phrase  (
lhs
){
  -> "," Rlint Rnamespace Rlint Rnamespace_id 
  ->  |?| {
      op
        CAbs_lr1_sym* sym = new Err_no_comma_present;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
}

Rnamespace  (){
  ->  ||| "#name-space" NS_identifier::TH_identifier 
  ->  ||| |?| NULL {
    op
      sf->p2__->set_auto_delete(true);
        CAbs_lr1_sym* sym = new Err_no_namespace_present;
        sym->set_rc(*sf->p2__,__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
    ***
    }
  ->  |?| {
      op
        CAbs_lr1_sym* sym = new Err_no_namespace_present;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
}

Rnamespace_id  (){
  ->  ||| identifier NS_identifier::TH_identifier {
      op
        Clr1_k_phrase_th* fsm = (Clr1_k_phrase_th*)rule_info__.parser__->fsm_tbl__;
        fsm->lr1_k_phrase_->namespace_id(sf->p2__);
      ***
      } 
  ->  ||| |?| NULL {
    op
      sf->p2__->set_auto_delete(true);
        CAbs_lr1_sym* sym = new Err_no_namespace_id_present;
        sym->set_rc(*sf->p2__,__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
    ***
    }
  ->  |?| {
      op
        CAbs_lr1_sym* sym = new Err_no_namespace_id_present;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
}

Rsym_defs_phrase
/@
Use of \invisibleshift to make it lr(1).
@/
(){
  -> Rlint Rsym_def Rlint Rsym_def1s |.| 
}

Rsym_def  (){
  ->  ||| "terminal-def" NS_term_def_ph::TH_term_def_ph {
    op
      Clr1_k_phrase_th* fsm = (Clr1_k_phrase_th*)rule_info__.parser__->fsm_tbl__;
	  sf->p2__->classification(T_terminal_def::lrk);
      CAbs_lr1_sym* r = fsm->lr1_k_phrase_->add_t_to_alphabet(sf->p2__,rule_info__.parser__);
      if(r == 0) return;
      RSVP(r);
      rule_info__.parser__->set_stop_parse(true);
    ***
    }
  ->  ||| |?| NULL {
      op
        sf->p2__->set_auto_delete(true);
        CAbs_lr1_sym* sym = new Err_no_sym_defs_present;
        sym->set_rc(*sf->p2__,__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
  ->  |?| {
    op
        CAbs_lr1_sym* sym = new Err_no_sym_defs_present;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
    ***
    }
}

Rsym_def1s  (){
  ->  Rsym_def1 Rlint
  ->  Rsym_def1s Rsym_def1 Rlint
  -> 
}

Rsym_def1  (){
  ->  ||| "terminal-def" NS_term_def_ph::TH_term_def_ph {
    op
      Clr1_k_phrase_th* fsm = (Clr1_k_phrase_th*)rule_info__.parser__->fsm_tbl__;
	  sf->p2__->classification(T_terminal_def::lrk);
      CAbs_lr1_sym* r = 
	fsm->lr1_k_phrase_->add_t_to_alphabet(sf->p2__,rule_info__.parser__);
      if(r != 0){
        RSVP(r);
        rule_info__.parser__->set_stop_parse(true);
        return;
      }
    ***
    }
  ->  ||| "no key-value present in definition" NULL {
      op
        Clr1_k_phrase_th* fsm = (Clr1_k_phrase_th*)rule_info__.parser__->fsm_tbl__;
        RSVP(sf->p2__);
        fsm->lr1_k_phrase_ = 0;
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
  ->  ||| |?| NULL {
    op
      using namespace NS_yacco2_T_enum;
       int id = sf->p2__->enumerated_id__;
       if(id >= T_Enum::start_ERR && id <= T_Enum::end_ERR){
         RSVP(sf->p2__);
         rule_info__.parser__->set_stop_parse(true);
       }else{
        CAbs_lr1_sym* sym = new Err_not_a_terminal_definition;
        sym->set_rc(*sf->p2__,__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
       }
    ***
    }
}

Rt_sufx_phrase  (){
  -> Rlint Rcweb_k Rlint Rt_sufx_kw_must Rt_sufx_code {
  op
    Clr1_k_phrase_th* fsm = (Clr1_k_phrase_th*)rule_info__.parser__->fsm_tbl__;
	  fsm->lr1_k_phrase_->lrk_sufx_code()
	  ->add_cweb_marker(sf->p2__->cweb_t_);		
  ***
  } 
  -> Rlint Rt_sufx_kw_code
}

Rt_sufx_kw_code  
/@
If a |cweb| comment is seen, deposit it in the 
directive's syntax directed code.
@/
(){
  -> Rt_sufx_kw Rt_sufx_code 
  -> 
}

Rt_sufx_kw  
/@
Drop keyword as it's presence is indicated elsewhere.
So pop the cork and let the good times roll.
@/

(){
  -> ||| "#lrk-sufx" NS_identifier::TH_identifier {
	  op
         sf->p2__->set_auto_delete(true);
      ***
      }
}

Rt_sufx_kw_must  
/@
Drop keyword as it's presence is indicated elsewhere.
So pop the cork and let the good times roll.
@/

(){
  -> ||| "#lrk-sufx" NS_identifier::TH_identifier {
	  op
         sf->p2__->set_auto_delete(true);
      ***
      }
  ->  ||| |?| NULL {
      op
          CAbs_lr1_sym* sym = new Err_missing_lrk_sufx_kw;
          sym->set_rc(*sf->p2__,__FILE__,__LINE__);
          RSVP(sym);
          sf->p2__->set_auto_delete(true);
          rule_info__.parser__->set_stop_parse(true);
      ***
      }
  -> |?| {
     op
          CAbs_lr1_sym* sym = new Err_missing_lrk_sufx_kw;
          sym->set_rc(*sf->p1__,__FILE__,__LINE__);
          RSVP(sym);
          rule_info__.parser__->set_stop_parse(true);
          return;
     ***
     }
}

Rt_sufx_code  (){
  ->  ||| "syntax-code" NS_o2_sdc::TH_o2_sdc {
	  op
        Clr1_k_phrase_th* fsm = (Clr1_k_phrase_th*)rule_info__.parser__->fsm_tbl__;
        fsm->lr1_k_phrase_->lrk_sufx_code(sf->p2__);
      ***
      }
  ->  ||| |?| NULL {
      op
          CAbs_lr1_sym* sym = new Err_no_syntax_code_present;
          sym->set_rc(*sf->p2__,__FILE__,__LINE__);
          RSVP(sym);
          sf->p2__->set_auto_delete(true);
          rule_info__.parser__->set_stop_parse(true);
      ***
      }
  ->  |?| {
      op
          CAbs_lr1_sym* sym = new Err_no_syntax_code_present;
          sym->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__);
          RSVP(sym);
          rule_info__.parser__->set_stop_parse(true);
      ***
      }
}

Ropen_brace  (){
  ->  |?| { 
	  op
        CAbs_lr1_sym* sym = new Err_no_open_brace;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
  ->  "{"
}

Rclose_brace  (){
  ->  |?| { 
	  op
        CAbs_lr1_sym* sym = new Err_no_close_brace;
        sym->set_rc(*rule_info__.parser__->current_token(),__FILE__,__LINE__);
        RSVP(sym);
        rule_info__.parser__->set_stop_parse(true);
      ***
      }
  ->  "}"
}

Rlint  (){
  ->  ||| lint NS_lint_balls::TH_lint_balls
  -> 
}

Rcweb_k  (
lhs {
	user-declaration
	  AST* cweb_t_;
	***
	constructor
	  cweb_t_ = 0;
	***
	}
){
 ->  ||| "cweb-comment" NS_cweb_or_c_k::TH_cweb_or_c_k {
  op
       Clr1_k_phrase_th* fsm = (Clr1_k_phrase_th*)rule_info__.parser__->fsm_tbl__;
      T_cweb_comment* k = sf->p2__;
      AST* cwebk_t_ = new AST(*k);
      cweb_t_ = new AST();
      T_cweb_marker* cw = new T_cweb_marker(cweb_t_);
      cw->set_rc(*k,__FILE__,__LINE__);
        cweb_t_ = cw->ast();
      AST::set_content(*cweb_t_,*cw);
        AST::join_pts(*cweb_t_,*cwebk_t_);
  ***
  }
    ->  ||| |?| NULL {
      op 
		RSVP(sf->p2__);
		rule_info__.parser__->set_stop_parse(true); 
      ***
      }
}
}// end of rules
