File: html.y

package info (click to toggle)
html-xml-utils 7.7-1.1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 2,488 kB
  • sloc: ansic: 11,213; sh: 7,996; lex: 243; makefile: 193; yacc: 125
file content (159 lines) | stat: -rw-r--r-- 5,008 bytes parent folder | download | duplicates (4)
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
%{
/*
 * Simple XML grammar, with call-back functions.
 *
 * Part of HTML-XML-utils, see:
 * http://www.w3.org/Tools/HTML-XML-utils/
 *
 * Copyright © 1994-2000 World Wide Web Consortium
 * See http://www.w3.org/Consortium/Legal/copyright-software
 *
 * Author: Bert Bos <bert@w3.org>
 * Created: 1997
 **/
#include "config.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "export.h"
#include "types.e"

/* The types of the various callback routines */

EXPORT typedef void (*html_handle_error_fn)
  (void *clientdata, const string s, int lineno);
EXPORT typedef void* (*html_handle_start_fn)
  (void);
EXPORT typedef void (*html_handle_end_fn)
  (void *clientdata);
EXPORT typedef void (*html_handle_comment_fn)
  (void *clientdata, const string commenttext);
EXPORT typedef void (*html_handle_text_fn)
  (void *clientdata, const string text);
EXPORT typedef void (*html_handle_decl_fn)
  (void *clientdata, const string gi, const string fpi, const string url);
EXPORT typedef void (*html_handle_pi_fn)
  (void *clientdata, const string pi_text);
EXPORT typedef void (*html_handle_starttag_fn)
  (void *clientdata, const string name, pairlist attribs);
EXPORT typedef void (*html_handle_emptytag_fn)
  (void *clientdata, const string name, pairlist attribs);
EXPORT typedef void (*html_handle_endtag_fn)
  (void *clientdata, const string name);
EXPORT typedef void (*html_handle_endincl_fn)
  (void *clientdata);

/* yyparse -- entry point for the parser */
EXPORT extern int yyparse(void);

/* Store client data */
static void *data;

/* All callback routines */
static struct {
  html_handle_error_fn error;
  html_handle_start_fn start;
  html_handle_end_fn end;
  html_handle_comment_fn comment;
  html_handle_text_fn text;
  html_handle_decl_fn decl;
  html_handle_pi_fn pi;
  html_handle_starttag_fn starttag;
  html_handle_emptytag_fn emptytag;
  html_handle_endtag_fn endtag;
  html_handle_endincl_fn endincl;
} h = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};

/* Routines to bind concrete routines to the callbacks */
EXPORT void set_error_handler(html_handle_error_fn f) {h.error = f;}
EXPORT void set_start_handler(html_handle_start_fn f) {h.start = f;}
EXPORT void set_end_handler(html_handle_end_fn f) {h.end = f;}
EXPORT void set_comment_handler(html_handle_comment_fn f) {h.comment = f;}
EXPORT void set_text_handler(html_handle_text_fn f) {h.text = f;}
EXPORT void set_decl_handler(html_handle_decl_fn f) {h.decl = f;}
EXPORT void set_pi_handler(html_handle_pi_fn f) {h.pi = f;}
EXPORT void set_starttag_handler(html_handle_starttag_fn f){h.starttag = f;}
EXPORT void set_emptytag_handler(html_handle_emptytag_fn f){h.emptytag = f;}
EXPORT void set_endtag_handler(html_handle_endtag_fn f) {h.endtag = f;}
EXPORT void set_endincl_handler(html_handle_endincl_fn f) {h.endincl = f;}

extern int yylex(void);
EXPORT int lineno = 1;		/* Line number in input file */

static int nrerrors = 0;
#define MAX_ERRORS_REPORTED 20

/* yyerror -- report parse error */ 
static void yyerror(const string s)
{
  nrerrors++;
  if (nrerrors < MAX_ERRORS_REPORTED)
    h.error(data, s, lineno);
  else if (nrerrors == MAX_ERRORS_REPORTED)
    h.error(data, "too many errors", lineno);
  else
    ; /* don't report any more errors */
}

/* call -- if the function exists, call it with the given aguments */
#define call(fn, args) do {if (fn) (fn)args;} while (0)
%}

%union {
    string s;
    pairlist p;
}

%token <s> TEXT COMMENT START END NAME STRING PROCINS
%token EMPTYEND DOCTYPE ENDINCL

%type <p> attribute attributes

%%

start
:					{data = h.start ? h.start() : NULL;}
    document				{call(h.end, (data));}
  ;
document
  : document COMMENT			{call(h.comment, (data, $2));}
  | document TEXT			{call(h.text, (data, $2));}
  | document starttag
  | document endtag
  | document decl
  | document PROCINS			{call(h.pi, (data, $2));}
  | document ENDINCL			{call(h.endincl, (data));}
  | document error
  | /* empty */
  ;
starttag
  : START attributes '>'		{call(h.starttag, (data, $1, $2));}
  | START attributes EMPTYEND		{call(h.emptytag, (data, $1, $2));}
  ;
attributes
  : attribute attributes		{$$ = $1; $$->next = $2;}
  | /* empty */				{$$ = NULL;}
  ;
attribute
  : NAME				{pairlist h = malloc(sizeof(*h));
					 assert(h != NULL); h->name = $1;
					 h->value=NULL; $$ = h;}
  | NAME '=' NAME			{pairlist h = malloc(sizeof(*h));
					 assert(h != NULL); h->name = $1;
					 h->value = $3; $$ = h;}
  | NAME '=' STRING			{pairlist h = malloc(sizeof(*h));
					 assert(h != NULL); h->name = $1;
					 h->value = $3; $$ = h;}
  ;
endtag
  : END '>'				{call(h.endtag, (data, $1));}
  ;
decl
  : DOCTYPE NAME NAME STRING STRING '>'	{call(h.decl, (data, $2, $4, $5));}
  | DOCTYPE NAME NAME STRING '>'	{if (strcasecmp($3, "public") == 0)
				     	   call(h.decl, (data, $2, $4, NULL));
					 else /* "system" */
					   call(h.decl, (data, $2, NULL, $4));}
  | DOCTYPE NAME '>'			{call(h.decl, (data, $2, NULL, NULL));}
  ;