xref: /freebsd/contrib/com_err/parse.y (revision 5773cccf19ef7b97e56c1101aa481c43149224da)
1 %{
2 /*
3  * Copyright (c) 1998, 1999 Kungliga Tekniska H�gskolan
4  * (Royal Institute of Technology, Stockholm, Sweden).
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * 3. All advertising materials mentioning features or use of this software
19  *    must display the following acknowledgement:
20  *      This product includes software developed by Kungliga Tekniska
21  *      H�gskolan and its contributors.
22  *
23  * 4. Neither the name of the Institute nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  */
39 
40 #include "compile_et.h"
41 #if 0
42 RCSID("$Id: parse.y,v 1.9 1999/07/04 14:54:58 assar Exp $");
43 #endif
44 
45 void yyerror (char *s);
46 long name2number(const char *str);
47 void error_message(char *, ...);
48 
49 extern char *yytext;
50 
51 /* This is for bison */
52 
53 #if !defined(alloca) && !defined(HAVE_ALLOCA)
54 #define alloca(x) malloc(x)
55 #endif
56 
57 %}
58 
59 %union {
60   char *string;
61   int number;
62 }
63 
64 %token ET INDEX PREFIX EC ID END
65 %token <string> STRING
66 %token <number> NUMBER
67 
68 %%
69 
70 file		: /* */
71 		| header statements
72 		;
73 
74 header		: id et
75 		| et
76 		;
77 
78 id		: ID STRING
79 		{
80 		    id_str = $2;
81 		}
82 		;
83 
84 et		: ET STRING
85 		{
86 		    base = name2number($2);
87 		    strncpy(name, $2, sizeof(name));
88 		    name[sizeof(name) - 1] = '\0';
89 		    free($2);
90 		}
91 		| ET STRING STRING
92 		{
93 		    base = name2number($2);
94 		    strncpy(name, $3, sizeof(name));
95 		    name[sizeof(name) - 1] = '\0';
96 		    free($2);
97 		    free($3);
98 		}
99 		;
100 
101 statements	: statement
102 		| statements statement
103 		;
104 
105 statement	: INDEX NUMBER
106 		{
107 			number = $2;
108 		}
109 		| PREFIX STRING
110 		{
111 		    prefix = realloc(prefix, strlen($2) + 2);
112 		    strcpy(prefix, $2);
113 		    strcat(prefix, "_");
114 		    free($2);
115 		}
116 		| PREFIX
117 		{
118 		    prefix = realloc(prefix, 1);
119 		    *prefix = '\0';
120 		}
121 		| EC STRING ',' STRING
122 		{
123 		    struct error_code *ec = malloc(sizeof(*ec));
124 
125 		    ec->next = NULL;
126 		    ec->number = number;
127 		    if(prefix && *prefix != '\0') {
128 			asprintf (&ec->name, "%s%s", prefix, $2);
129 			free($2);
130 		    } else
131 			ec->name = $2;
132 		    ec->string = $4;
133 		    APPEND(codes, ec);
134 		    number++;
135 		}
136 		| END
137 		{
138 			YYACCEPT;
139 		}
140 		;
141 
142 %%
143 
144 long
145 name2number(const char *str)
146 {
147     const char *p;
148     long base = 0;
149     const char *x = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
150 	"abcdefghijklmnopqrstuvwxyz0123456789_";
151     if(strlen(str) > 4) {
152 	yyerror("table name too long");
153 	return 0;
154     }
155     for(p = str; *p; p++){
156 	char *q = strchr(x, *p);
157 	if(q == NULL) {
158 	    yyerror("invalid character in table name");
159 	    return 0;
160 	}
161 	base = (base << 6) + (q - x) + 1;
162     }
163     base <<= 8;
164     if(base > 0x7fffffff)
165 	base = -(0xffffffff - base + 1);
166     return base;
167 }
168 
169 void
170 yyerror (char *s)
171 {
172      error_message ("%s\n", s);
173 }
174