@q file: constraints.w@> @q% Copyright Dave Bone 1998 - 2015@> @q% /*@> @q% This Source Code Form is subject to the terms of the Mozilla Public@> @q% License, v. 2.0. If a copy of the MPL was not distributed with this@> @q% file, You can obtain one at http://mozilla.org/MPL/2.0/.@> @q% */@> @** Constraints. Validation code snippets.\fbreak This is the source collector of all constraints used across Yacco2's code. Why one place insead of keeping the code close to the routines using them? Good question. Code comprehension demands that the code be within the the reading periphery of the programmer. But, code clutter can remove this advantage to understanding. |cweb| provides a better way to do it. You can still use the code clutter approach but it provides a better way. Just describe the code block with intention and reference it. No need to keep the code near by! Gardening chores are tidier, one-place-only to correct and improve. @ Invalid use of \QUEshift{} instead of \ALLshift{} symbol. @= @.Err Invalid \QUEshift{} instead of \ALLshift@> char a[BUFFER_SIZE]; yacco2::KCHARP msg = "Error - Bad use of |?| instead of |+| symbol or epsilon subrule. " "Correct %s grammar, parse state: %i. Cannot continue parsing."; sprintf(a,msg,fsm_tbl__->id__,parse_stack__.top__->state__->state_no__); Yacco2_faulty_precondition(a,__FILE__,__LINE__); exit(1); @ Validate any token for parsing. @= if (current_token__ == 0){ @.Err current token ptr zero. Cann...@> yacco2::KCHARP msg = "Error - current token ptr zero. Cannot continue parsing."; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate Line no parameter. @= if (Line_no < 1){@/ @.Err Line\_no not 1 or greater@> yacco2::KCHARP msg = "Error - Line_no not 1 or greater"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate Pos parameter. @= if (Pos < 1){@/ @.Err Pos not 1 or greater@> yacco2::KCHARP msg = "Error - Pos not 1 or greater"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate Pos in line parameter. @= if (Pos_in_line < 1){@/ @.Err Pos\_in\_line not 1 or great...@> yacco2::KCHARP msg = "Error - Pos_in_line not 1 or greater"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate File no parameter. @= if (File_no < 1){@/ @.Err File\_no not 1 or greater@> yacco2::KCHARP msg = "Error - File_no not 1 or greater"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate any symbol for co-ordinate setting to relate to?. @= if (pt == 0){@/ @.Err no supplier symbol found to ...@>; yacco2::KCHARP msg = "Error - no supplier symbol found to relate to for co-ordinate setting"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate parser's finite state table. @= if (parser->fsm_tbl__ == 0){@/ @.Err parser's finite state table ...@> yacco2::KCHARP msg = "Error - parser's finite state table is zero ptr"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate that parser stack is not empty. @= if (parser->parse_stack__.top_sub__ < 1) { @.Err parser's stack is empty@> yacco2::KCHARP msg = "Error - parser's stack is empty"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate if parser's supplier exists. @= if(token_supplier__ == 0){@/ @.Err parser's supplier is zero ptr@> yacco2::KCHARP msg = "Error - parser's supplier is zero ptr"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate if subscript within supplier's bnds. @= if (Pos > token_supplier__->size()){@/ @.Err Pos out of bounds against su...@> yacco2::KCHARP msg = "Error - Pos out of bounds against supplier"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate subscript not |<=| 0. The subscript must be a positive integer. This condition is now controlled by |Token_start_pos| macro. The original subscript is relative to 0. My preference is relative to 1. So, provide a mechanism to change in one place so that these conditions can be experimented with. @= if (Pos < Token_start_pos){ char a[BUFFER_SIZE]; @.Err Subcript Pos value < ...@> yacco2::KCHARP msg = "Error - Subcript Pos value < %i --- out of bounds"; sprintf(a,msg,Token_start_pos); Yacco2_faulty_precondition(a,__FILE__,__LINE__); exit(1); } @ Validate parse stack number of removal items. @= if (No_to_remove < 0){ @.Err parse stack number of remova...@> yacco2::KCHARP msg = "Error - parse stack number of removal items < 0"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Validate parse stack removal for underflow. @< Validate parse stack removal for underflow@>= if(parse_stack__.top_sub__ < 1) { char a[BUFFER_SIZE]; @.Err FSM id: ... parse stack empt...@> yacco2::KCHARP msg = "FSM id: %s parse stack empty!"; sprintf(a,msg,fsm_tbl__->id__); Yacco2_faulty_precondition(a,__FILE__,__LINE__); exit(1); } if (No_to_remove > MAX_LR_STK_ITEMS){ char a[BUFFER_SIZE]; @.Err Underflow FSM id: ...@> yacco2::KCHARP msg = "Error - Underflow FSM id: %s on parse stack size:%i removal request: %i "; sprintf(a,msg,fsm_tbl__->id__,MAX_LR_STK_ITEMS,No_to_remove); Yacco2_faulty_precondition(a,__FILE__,__LINE__); exit(1); } @ Validate error queue. @= if (error_queue__ == 0){ @.Err Trying to add to Parser erro...@> yacco2::KCHARP msg = "Error - Trying to add to Parser error_queue__ which is zero ptr"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Error shift symbol not fnd in fsm table.\fbreak The reason for not using a Error type T is that this is below the language being parsed. It would force having a pre-canned error terminal in the error class of the language being defined: lr constants and rc terminals are enough cement. That's the short of it. @= if(se == 0){ char a[BUFFER_SIZE]; @.Err Can't find symbol to shift i...@> yacco2::KCHARP msg = "Error - Can't find symbol to shift in FSM id: %s state: %i sym-id: %i literal: %s"; CAbs_lr1_sym* xxx = current_token(); sprintf(a,msg,fsm_tbl__->id__,pr->state__->state_no__,xxx->enumerated_id(),xxx->id()); Yacco2_faulty_precondition(a,__FILE__,__LINE__); yacco2::KCHARP msg2 = "T co-ordinates: file: %s GPS LINE: %i GPS CHR POS: %i"; sprintf(a,msg2 ,xxx->tok_co_ords__.external_file_id__ != MAX_USINT? yacco2::FILE_TBL__[xxx->tok_co_ords__.external_file_id__].c_str() :" No external file" ,xxx->tok_co_ords__.line_no__ ,xxx->tok_co_ords__.pos_in_line__); Yacco2_faulty_precondition(a,__FILE__,__LINE__); exit(1); } @ Validate if rule shift symbol in fsm table. @= if(se == 0){ char a[BUFFER_SIZE]; @.Err Cant find rule shift in stat...@> yacco2::KCHARP msg = "Error - Cant find rule shift in state FSM id: %s state: %i rule id: %i "; sprintf(a,msg,fsm_tbl__->id__,parse_stack__.top__->state__->state_no__ ,(*rule_rec)->rule_->enumerated_id__); Yacco2_faulty_precondition(a,__FILE__,__LINE__); exit(1); } @ Validate reduce entry. @= if(re == 0){ char a[BUFFER_SIZE]; @.Err Cant find parallel sym reduc...@> yacco2::KCHARP msg = "Error - Cant find parallel sym reduce in FSM id: %s state: %i token: %s subs: %i "; sprintf(a,msg,fsm_tbl__->id__,pr->state__->state_no__ ,current_token__->id__,current_token_pos__); Yacco2_faulty_precondition(a,__FILE__,__LINE__); exit(1); } @ Validate accept message. @< Validate accept message@>= if(arbitrated_token__->accept_token_pos__ == arbitrated_token__->la_token_pos__){ @.Err Parallel token boundry same ...@> yacco2::KCHARP msg = "Error - Parallel token boundry same as LA token boundry"; Yacco2_faulty_precondition(msg,__FILE__,__LINE__); exit(1); } @ Error bad character mapping. @= char a[BUFFER_SIZE]; @.Err Bad char mapping chr value: ...@> yacco2::KCHARP msg = "Error - Bad char mapping chr value: %i"; sprintf(a,msg,Char); Yacco2_faulty_precondition(a,__FILE__,__LINE__); exit(1); @ Error no more raw character storage. @= char a[BUFFER_SIZE]; @.Err Sorry run out of raw charact...@> yacco2::KCHARP msg = "Error - Sorry run out of raw character storage: need to regen Yacco2: %i"; sprintf(a,msg,SIZE_RC_MALLOC); Yacco2_faulty_precondition(a,__FILE__,__LINE__); exit(1);