/*
  Copyright Dave Bone 1998 - 2014 
  All Rights Reserved. 
  No part of this document may be reproduced without written consent from the author.
	
FILE:     linker_id.lex
dates:    14 Mar 2005	
Purpose:  linker identifiers
Returned: T_identifier
Claim-to-fame: use of yacco2's symbol table to filter out linker's keywords
and allows the run thru of keyword "-" characters building up an id.
There are no expressions within Linker, so this extension does not conflict
with expressions and legitimite ids: a-b.

Extend the id to include unquoted string type recognition.
This allows the linker's ids to consume the full file name until
Yacco2 emits these fles as quoted strings thus protecting
against a legitimate file name having one of Linker's keywords:
monolithic or transitive.
*/
/@
@i "/usr/local/yacco2/copyright.w"
@** |linker_id| thread.\fbreak
Recognize Linker's identifiers.
@/
fsm	
(fsm-id	"linker_id.lex",fsm-filename linker_id,fsm-namespace NS_linker_id
,fsm-class		Clinker_id{
  user-prefix-declaration
#include "yacco2_stbl.h"
  ***  
  user-declaration
    public:
    std::string data_;
  ***  
  op
    data_.erase();
  ***
  constructor
    data_.erase();
  ***
  }
,fsm-version "1.0",fsm-date "17 Juin 2003",fsm-debug "false"
,fsm-comments	"\\olinker identifiers recognizer: uses symbol table.")
parallel-parser	
(	
  parallel-thread-function
    TH_linker_id
  ***
  parallel-la-boundary
    eolr - Rminus_la
  ***
)
@"/usr/local/yacco2/compiler/grammars/yacco2_T_includes.T"

rules{
Rlinker_id	 (
lhs{
  op
    Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
    T_sym_tbl_report_card report_card;
    kw_in_stbl* kw_in;
    using namespace yacco2_stbl;
    
    find_sym_in_stbl(report_card,*fsm->data_.c_str());
    if(report_card.action_ == T_sym_tbl_report_card::fnd){
      if(report_card.tbl_entry_->type_ == table_entry::keyword){
		kw_in = (kw_in_stbl*)report_card.tbl_entry_->symbol_;
		CAbs_lr1_sym* kw = kw_in->keyword_in_stbl();
			CAbs_lr1_sym* nkw;
			switch(kw->enumerated_id__){
			case T_Enum::T_T_transitive_:{nkw = new T_transitive;break;}  
			case T_Enum::T_T_grammar_name_:{nkw = new T_grammar_name;break;}  
			case T_Enum::T_T_error_symbols_:{nkw = new T_error_symbols;break;}  
			case T_Enum::T_T_name_space_:{nkw = new T_name_space;break;}  

			case T_Enum::T_T_thread_name_:{nkw = new T_thread_name;break;}  
			case T_Enum::T_T_monolithic_:{nkw = new T_monolithic;break;}  
			case T_Enum::T_T_file_name_:{nkw = new T_file_name;break;}  
			case T_Enum::T_T_no_of_T_:{nkw = new T_no_of_T;break;}  

			case T_Enum::T_T_list_of_native_first_set_terminals_:
	{nkw = new T_list_of_native_first_set_terminals;break;}  
			case T_Enum::T_T_end_list_of_native_first_set_terminals_:
	{nkw = new T_end_list_of_native_first_set_terminals;break;}  
			case T_Enum::T_T_list_of_transitive_threads_:
	{nkw = new T_list_of_transitive_threads;break;}  
			case T_Enum::T_T_end_list_of_transitive_threads_:
	{nkw = new T_end_list_of_transitive_threads;break;}  
			case T_Enum::T_T_list_of_used_threads_:
	{nkw = new T_list_of_used_threads;break;}  
			case T_Enum::T_T_end_list_of_used_threads_:
	{nkw = new T_end_list_of_used_threads;break;}  
			case T_Enum::T_T_T_alphabet_:{nkw = new T_T_alphabet;break;}  
			case T_Enum::T_T_end_T_alphabet_:{nkw = new T_end_T_alphabet;break;}  
			case T_Enum::T_T_file_of_T_alphabet_:{nkw = new T_file_of_T_alphabet;break;}  
			case T_Enum::T_T_emitfile_:{nkw = new T_emitfile;break;}  
			case T_Enum::T_T_preamble_:{nkw = new T_preamble;break;}  
			case T_Enum::T_T_fsm_comments_:{nkw = new T_fsm_comments;break;}  
			case T_Enum::T_T_end_preamble_:{nkw = new T_end_preamble;break;}  
			}
			nkw->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__);
			RSVP(nkw);
			return;
		}else{
		  RSVP(report_card.tbl_entry_->symbol_);
		  return;
		}      
    }
    T_identifier* id = new T_identifier(fsm->data_.c_str());
    id->set_rc(*rule_info__.parser__->start_token__,__FILE__,__LINE__);
    RSVP(id);
  ***
  }
)
{
  -> Rstart_char |.| 
  -> Rstart_char Rtail_chars |.| 
}

