File: parser.y

package info (click to toggle)
libtrace3 3.0.7-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 3,676 kB
  • ctags: 3,140
  • sloc: ansic: 20,551; sh: 10,125; cpp: 1,384; makefile: 415; yacc: 96; lex: 50
file content (142 lines) | stat: -rw-r--r-- 3,385 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
%{
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <arpa/inet.h>
    #include <assert.h>
    #include "grammar.h"
    #include "libpacketdump.h"
    #include "bitbuffer.h"

    #define YYERROR_VERBOSE 1

    
    int yylex(void);

    char *file;
    element_t *el_list = NULL;

%}


%union {
    int intval;
    char *textval;
    element_t *ptr;
}

%token TOK_BIGENDIAN TOK_LITTLEENDIAN TOK_NEXT TOK_OUTPUT_INT TOK_OUTPUT_HEX TOK_OUTPUT_IPV4 TOK_OUTPUT_FLAG TOK_CONSTANT TOK_IDENTIFIER TOK_OUTPUT_MAC TOK_OUTPUT_NONE

%type <intval> TOK_BIGENDIAN TOK_LITTLEENDIAN TOK_NEXT TOK_OUTPUT_INT TOK_OUTPUT_HEX TOK_OUTPUT_IPV4 TOK_OUTPUT_FLAG TOK_OUTPUT_NONE TOK_CONSTANT output byteorder size '"'
%type <textval> TOK_IDENTIFIER identifier
%type <ptr> element nextfile elements

%%

config:	    elements nextfile { /*print_list(el_list);*/ }
	   ;
	
elements:   element 
	  | elements element { }
	  ;

element:    byteorder size output identifier { 
		node_t *n;
		element_t *el;
		/* create a new field node... */
	        field_t *new_field = (field_t *)malloc(sizeof(field_t)); 
		new_field->order = $1;
		new_field->size = $2;
		new_field->display = $3;
		new_field->identifier = $4;

		/* to go inside a new node... */
		n = (node_t *)malloc(sizeof(node_t));
		n->field = new_field;

		/* to go inside a new element */
		el = (element_t *)malloc(sizeof(element_t));		
		el->type = FIELD;
		el->next = NULL;
		el->data = n;
		
		/* and stick the new element on the end of our list */
		el_list = append(el_list, el);
	    }
	  ;

byteorder: TOK_BIGENDIAN { $$ = BIGENDIAN; }
	    | TOK_LITTLEENDIAN { $$ = LITTLEENDIAN; }
	  ;

size:	TOK_CONSTANT { $$ = yylval.intval; }
	;

output:   TOK_OUTPUT_HEX    { $$ = DISPLAY_HEX; }
	| TOK_OUTPUT_INT    { $$ = DISPLAY_INT; }
	| TOK_OUTPUT_IPV4   { $$ = DISPLAY_IPV4; }
	| TOK_OUTPUT_FLAG   { $$ = DISPLAY_FLAG; }
	| TOK_OUTPUT_MAC    { $$ = DISPLAY_MAC; }
	| TOK_OUTPUT_NONE   { $$ = DISPLAY_NONE; }
	;


identifier: TOK_IDENTIFIER { $$ = strdup($1); }
	    ;


nextfile:   TOK_NEXT identifier identifier { 

		element_t *tmp;
		node_t *n;
		element_t *el;
	        next_t *nextheader = (next_t *)malloc(sizeof(next_t)); 
		nextheader->prefix = $2;
		nextheader->fieldname = $3;
		nextheader->target = NULL;
		
		for(tmp = el_list ;; tmp=tmp->next)
		{
		    /* 
		     * if we hit the end of the list or a nextheader then
		     * the field name we are looking for doesn't exist
		     * - this is an error but we can carry on and just
		     * not bother parsing anything after this header
		     */
		    if(tmp == NULL || tmp->type == NEXTHEADER)
		    {
			fprintf(stderr, "XXX No field match found for "
					"nextfield '%s'...ignoring\n", $3);
			$$ = NULL;
			break;
		    }
		    
		    /* 
		     * if the field name matches the one we are looking at,
		     * store a pointer to it so we can steal its value later
		     */
		    if(strcmp($3, tmp->data->field->identifier) == 0)
		    {
			nextheader->target = tmp->data->field;
			break;
		    }
		}
		
		n = (node_t *)malloc(sizeof(node_t));
		n->nextheader = nextheader;

		el = (element_t *)malloc(sizeof(element_t));		
		el->type = NEXTHEADER;
		el->next = NULL;
		el->data = n;
		
		el_list = append(el_list, el);
	    }
	|   { /*printf("no next file...\n");*/ $$ = NULL; }
	;


%%