warnings: pacify ‘gcc -Wchar-subscripts’ in yacc.c
[bison.git] / tests / scanner.at
blobc03dbbbdf8bc614c69129b6264a88250e1e886e5
1 # Interface with the scanner.                           -*- Autotest -*-
3 # Copyright (C) 2019 Free Software Foundation, Inc.
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 AT_BANNER([[Interface with the scanner.]])
21 # -------------- #
22 # AT_RAW_YYLEX.  #
23 # -------------- #
25 m4_pushdef([AT_RAW_YYLEX],   [AT_LANG_DISPATCH([$0], $@)])
27 m4_define([AT_RAW_YYLEX(c)],
28 [#include <stdlib.h> /* abort */
29 AT_YYLEX_PROTOTYPE[
31   static const char* input = "0-(1+2)*3/9";
32   int c = *input++;
33   switch (c)
34     {
35     case '0':
36     case '1':
37     case '2':
38     case '3':
39     case '4':
40     case '5':
41     case '6':
42     case '7':
43     case '8':
44     case '9':
45       ]AT_VAL[.val = c - '0';
46       return NUM;
47     case '+': return PLUS;
48     case '-': return MINUS;
49     case '*': return STAR;
50     case '/': return SLASH;
51     case '(': return LPAR;
52     case ')': return RPAR;
53     case 0:   return 0;
54     }
55   abort ();
57 ]])
59 m4_define([AT_RAW_YYLEX(c++)],
60 [#include <stdlib.h> /* abort */
61 AT_YYLEX_PROTOTYPE[
63   static const char* input = "0-(1+2)*3/9";
64   int c = *input++;
65   switch (c)
66     {
67     case '0':
68     case '1':
69     case '2':
70     case '3':
71     case '4':
72     case '5':
73     case '6':
74     case '7':
75     case '8':
76     case '9':]AT_TOKEN_CTOR_IF([[
77       return yy::parser::make_NUM (c - '0');]], [[
78       ]AT_VAL[.val = c - '0';
79       return yy::parser::token::NUM;]])[
80     case '+': return yy::parser::]AT_TOKEN_CTOR_IF([make_PLUS ()],  [token::PLUS])[;
81     case '-': return yy::parser::]AT_TOKEN_CTOR_IF([make_MINUS ()], [token::MINUS])[;
82     case '*': return yy::parser::]AT_TOKEN_CTOR_IF([make_STAR ()],  [token::STAR])[;
83     case '/': return yy::parser::]AT_TOKEN_CTOR_IF([make_SLASH ()], [token::SLASH])[;
84     case '(': return yy::parser::]AT_TOKEN_CTOR_IF([make_LPAR ()],  [token::LPAR])[;
85     case ')': return yy::parser::]AT_TOKEN_CTOR_IF([make_RPAR ()],  [token::RPAR])[;
86     case 0:   return yy::parser::]AT_TOKEN_CTOR_IF([make_END ()],   [token::END])[;
87     }
88   abort ();
90 ]])
92 m4_define([AT_RAW_YYLEX(d)],
93 [[import std.range.primitives;
94 import std.stdio;
96 auto yyLexer(R)(R range)
97   if (isInputRange!R && is (ElementType!R : dchar))
99   return new YYLexer!R(range);
102 auto yyLexer ()
104   return yyLexer("0-(1+2)*3/9");
107 class YYLexer(R) : Lexer
108   if (isInputRange!R && is (ElementType!R : dchar))
110   R input;
112   this(R r) {
113     input = r;
114   }
116   ]AT_YYERROR_DEFINE[
118   YYSemanticType semanticVal_;
119   public final @property YYSemanticType semanticVal ()
120   {
121     return semanticVal_;
122   }
124   int yylex ()
125   {
126     import std.uni : isNumber;
127     // Handle EOF.
128     if (input.empty)
129       return YYTokenType.EOF;
131     auto c = input.front;
132     input.popFront;
134     // Numbers.
135     switch (c)
136     {
137     case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
138       semanticVal_.val = c - '0';
139       return YYTokenType.NUM;
140     case '+': return YYTokenType.PLUS;
141     case '-': return YYTokenType.MINUS;
142     case '*': return YYTokenType.STAR;
143     case '/': return YYTokenType.SLASH;
144     case '(': return YYTokenType.LPAR;
145     case ')': return YYTokenType.RPAR;
146     default: assert(0);
147     }
148   }
152 m4_pushdef([AT_MAIN_DEFINE(d)],
153 [[int main ()
155   auto l = yyLexer ();
156   auto p = new YYParser (l);
157   return !p.parse ();
158 }]])
161 ## ------------------- ##
162 ## Raw token numbers.  ##
163 ## ------------------- ##
165 m4_pushdef([AT_TEST],
167 AT_SETUP([Token numbers: $1])
169 AT_BISON_OPTION_PUSHDEFS([%debug $1])
170 AT_DATA_GRAMMAR([[input.y]],
171 [[$1
172 %debug
173 ]AT_D_IF([], [[
174 %code
176 #include <stdio.h>
177 ]AT_YYERROR_DECLARE[
178 ]AT_YYLEX_DECLARE[
179 }]])[
181 ]AT_VARIANT_IF([[
182 %token <int> NUM "number"
183 %nterm <int> exp
184 ]], [[
185 %union {
186   int val;
188 %token <val> NUM "number"
189 %nterm <val> exp
190 ]])[
192 %token
193   PLUS  "+"
194   MINUS "-"
195   STAR  "*"
196   SLASH "/"
197   LPAR  "("
198   RPAR  ")"
199   END   0
201 %left "+" "-"
202 %left "*" "/"
206 input
207 : exp         { printf ("%d\n", $][1); }
211 : exp "+" exp { $][$][ = $][1 + $][3; }
212 | exp "-" exp { $][$][ = $][1 - $][3; }
213 | exp "*" exp { $][$][ = $][1 * $][3; }
214 | exp "/" exp { $][$][ = $][1 / $][3; }
215 | "(" exp ")" { $][$][ = $][2; }
216 | "number"    { $][$][ = $][1; }
220 ]AT_YYERROR_DEFINE[
221 ]AT_RAW_YYLEX[
222 ]AT_MAIN_DEFINE[
225 AT_FULL_COMPILE([input])
227 # yacc.c, glr.c and glr.cc use 'yytranslate' (and YYTRANSLATE).
228 # lalr1.cc uses 'translate_table' (and yytranslate_).
229 # lalr1.d uses 'byte[] translate_table =' (and yytranslate_).
230 AT_CHECK([[$EGREP -c 'yytranslate\[\]|translate_table\[\]|translate_table =' input.]AT_LANG_EXT],
231          [ignore],
232          [AT_TOKEN_RAW_IF([0], [1])[
235 AT_PARSER_CHECK([input], 0,
236 [[-1
239 AT_BISON_OPTION_POPDEFS
240 AT_CLEANUP
243 m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc], [lalr1.d]],
244 [AT_TEST([%skeleton "]b4_skel["])
245  AT_TEST([%skeleton "]b4_skel[" %define api.token.raw])])
247 AT_TEST([%skeleton "lalr1.cc" %define api.token.raw %define api.value.type variant %define api.token.constructor])])
249 m4_popdef([AT_MAIN_DEFINE(d)])
250 m4_popdef([AT_TEST])