diff options
author | Luis Ontanon <luis.ontanon@gmail.com> | 2005-09-10 17:29:15 +0000 |
---|---|---|
committer | Luis Ontanon <luis.ontanon@gmail.com> | 2005-09-10 17:29:15 +0000 |
commit | 96326c0b8617db336cb85d122b1e1e5a00644f2b (patch) | |
tree | ac7c2065c289737d9c131c768c1c153e55747890 /epan/dtd_grammar.lemon | |
parent | 541fd750b86a0fa3666c4ec2d917ff6c23a332f9 (diff) |
the dtd parser (still missing the glue) and few fixes to packet-xml.c
svn path=/trunk/; revision=15745
Diffstat (limited to 'epan/dtd_grammar.lemon')
-rw-r--r-- | epan/dtd_grammar.lemon | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/epan/dtd_grammar.lemon b/epan/dtd_grammar.lemon new file mode 100644 index 0000000000..fc98472c99 --- /dev/null +++ b/epan/dtd_grammar.lemon @@ -0,0 +1,151 @@ +%include { + +/* dtd_parser.lemon +* XML dissector for ethereal +* XML's DTD grammar +* +* Copyright 2005, Luis E. Garcia Ontanon <luis.ontanon@gmail.com> +* +* $Id $ +* +* Ethereal - Network traffic analyzer +* By Gerald Combs <gerald@ethereal.com> +* Copyright 1998 Gerald Combs +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include <glib.h> +#include "dtd.h" + + +static dtd_named_list_t* dtd_named_list_new(gchar* name, GPtrArray* list) { + dtd_named_list_t* nl = g_malloc(sizeof(dtd_named_list_t)); + + nl->name = name; + nl->list = list; + + return nl; +} + +static GPtrArray* g_ptr_array_join(GPtrArray* a, GPtrArray* b){ + + while(b->len > 0) { + g_ptr_array_add(a,g_ptr_array_remove_index_fast(b,0)); + } + + g_ptr_array_free(b,FALSE); + + return a; +} + +} + +%name DtdParse + +%extra_argument { dtd_build_data_t *bd } + +%token_destructor { + if ($$) { + if ($$->text) g_free($$->text); + if ($$->location) g_free($$->location); + g_free($$); + } +} + +%syntax_error { + if (!TOKEN) + g_string_sprintfa(bd->error,"syntax error at end of file"); + else + g_string_sprintfa(bd->error,"syntax error in %s at or before '%s': \n", bd->location,TOKEN->text); +} + +%parse_failure { + g_string_sprintfa(bd->error,"DTD parsing failure at %s\n",bd->location); +} + +%token_prefix TOKEN_ + +%token_type { dtd_token_data_t* } + +dtd ::= doctype. +dtd ::= dtd_parts. + +doctype ::= TAG_START DOCTYPE_KW NAME(Name) OPEN_BRACKET dtd_parts CLOSE_BRACKET TAG_STOP. { + bd->proto_name = g_strdown(g_strdup(Name->text)); +} + +dtd_parts ::= dtd_parts element(Element). { g_ptr_array_add(bd->elements,Element); } +dtd_parts ::= dtd_parts attlist(Attlist). { g_ptr_array_add(bd->attributes,Attlist); } +dtd_parts ::= element(Element). { g_ptr_array_add(bd->elements,Element); } +dtd_parts ::= attlist(Attlist). { g_ptr_array_add(bd->attributes,Attlist); } + +%type attlist { dtd_named_list_t* } +attlist(A) ::= TAG_START ATTLIST_KW NAME(B) attrib_list(TheList) TAG_STOP. { A = dtd_named_list_new(B->text,TheList); } + +%type element { dtd_named_list_t* } +element(A) ::= TAG_START ELEMENT_KW NAME(B) sub_elements(C) TAG_STOP. { A = dtd_named_list_new(B->text,C); } + +%type attrib_list { GPtrArray* } +attrib_list(A) ::= attrib_list(B) attrib(C). { g_ptr_array_add(B,C); A = B; } +attrib_list(A) ::= attrib(B). { A = g_ptr_array_new(); g_ptr_array_add(A,B); } + +%type attrib { gchar* } +attrib(A) ::= NAME(B) att_type att_default. { A = g_strdown(g_strdup(B->text)); } + +att_type ::= ATT_TYPE. +att_type ::= enumeration. + +att_default ::= ATT_DEF. +att_default ::= ATT_DEF_WITH_VALUE QUOTED. +att_default ::= QUOTED. +att_default ::= IMPLIED_KW. +att_default ::= REQUIRED_KW. + +enumeration ::= OPEN_PARENS enum_list CLOSE_PARENS. + +enum_list ::= enum_list PIPE enum_item. +enum_list ::= enum_item. +enum_list ::= enumeration. +enum_list ::= enum_list PIPE enumeration. + +enum_item ::= NAME. +enum_item ::= QUOTED. + + +%type sub_elements { GPtrArray* } +sub_elements(A) ::= sub_elements(B) STAR. {A=B;} +sub_elements(A) ::= sub_elements(B) PLUS. {A=B;} +sub_elements(A) ::= sub_elements(B) QUESTION. {A=B;} +sub_elements(A) ::= OPEN_PARENS ELEM_DATA CLOSE_PARENS. { A = g_ptr_array_new(); } +sub_elements(A) ::= OPEN_PARENS element_list(B) COMMA ELEM_DATA CLOSE_PARENS. { A = B; } +sub_elements(A) ::= OPEN_PARENS element_list(B) PIPE ELEM_DATA CLOSE_PARENS. { A = B; } +sub_elements(A) ::= OPEN_PARENS element_list(B) CLOSE_PARENS. { A = B; } +sub_elements(A) ::= EMPTY_KW. { A = g_ptr_array_new(); } + +%type element_list { GPtrArray* } +element_list(A) ::= element_list(B) COMMA element_child(C). { g_ptr_array_add(B,C); A = B; } +element_list(A) ::= element_list(B) PIPE element_child(C). { g_ptr_array_add(B,C); A = B; } +element_list(A) ::= element_child(B). { A = g_ptr_array_new(); g_ptr_array_add(A,B); } +element_list(A) ::= sub_elements(B). { A = B; } +element_list(A) ::= element_list(B) COMMA sub_elements(C). { A = g_ptr_array_join(B,C); } +element_list(A) ::= element_list(B) PIPE sub_elements(C). { A = g_ptr_array_join(B,C); } + +%type element_child { gchar* } +element_child(A) ::= NAME(B). { A = g_strdown(g_strdup(B->text)); } +element_child(A) ::= NAME(B) STAR. { A = g_strdown(g_strdup(B->text)); } +element_child(A) ::= NAME(B) QUESTION. { A = g_strdown(g_strdup(B->text)); } +element_child(A) ::= NAME(B) PLUS. { A = g_strdown(g_strdup(B->text)); } + |