debug keys
[metze/wireshark/wip.git] / epan / dtd_grammar.lemon
1 %include {
2
3 /* dtd_parser.lemon
4  * XML dissector for wireshark
5  * XML's DTD grammar
6  *
7  * Copyright 2005, Luis E. Garcia Ontanon <luis@ontanon.org>
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * SPDX-License-Identifier: GPL-2.0-or-later
14  */
15
16 #include "config.h"
17
18 #include <stdio.h>
19 #include <glib.h>
20 #include <assert.h>
21 #include "dtd.h"
22 #include "dtd_parse.h"
23
24 static dtd_named_list_t* dtd_named_list_new(gchar* name, GPtrArray* list) {
25         dtd_named_list_t* nl = g_new(dtd_named_list_t,1);
26
27         nl->name = name;
28         nl->list = list;
29
30         return nl;
31 }
32
33 static GPtrArray* g_ptr_array_join(GPtrArray* a, GPtrArray* b){
34
35         while(b->len > 0) {
36                 g_ptr_array_add(a,g_ptr_array_remove_index_fast(b,0));
37         }
38
39         g_ptr_array_free(b,TRUE);
40
41         return a;
42 }
43
44 }
45
46 %name DtdParse
47
48 %extra_argument { dtd_build_data_t *bd }
49
50 %token_destructor {
51         (void) bd; /* Mark unused, similar to Q_UNUSED */
52         if ($$) {
53                 g_free($$->text);
54                 g_free($$->location);
55                 g_free($$);
56         }
57 }
58
59 %syntax_error {
60         if (!TOKEN)
61                 g_string_append_printf(bd->error,"syntax error at end of file");
62         else
63                 g_string_append_printf(bd->error,"syntax error in %s at or before '%s': \n", TOKEN->location,TOKEN->text);
64 }
65
66 %parse_failure {
67         g_string_append_printf(bd->error,"DTD parsing failure\n");
68 }
69
70 %token_prefix TOKEN_
71
72 %token_type { dtd_token_data_t* }
73
74 dtd ::= doctype.
75 dtd ::= dtd_parts.
76
77 doctype ::= TAG_START DOCTYPE_KW NAME(Name) OPEN_BRACKET dtd_parts CLOSE_BRACKET TAG_STOP. {
78         dtd_named_list_t* root;
79         GPtrArray* root_elems = g_ptr_array_new();
80         guint i;
81         gchar *name;
82
83         if(! bd->proto_name) {
84                 bd->proto_name = Name->text;
85         }
86
87         g_free(bd->proto_root);
88
89         bd->proto_root = Name->text;
90
91         name = g_ascii_strdown(bd->proto_name, -1);
92         g_free(bd->proto_name);
93         bd->proto_name = name;
94
95         for( i = 0; i< bd->elements->len; i++) {
96                 dtd_named_list_t* el = (dtd_named_list_t*)g_ptr_array_index(bd->elements,i);
97
98                 g_ptr_array_add(root_elems,g_strdup(el->name));
99         }
100
101         root = dtd_named_list_new(g_strdup(Name->text),root_elems);
102
103         g_ptr_array_add(bd->elements,root);
104
105         g_free(Name->location);
106         g_free(Name);
107
108 }
109
110 dtd_parts ::= dtd_parts element(Element). { g_ptr_array_add(bd->elements,Element); }
111 dtd_parts ::= dtd_parts attlist(Attlist). { g_ptr_array_add(bd->attributes,Attlist); }
112 dtd_parts ::= element(Element). { g_ptr_array_add(bd->elements,Element); }
113 dtd_parts ::= attlist(Attlist). { g_ptr_array_add(bd->attributes,Attlist); }
114
115 %type   attlist                         { dtd_named_list_t* }
116 attlist(A) ::= TAG_START ATTLIST_KW NAME(B) attrib_list(TheList) TAG_STOP. {
117         A = dtd_named_list_new(g_ascii_strdown(B->text, -1),TheList);
118         g_free(B->text);
119         g_free(B->location);
120         g_free(B);
121 }
122
123 %type element { dtd_named_list_t* }
124 element(A) ::= TAG_START ELEMENT_KW NAME(B) sub_elements(C) TAG_STOP. {
125         A = dtd_named_list_new(g_ascii_strdown(B->text, -1),C);
126         g_free(B->text);
127         g_free(B->location);
128         g_free(B);
129 }
130
131 %type   attrib_list                     { GPtrArray* }
132 attrib_list(A) ::= attrib_list(B) attrib(C). { g_ptr_array_add(B,C); A = B; }
133 attrib_list(A) ::= attrib(B).  { A = g_ptr_array_new(); g_ptr_array_add(A,B);  }
134
135 %type   attrib                          { gchar* }
136 attrib(A) ::= NAME(B) att_type att_default. {
137         A = g_ascii_strdown(B->text, -1);
138         g_free(B->text);
139         g_free(B->location);
140         g_free(B);
141 }
142
143 att_type ::= ATT_TYPE.
144 att_type ::= enumeration.
145
146 att_default ::= ATT_DEF.
147 att_default ::= ATT_DEF_WITH_VALUE QUOTED.
148 att_default ::= QUOTED.
149 att_default ::= IMPLIED_KW.
150 att_default ::= REQUIRED_KW.
151
152 enumeration ::= OPEN_PARENS enum_list CLOSE_PARENS.
153
154 enum_list ::= enum_list PIPE enum_item.
155 enum_list ::= enum_item.
156 enum_list ::= enumeration.
157 enum_list ::= enum_list PIPE enumeration.
158
159 enum_item ::= NAME.
160 enum_item ::= QUOTED.
161
162
163 %type   sub_elements            { GPtrArray* }
164 sub_elements(A) ::= sub_elements(B) STAR. {A=B;}
165 sub_elements(A) ::= sub_elements(B) PLUS. {A=B;}
166 sub_elements(A) ::= sub_elements(B) QUESTION. {A=B;}
167 sub_elements(A) ::= OPEN_PARENS ELEM_DATA CLOSE_PARENS. { A = g_ptr_array_new(); }
168 sub_elements(A) ::= OPEN_PARENS element_list(B) COMMA ELEM_DATA CLOSE_PARENS.   { A = B; }
169 sub_elements(A) ::= OPEN_PARENS element_list(B) PIPE ELEM_DATA CLOSE_PARENS.    { A = B; }
170 sub_elements(A) ::= OPEN_PARENS element_list(B) CLOSE_PARENS. { A = B; }
171 sub_elements(A) ::= EMPTY_KW. { A = g_ptr_array_new(); }
172
173 %type   element_list    { GPtrArray* }
174 element_list(A) ::= element_list(B) COMMA element_child(C).     { g_ptr_array_add(B,C); A = B; }
175 element_list(A) ::= element_list(B) PIPE element_child(C).      { g_ptr_array_add(B,C); A = B; }
176 element_list(A) ::= element_child(B).                                           { A = g_ptr_array_new(); g_ptr_array_add(A,B); }
177 element_list(A) ::= sub_elements(B).                                            { A = B; }
178 element_list(A) ::= element_list(B) COMMA sub_elements(C).      { A = g_ptr_array_join(B,C); }
179 element_list(A) ::= element_list(B) PIPE sub_elements(C).       { A = g_ptr_array_join(B,C); }
180
181 %type   element_child           { gchar* }
182 element_child(A) ::= NAME(B).                   {
183         A = g_ascii_strdown(B->text, -1);
184         g_free(B->text);
185         g_free(B->location);
186         g_free(B);
187 }
188
189 element_child(A) ::= NAME(B) STAR.              {
190         A = g_ascii_strdown(B->text, -1);
191         g_free(B->text);
192         g_free(B->location);
193         g_free(B);
194 }
195
196 element_child(A) ::= NAME(B) QUESTION.  {
197         A = g_ascii_strdown(B->text, -1);
198         g_free(B->text);
199         g_free(B->location);
200         g_free(B);
201 }
202
203 element_child(A) ::= NAME(B) PLUS.              {
204         A = g_ascii_strdown(B->text, -1);
205         g_free(B->text);
206         g_free(B->location);
207         g_free(B);
208 }
209