Rtail_chars	 (){
  -> Rtail_char  
  -> Rtail_chars Rtail_char  
}
Rstart_char	 ()  {
  -> RUPPER_A_M  
  -> RUPPER_N_Z  
  -> Rlower_a_m  
  -> Rlower_n_z  
}

Rtail_char	 () {
  -> Rstart_char
  -> Rno_and_underscore_and_hyphen
}

Rno_and_underscore_and_hyphen	 () {
  -> ":" {
  /@
  Extend to pull in the threads.
  @/
    op
      Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
      fsm->data_ += sf->p1__->id__;
    ***
    }
  -> "." {
  /@
  Extend to pull in non-quoted file names with extension.
  Normally this is generated by the frontend \Yacco2
  as a quoted string but this extension
   allows the possible tampering by
  the compiler writer to play with things
  when things aren't going well by the front-end.
  It's a minor relief to help out the compiler writer.
  @/
    op
      Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
      fsm->data_ += sf->p1__->id__;
    ***
    }
  -> "_" {
    op
      Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
      fsm->data_ += sf->p1__->id__;
    ***
    }
  -> "-" {
    op
      Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
      fsm->data_ += sf->p1__->id__;
    ***
    }
  -> RNUMBERS
}

Rminus_la  () {
  -> "." 
  -> ":"  
  -> "_" 
  -> "-"  
  -> RUPPER_A_M  
  -> RUPPER_N_Z  
  -> Rlower_a_m  
  -> Rlower_n_z  
  -> RNUMBERS  
}

RUPPER_A_M   (
lhs {
  op
    Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
    size_t pos = rule_info__.parser__->parse_stack__.top_sub__ - 1;
    CAbs_lr1_sym* sym = rule_info__.parser__->get_spec_stack_token(pos);
    fsm->data_ += sym->id__;
  ***
  }
){
  -> A -> B -> C -> D -> E -> F -> G -> H -> I -> J -> K -> L -> M 
}

RUPPER_N_Z   (
lhs {
  op
    Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
    size_t pos = rule_info__.parser__->parse_stack__.top_sub__ - 1;
    CAbs_lr1_sym* sym = rule_info__.parser__->get_spec_stack_token(pos);
    fsm->data_ += sym->id__;
  ***
  }
){
  -> N -> O -> P -> Q 
  -> "R" // considered a Rule when not quoted!
  -> S -> T -> U -> V -> W -> X -> Y -> Z
}

Rlower_a_m   (
lhs {
  op
    Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
    size_t pos = rule_info__.parser__->parse_stack__.top_sub__ - 1;
    CAbs_lr1_sym* sym = rule_info__.parser__->get_spec_stack_token(pos);
    fsm->data_ += sym->id__;
  ***
  }
){
  -> a -> b -> c -> d -> e -> f -> g -> h -> i -> j -> k -> l -> m 
}

Rlower_n_z   (
lhs {
  op
    Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
    size_t pos = rule_info__.parser__->parse_stack__.top_sub__ - 1;
    CAbs_lr1_sym* sym = rule_info__.parser__->get_spec_stack_token(pos);
    fsm->data_ += sym->id__;
  ***
  }
){
  -> n -> o -> p -> q -> r -> s -> t -> u -> v -> w -> x -> y -> z
}

RNUMBERS   (
lhs {
  op
    Clinker_id* fsm = (Clinker_id*) rule_info__.parser__->fsm_tbl__;
    size_t pos = rule_info__.parser__->parse_stack__.top_sub__ - 1;
    CAbs_lr1_sym* sym = rule_info__.parser__->get_spec_stack_token(pos);
    fsm->data_ += sym->id__;
  ***
  }
){
  -> 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9
}
}// end of rules
