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