1 %{
2 /*
3 * Simple XML grammar, with call-back functions.
4 *
5 * Part of HTML-XML-utils, see:
6 * http://www.w3.org/Tools/HTML-XML-utils/
7 *
8 * Copyright © 1994-2000 World Wide Web Consortium
9 * See http://www.w3.org/Consortium/Legal/copyright-software
10 *
11 * Author: Bert Bos <bert@w3.org>
12 * Created: 1997
13 **/
14 #include "config.h"
15 #include <assert.h>
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include "export.h"
20 #include "types.e"
21
22 /* The types of the various callback routines */
23
24 EXPORT typedef void (*html_handle_error_fn)
25 (void *clientdata, const string s, int lineno);
26 EXPORT typedef void* (*html_handle_start_fn)
27 (void);
28 EXPORT typedef void (*html_handle_end_fn)
29 (void *clientdata);
30 EXPORT typedef void (*html_handle_comment_fn)
31 (void *clientdata, const string commenttext);
32 EXPORT typedef void (*html_handle_text_fn)
33 (void *clientdata, const string text);
34 EXPORT typedef void (*html_handle_decl_fn)
35 (void *clientdata, const string gi, const string fpi, const string url);
36 EXPORT typedef void (*html_handle_pi_fn)
37 (void *clientdata, const string pi_text);
38 EXPORT typedef void (*html_handle_starttag_fn)
39 (void *clientdata, const string name, pairlist attribs);
40 EXPORT typedef void (*html_handle_emptytag_fn)
41 (void *clientdata, const string name, pairlist attribs);
42 EXPORT typedef void (*html_handle_endtag_fn)
43 (void *clientdata, const string name);
44 EXPORT typedef void (*html_handle_endincl_fn)
45 (void *clientdata);
46
47 /* yyparse -- entry point for the parser */
48 EXPORT extern int yyparse(void);
49
50 /* Store client data */
51 static void *data;
52
53 /* All callback routines */
54 static struct {
55 html_handle_error_fn error;
56 html_handle_start_fn start;
57 html_handle_end_fn end;
58 html_handle_comment_fn comment;
59 html_handle_text_fn text;
60 html_handle_decl_fn decl;
61 html_handle_pi_fn pi;
62 html_handle_starttag_fn starttag;
63 html_handle_emptytag_fn emptytag;
64 html_handle_endtag_fn endtag;
65 html_handle_endincl_fn endincl;
66 } h = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
67
68 /* Routines to bind concrete routines to the callbacks */
set_error_handler(html_handle_error_fn f)69 EXPORT void set_error_handler(html_handle_error_fn f) {h.error = f;}
set_start_handler(html_handle_start_fn f)70 EXPORT void set_start_handler(html_handle_start_fn f) {h.start = f;}
set_end_handler(html_handle_end_fn f)71 EXPORT void set_end_handler(html_handle_end_fn f) {h.end = f;}
set_comment_handler(html_handle_comment_fn f)72 EXPORT void set_comment_handler(html_handle_comment_fn f) {h.comment = f;}
set_text_handler(html_handle_text_fn f)73 EXPORT void set_text_handler(html_handle_text_fn f) {h.text = f;}
set_decl_handler(html_handle_decl_fn f)74 EXPORT void set_decl_handler(html_handle_decl_fn f) {h.decl = f;}
set_pi_handler(html_handle_pi_fn f)75 EXPORT void set_pi_handler(html_handle_pi_fn f) {h.pi = f;}
set_starttag_handler(html_handle_starttag_fn f)76 EXPORT void set_starttag_handler(html_handle_starttag_fn f){h.starttag = f;}
set_emptytag_handler(html_handle_emptytag_fn f)77 EXPORT void set_emptytag_handler(html_handle_emptytag_fn f){h.emptytag = f;}
set_endtag_handler(html_handle_endtag_fn f)78 EXPORT void set_endtag_handler(html_handle_endtag_fn f) {h.endtag = f;}
set_endincl_handler(html_handle_endincl_fn f)79 EXPORT void set_endincl_handler(html_handle_endincl_fn f) {h.endincl = f;}
80
81 extern int yylex(void);
82 EXPORT int lineno = 1; /* Line number in input file */
83
84 static int nrerrors = 0;
85 #define MAX_ERRORS_REPORTED 20
86
87 /* yyerror -- report parse error */
yyerror(const string s)88 static void yyerror(const string s)
89 {
90 nrerrors++;
91 if (nrerrors < MAX_ERRORS_REPORTED)
92 h.error(data, s, lineno);
93 else if (nrerrors == MAX_ERRORS_REPORTED)
94 h.error(data, "too many errors", lineno);
95 else
96 ; /* don't report any more errors */
97 }
98
99 /* call -- if the function exists, call it with the given aguments */
100 #define call(fn, args) do {if (fn) (fn)args;} while (0)
101 %}
102
103 %union {
104 string s;
105 pairlist p;
106 }
107
108 %token <s> TEXT COMMENT START END NAME STRING PROCINS
109 %token EMPTYEND DOCTYPE ENDINCL
110
111 %type <p> attribute attributes
112
113 %%
114
115 start
116 : {data = h.start ? h.start() : NULL;}
117 document {call(h.end, (data));}
118 ;
119 document
120 : document COMMENT {call(h.comment, (data, $2));}
121 | document TEXT {call(h.text, (data, $2));}
122 | document starttag
123 | document endtag
124 | document decl
125 | document PROCINS {call(h.pi, (data, $2));}
126 | document ENDINCL {call(h.endincl, (data));}
127 | document error
128 | /* empty */
129 ;
130 starttag
131 : START attributes '>' {call(h.starttag, (data, $1, $2));}
132 | START attributes EMPTYEND {call(h.emptytag, (data, $1, $2));}
133 ;
134 attributes
135 : attribute attributes {$$ = $1; $$->next = $2;}
136 | /* empty */ {$$ = NULL;}
137 ;
138 attribute
139 : NAME {pairlist h = malloc(sizeof(*h));
140 assert(h != NULL); h->name = $1;
141 h->value=NULL; $$ = h;}
142 | NAME '=' NAME {pairlist h = malloc(sizeof(*h));
143 assert(h != NULL); h->name = $1;
144 h->value = $3; $$ = h;}
145 | NAME '=' STRING {pairlist h = malloc(sizeof(*h));
146 assert(h != NULL); h->name = $1;
147 h->value = $3; $$ = h;}
148 ;
149 endtag
150 : END '>' {call(h.endtag, (data, $1));}
151 ;
152 decl
153 : DOCTYPE NAME NAME STRING STRING '>' {call(h.decl, (data, $2, $4, $5));}
154 | DOCTYPE NAME NAME STRING '>' {if (strcasecmp($3, "public") == 0)
155 call(h.decl, (data, $2, $4, NULL));
156 else /* "system" */
157 call(h.decl, (data, $2, NULL, $4));}
158 | DOCTYPE NAME '>' {call(h.decl, (data, $2, NULL, NULL));}
159 ;
160