1%{ 2 3 /* 4 * $Id: FormatParser.yy,v 1.6 2002/10/07 20:44:24 mcoletti Exp $ 5 * 6 */ 7 8/* 9 FormatParser.y 10 11 build parser by: 12 13 % bison -p sio_8211_yy FormatParser.y 14 15*/ 16 17// #define yymaxdepth sio_8211_maxdepth 18// #define yyparse sio_8211_yyparse 19// #define yylex sio_8211_lex 20// #define yyerror sio_8211_error 21// #define yylval sio_8211_lval 22// #define yychar sio_8211_char 23// #define yydebug sio_8211_debug 24// #define yypact sio_8211_pact 25// #define yyr1 sio_8211_r1 26// #define yyr2 sio_8211_r2 27// #define yydef sio_8211_def 28// #define yychk sio_8211_chk 29// #define yypgo sio_8211_pgo 30// #define yyact sio_8211_act 31// #define yyexca sio_8211_exca 32// #define yyerrflag sio_8211_errflag 33// #define yynerrs sio_8211_nerrs 34// #define yyps sio_8211_ps 35// #define yypv sio_8211_pv 36// #define yys sio_8211_s 37// #define yy_yys sio_8211_yys 38// #define yystate sio_8211_state 39// #define yytmp sio_8211_tmp 40// #define yyv sio_8211_v 41// #define yy_yyv sio_8211_yyv 42// #define yyval sio_8211_val 43// #define yylloc sio_8211_lloc 44// #define yyreds sio_8211_reds 45// #define yytoks sio_8211_toks 46// #define yylhs sio_8211_yylhs 47// #define yylen sio_8211_yylen 48// #define yydefred sio_8211_yydefred 49// #define yydgoto sio_8211_yydgoto 50// #define yysindex sio_8211_yysindex 51// #define yyrindex sio_8211_yyrindex 52// #define yygindex sio_8211_yygindex 53// #define yytable sio_8211_yytable 54// #define yycheck sio_8211_yycheck 55// #define yyname sio_8211_yyname 56// #define yyrule sio_8211_yyrule 57 58 59 60#ifdef WIN32 61#pragma warning( disable : 4786 ) 62#include <malloc.h> 63#endif 64 65 66#include <ctype.h> /* toupper() */ 67 68#include <map> 69 70#include <string> 71 72#include <iostream> 73 74#include <cstdio> 75 76#include <cstdlib> 77 78#ifndef INCLUDED_SIO8211FIELDFORMAT_H 79#include "sdts++/io/sio_8211FieldFormat.h" 80#endif 81 82#ifndef INCLUDED_SIO_CONVERTER_H 83#include "sdts++/io/sio_Converter.h" 84#endif 85 86#ifndef INCLUDED_SIO_8211CONVERTER_H 87#include "sdts++/io/sio_8211Converter.h" 88#endif 89 90/* buffer containing current subfield format string */ 91 92extern const char * sio_8211_subfield_format_buffer; 93 94 95 96/* cursor into a subfield format to be set by the format string */ 97 98extern sio_8211FieldFormat::iterator current_sio_8211Subfield; 99 100 101 102/* hints for finding the _right_ converter for a given binary subfield -- should 103 be set by sio_8211MakeFieldFormat() */ 104 105extern sio_8211_converter_dictionary const* sio_8211_binary_converter_hints; 106 107extern int yylex(); 108 109// extern "C" { int yywrap() { return 1; } } 110 111extern "C" { int sio_8211_yywrap() { return 1; } } 112 113void yyerror(const char* s); 114 115void setConverter( sio_8211SubfieldFormat& sf ); 116 117void setType( char t, sio_8211SubfieldFormat& sf ); 118 119%} 120 121 122%union { 123 int i_val; 124 char c_val; 125} 126 127%token <i_val> NUMBER 128%token <c_val> TYPE 129%token <c_val> CHAR ',' 130%type <c_val> delimiter 131%left '(' 132 133 134%% 135 136format : '(' '(' n_base_list ')' ')' { } 137 | '(' n_base_list ')' { } 138 ; 139 140 141n_base : NUMBER base 142 { 143 // save an iterator for the first subfield 144 sio_8211FieldFormat::iterator first_sio_8211Subfield = 145 current_sio_8211Subfield; 146 147 current_sio_8211Subfield++; // skip the current subfield; it 148 // already has the proper value 149 150 151 // now the remaining N - 1 subfields need 152 // to get the _same_ data and semantic 153 // type as the first subfield; so, 154 // iterate through the next N - 1 155 // subfields, setting their type to that of the first subfield 156 157 for ( int i = 1; i < $1; i++ ) 158 { // assign the state of the first subfield format to the current one 159 (*current_sio_8211Subfield).setFormat( (*first_sio_8211Subfield).getFormat() ); 160 161 switch ( (*current_sio_8211Subfield).getFormat() ) 162 { 163 case sio_8211SubfieldFormat::fixed : 164 (*current_sio_8211Subfield).setLength( (*first_sio_8211Subfield).getLength() ); 165 break; 166 case sio_8211SubfieldFormat::variable : 167 (*current_sio_8211Subfield).setDelimiter( (*first_sio_8211Subfield).getDelimiter() ); 168 break; 169 } 170 171 // we set the type last so that the length can be properly resized in the case 172 // of binary subfields 173 174 (*current_sio_8211Subfield).setType( (*first_sio_8211Subfield).getType() ); 175 setConverter( *current_sio_8211Subfield ); 176 177 current_sio_8211Subfield++; 178 } 179 180 } 181 | NUMBER '(' n_base ')' { } 182 | base { current_sio_8211Subfield++; } 183 ; 184 185descriptor : '(' NUMBER ')' { (*current_sio_8211Subfield).setLength( $2 ); } 186 | '(' delimiter ')'{ (*current_sio_8211Subfield).setDelimiter( $2 ); } 187 ; 188 189n_base_list : n_base_list ',' n_base 190 | n_base 191 ; 192 193delimiter : ',' 194 | CHAR 195 ; 196 197base : TYPE descriptor 198 { 199 setType( $1, *current_sio_8211Subfield ); 200 setConverter( *current_sio_8211Subfield ); 201 } 202 | TYPE 203 { 204 setType( $1, *current_sio_8211Subfield ); 205 setConverter( *current_sio_8211Subfield ); 206 } 207 ; 208 209%% 210 211char* format_buffer; 212 213void 214yyerror(const char* s) 215{ 216 perror(s); 217} 218 219 220 221/* converters for use by setConverter */ 222 223static sio_8211Converter_A _A_converter; 224static sio_8211Converter_I _I_converter; 225static sio_8211Converter_R _R_converter; 226static sio_8211Converter_S _S_converter; 227 228 229 230void 231setConverter( sio_8211SubfieldFormat& sf ) 232{ 233 234 switch ( sf.getType() ) 235 { 236 case sio_8211SubfieldFormat::A : sf.setConverter( & _A_converter ); break; 237 238 case sio_8211SubfieldFormat::I : sf.setConverter( & _I_converter ); break; 239 240 case sio_8211SubfieldFormat::R : sf.setConverter( & _R_converter ); break; 241 242 case sio_8211SubfieldFormat::S : sf.setConverter( & _S_converter ); break; 243 244 case sio_8211SubfieldFormat::C : /* sf.setConverter( & _C_converter ); */ break; 245 246 case sio_8211SubfieldFormat::B : 247 { 248 /* if binary converters are supplied, 249 find one that matches the subfield 250 label and bind it to the current 251 subfield format -- if either of 252 those conditions fail, the 253 converter function will be null for 254 that subfield format. */ 255 256 if ( 0 != sio_8211_binary_converter_hints ) 257 { 258 sio_8211_converter_dictionary::const_iterator converter_itr = 259 (*sio_8211_binary_converter_hints).find( sf.getLabel() ); 260 261 // cerr << "looking for " << sf.getLabel() << "'s converter\n"; 262 263 if ( converter_itr != (*sio_8211_binary_converter_hints).end() ) 264 { 265 sf.setConverter( (*converter_itr).second ); 266 // cerr << "converter for " << sf.getLabel() << " found." << 267 // " Set to " << hex << (*converter_itr).second << dec << ".\n"; 268 } 269 else 270 { 271 // cerr << "converter for " << sf.getLabel() << " not found.\n"; 272 } 273 274 } 275 else 276 { 277 // cerr << __FILE__ << ":\tno binary converter hints\n"; 278 } 279 280 break; 281 } 282 283 case sio_8211SubfieldFormat::X : 284 /* sf.setConverter( & _X_converter ); */ 285 break; 286 287 default : break; 288 289 } 290 291 return; 292 293} /* setConverter() */ 294 295 296 297 298void 299setType( char t, sio_8211SubfieldFormat& sf ) 300{ 301 char type = toupper(t); /* upcase just in case */ 302 303 switch (type) 304 { 305 case 'A': sf.setType( sio_8211SubfieldFormat::A ); break; 306 307 case 'I': sf.setType( sio_8211SubfieldFormat::I ); break; 308 309 case 'R': sf.setType( sio_8211SubfieldFormat::R ); break; 310 311 case 'S': sf.setType( sio_8211SubfieldFormat::S ); break; 312 313 case 'C': sf.setType( sio_8211SubfieldFormat::C ); break; 314 315 case 'B': sf.setType( sio_8211SubfieldFormat::B ); break; 316 317 case 'X': sf.setType( sio_8211SubfieldFormat::X ); break; 318 319 default: return; 320 321 } 322 323} /* setType() */ 324 325 326 327#ifdef FOR_SLIGHTY_BENT_TESTING_PURPOSES 328int 329main() 330{ 331 string parse_string; 332 333 cout << "--> "; 334 335 cin >> parse_string; 336 337 cout << "you entered: " << parse_string << "\n"; 338 339 format_stream << parse_string << ends; 340 341 yyparse(); 342 343 exit(0); 344 345} 346 347#endif 348