source: svn/trunk/newcon3bcm2_21bu/dta/tests/unit_test/input_parser.c

Last change on this file was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 7.4 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2011, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: $
11 * $brcm_Revision: $
12 * $brcm_Date: $
13 *
14 * Module Description: parser for CCAD input file format
15 *
16 * Revision History:
17 *
18 * $brcm_Log: $
19 *
20 *
21 ***************************************************************************/
22
23#include "input_parser.h"
24
25#define EOF_SYMBOL '$'
26/*
27  Parser recognizes following tockens:
28  DIGIT - a hexdecimal digit 0-F or 0-f
29  COMMA - ,
30  COMMENT - #
31  NEWLINE - \r or \n or any combination of these
32  EOF - $ or any other symbol defined below
33  Anything else is ignored. Anything betwee COMMENT and NEWLINE is ignored
34  even if it is DIGIT or COMMA
35 */
36
37enum token_t {
38    TO_XDIGIT,
39    TO_COMMA,
40    TO_COMMENT,
41    TO_NEWLINE,
42    TO_EOF,
43    TO_OTHER
44};
45
46/* state_transitions[input][current_state] = new_state */
47int state_transitions [6][3] = 
48{
49    {1, 0, 2}, /* xdig */
50    {1, 1, 2}, /* comma */
51    {2, 2, 2}, /* comment */
52    {0, 1, 1}, /* nl */
53    {99, 99, 99}, /* eof */
54    {0, 1, 2}, /* other */
55};
56
57struct parser_data_t {
58    int ps;
59    int pps;
60    unsigned int number;
61    unsigned char * buffer;
62    unsigned int size;
63    unsigned int idx;
64};
65
66struct parser_data_t pd;
67
68int iparser_hex2nibble(int ch);
69
70enum token_t tokenize(int ch)
71{
72    if(('0' <= ch) && ('9' >= ch)){
73        return TO_XDIGIT;
74    }
75    if(('A' <= ch) && ('F' >= ch)){
76        return TO_XDIGIT;
77    }
78    if(('a' <= ch) && ('f' >= ch)){
79        return TO_XDIGIT;
80    }
81    switch(ch){
82    case ',':
83        return TO_COMMA;
84    case '#':
85        return TO_COMMENT;
86    case '\r':
87        return TO_NEWLINE;
88    case '\n':
89        return TO_NEWLINE;
90    case EOF_SYMBOL:
91        return TO_EOF;
92    default:
93        return TO_OTHER;
94    }
95    return TO_OTHER;
96}
97
98void iparser_init(unsigned char * buffer, unsigned int size)
99{
100    pd.number = 0;
101    pd.buffer = buffer;
102    pd.size = size;
103    pd.idx = 0;
104    pd.ps = 1;
105}
106
107int iparser_process(int ch)
108{
109    enum token_t tok;
110    int nps;    /* new parser state */
111    tok = tokenize(ch);
112
113    if(2 != pd.ps){
114        switch(tok){
115        case TO_XDIGIT:
116            pd.number = (pd.number << 4) | iparser_hex2nibble(ch);
117            break;
118        default:
119            break;
120        }
121    }
122    nps = state_transitions[tok][pd.ps];
123    if(nps != pd.ps){           /* changing state */
124        switch(pd.ps){
125        case 2:        /* coming out of consume */
126            pd.ps = pd.pps;     /* restore state */
127            return 0;
128        default:                /* all other states save state */
129            pd.pps = pd.ps;
130            break;
131        }
132    }
133    switch(nps){
134    case 1:
135        if(1 != pd.ps){
136            pd.buffer[pd.idx] = (unsigned char)pd.number;
137            pd.number = 0;
138            pd.idx++;
139            if(pd.idx >= pd.size){
140                pd.idx = pd.size - 1;
141                return -1;
142            }
143        }
144        break;
145    case MATCHED_EOF:
146        if(0 == pd.ps){
147            pd.buffer[pd.idx] = (unsigned char)pd.number;
148            pd.number = 0;
149            pd.idx++;
150        }
151        pd.ps = nps;
152        return MATCHED_EOF;
153    default:
154        break;
155    }
156    pd.ps = nps;
157    return 0;
158}
159
160unsigned int iparser_size(void)
161{
162    return pd.idx;
163}
164
165int iparser_hex2nibble(int ch)
166{
167    if(('0' <= ch) && ('9' >= ch)){
168        return (ch - '0');
169    }else if(('A' <= ch) && ('F' >= ch)){
170        return (ch - 'A' + 0xa);
171    }else{
172        return (ch - 'a' + 0xa);
173    }
174}
175
176
177/* enumeration to reduce size of the table */
178enum keyw_token_t {
179    KW_OTHER,
180    KW_A,
181    KW_D,
182    KW_R,
183    KW_P,
184    KW_I,
185    KW_M,
186    KW_S,
187    KW_G,
188    KW_EQ,
189    KW_SP,
190    KW_EOF,
191};
192
193enum keyw_token_t tokenize_keyw(int ch)
194{
195    switch(ch){
196    case 'A':
197        return KW_A;
198    case 'D':
199        return KW_D;
200    case 'R':
201        return KW_R;
202    case 'P':
203        return KW_P;
204    case 'I':
205        return KW_I;
206    case 'M':
207        return KW_M;
208    case 'S':
209        return KW_S;
210    case 'G':
211        return KW_G;
212    case '=':
213        return KW_EQ;
214    case ' ':
215        return KW_SP;
216    case EOF_SYMBOL:
217        return KW_EOF;
218    default:
219        break;   
220    }
221    return KW_OTHER;
222}
223
224/*
225  state 0 is starting state
226  state_transitions_keyw[input][current_state] = new_state
227  o - means other
228  5 - match ADDR=
229  8 - match PID=
230  14 - match MSG=
231  e - eof
232*/
233int state_transitons_keyw[12][14] = {
234    /*o*/ {00,00,00,00,00,00,00,00,00,00,00,00,00,00,},
235    /*A*/ { 1,00,00,00,00,00,00,00,00,00,00,00,00,00,},
236    /*D*/ {00,02,03,00,00,00,00, 8,00,00,00,00,00,00,},
237    /*R*/ { 0, 0, 0, 4, 0, 0, 0, 0, 0,00,00,00,00,00,},
238    /*P*/ { 6, 0, 0, 0, 0, 0, 0, 0, 0,00,00,00,00,00,},
239    /*I*/ { 0, 0, 0, 0, 0, 0, 7, 0, 0,00,00,00,00,00,},
240    /*M*/ {10, 0, 0, 0, 0, 0, 0, 0, 0,00,00,00,00,00,},
241    /*S*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0,00,11,00,00,00,},
242    /*G*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0,00,00,12,00,00,},
243    /*=*/ { 0, 0, 0, 0, 5, 0, 0, 0, 9,00,00,00,13,00,},
244    /* */ { 0, 0, 0, 0, 4, 0, 0, 0, 8,00,00,00,12,00,},
245    /*e*/ {99,99,99,99,99,99,99,99,99,99,99,99,99,99,},
246};
247
248struct fparser_data_t {
249    int ps;
250};
251
252struct fparser_data_t fpd;
253
254void iparser_init_keyw(void)
255{
256    fpd.ps = 0;                 /* set initial state */
257}
258
259int iparser_process_keyw(int ch)
260{
261    enum keyw_token_t tok;
262    int nps;                    /* new state */
263    tok = tokenize_keyw(ch);
264    nps = state_transitons_keyw[tok][fpd.ps];
265    switch(nps){
266    case MATCHED_ADDR:
267    case MATCHED_PID:
268    case MATCHED_MSG:
269        fpd.ps = 0;
270        return nps;
271    case MATCHED_EOF:
272        fpd.ps = 0;
273        return nps;
274    default:
275        break;
276    }
277    fpd.ps = nps;
278    return 0;
279}
280
281/* tokens for hex digits */
282enum hex_token_t {
283    HX_DIGIT,
284    HX_DELIM,
285    HX_OTHER,
286    HX_EOF,
287};
288
289enum hex_token_t tokenize_hex(int ch)
290{
291    switch(ch){
292    case '0': case '1': case '2': case '3': case '4': case '5':
293    case '6': case '7': case '8': case '9': case 'a': case 'b':
294    case 'c': case 'd': case 'e': case 'f': case 'A': case 'B':
295    case 'C': case 'D': case 'E': case 'F':
296        return HX_DIGIT;
297    case ' ': case ',': case '\r': case '\n':
298        return HX_DELIM;
299    case EOF_SYMBOL:
300        return HX_EOF;
301    default:
302        break;
303    }
304    return HX_OTHER;
305}
306
307int state_transitons_hex[4][2] = {
308    /*di*/ {01,01,},
309    /*de*/ {00,02,},
310    /*ot*/ {00,00,},
311    /*eo*/ {99,99,},
312};
313
314struct xparser_data_t {
315    int ps;
316    int value;
317};
318
319struct xparser_data_t xpd;
320
321void iparser_init_hex(void)
322{
323    xpd.ps = 0;
324    xpd.value = 0;
325}
326
327int iparser_process_hex(int ch, int * value)
328{
329    enum hex_token_t tok;
330    int nps;
331
332    tok = tokenize_hex(ch);
333    nps = state_transitons_hex[tok][xpd.ps];
334
335    if(HX_DIGIT == tok){
336        xpd.value = (xpd.value << 4) | iparser_hex2nibble(ch);
337    }
338    if(MATCHED_XNUMBER == nps){
339        *value = xpd.value;     /* return matched number */
340        xpd.value = 0;
341        xpd.ps = 0;
342        return MATCHED_XNUMBER;
343    }
344    if(MATCHED_EOF == nps){
345        *value = xpd.value;     /* return matched number */
346        xpd.value = 0;
347        xpd.ps = 0;
348        return MATCHED_EOF;
349    }
350    xpd.ps = nps;
351    return 0;
352}
Note: See TracBrowser for help on using the repository browser.