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