java: avoid Integer(String), use parseInt
[bison.git] / tests / scanner.at
blob1d1041b50303a60631cb9d304fbcd273eddd4b26
1 # Interface with the scanner.                           -*- Autotest -*-
3 # Copyright (C) 2019-2020 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   TokenKind yylex ()
125   {
126     import std.uni : isNumber;
127     // Handle EOF.
128     if (input.empty)
129       return TokenKind.END;
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 TokenKind.NUM;
140     case '+': return TokenKind.PLUS;
141     case '-': return TokenKind.MINUS;
142     case '*': return TokenKind.STAR;
143     case '/': return TokenKind.SLASH;
144     case '(': return TokenKind.LPAR;
145     case ')': return TokenKind.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 m4_pushdef([AT_MAIN_DEFINE(java)],
162 [[class input
164   public static void main (String[] args) throws IOException
165   {]AT_LEXPARAM_IF([[
166     ]AT_PARSER_CLASS[ p = new ]AT_PARSER_CLASS[ (System.in);]], [[
167     ]AT_API_prefix[Lexer l = new ]AT_API_prefix[Lexer (System.in);
168     ]AT_PARSER_CLASS[ p = new ]AT_PARSER_CLASS[ (l);]])AT_DEBUG_IF([[
169     //p.setDebugLevel (1);]])[
170     boolean success = p.parse ();
171     if (!success)
172       System.exit (1);
173   }
174 }]])
176 m4_define([AT_RAW_YYLEX(java)],
177 [[class CalcLexer implements Calc.Lexer {
179   StreamTokenizer st;
181   public CalcLexer (InputStream is)
182   {
183     st = new StreamTokenizer (new StringReader ("0-(1+2)*3/9"));
184     st.resetSyntax ();
185     st.eolIsSignificant (true);
186     st.whitespaceChars ('\t', '\t');
187     st.whitespaceChars (' ', ' ');
188     st.wordChars ('0', '9');
189   }
191   public void yyerror (String s)
192   {
193     System.err.println (s);
194   }
196   Integer yylval;
198   public Object getLVal () {
199     return yylval;
200   }
202   public int yylex() throws IOException {
203     int ttype = st.nextToken();
204     switch (ttype)
205       {
206       case StreamTokenizer.TT_EOF:
207         return EOF;
208       case StreamTokenizer.TT_EOL:
209         return (int) '\n';
210       case StreamTokenizer.TT_WORD:
211         yylval = Integer.parseInt(st.sval);
212         return NUM;
213       case '+':
214         return PLUS;
215       case '-':
216         return MINUS;
217       case '*':
218         return STAR;
219       case '/':
220         return SLASH;
221       case '(':
222         return LPAR;
223       case ')':
224         return RPAR;
225       default:
226         throw new AssertionError("invalid character: " + ttype);
227       }
228   }
233 ## ------------------- ##
234 ## Raw token numbers.  ##
235 ## ------------------- ##
237 m4_pushdef([AT_TEST],
239 AT_SETUP([Token numbers: $1])
241 AT_BISON_OPTION_PUSHDEFS([%debug ]m4_bmatch([$1], [java], [[%define api.prefix {Calc} %define api.parser.class {Calc}]])[ $1])
242 AT_DATA_GRAMMAR([[input.y]],
243 [[$1
244 %debug
245 ]AT_LANG_MATCH([[c\|c++]], [[
246 %code
248 #include <stdio.h>
249 ]AT_YYERROR_DECLARE[
250 ]AT_YYLEX_DECLARE[
251 }]],
252   [java], [[
253 %define api.prefix {Calc}
254 %define api.parser.class {Calc}
255 %code imports {
256   import java.io.IOException;
257   import java.io.InputStream;
258   import java.io.StringReader;
259   import java.io.Reader;
260   import java.io.StreamTokenizer;
262 ]])[
264 ]AT_LANG_MATCH([c\|c++\|d],
265 [AT_VARIANT_IF([[
266 %token <int> NUM "number"
267 %nterm <int> exp
268 ]], [[
269 %union {
270   int val;
272 %token <val> NUM "number"
273 %nterm <val> exp
274 ]])],
275     [java],
276 [[%token <Integer> NUM "number"
277 %type  <Integer> exp
278 ]])[
280 %token
281   PLUS  "+"
282   MINUS "-"
283   STAR  "*"
284   SLASH "/"
285   LPAR  "("
286   RPAR  ")"
287   END   0
289 %left "+" "-"
290 %left "*" "/"
294 input
295 : exp         { ]AT_JAVA_IF([[System.out.println ($][1)]], [[printf ("%d\n", $][1)]])[; }
299 : exp "+" exp { $][$][ = $][1 + $][3; }
300 | exp "-" exp { $][$][ = $][1 - $][3; }
301 | exp "*" exp { $][$][ = $][1 * $][3; }
302 | exp "/" exp { $][$][ = $][1 / $][3; }
303 | "(" exp ")" { $][$][ = $][2; }
304 | "number"    { $][$][ = $][1; }
308 ]AT_LANG_MATCH([c\|c++\|d],
309                [AT_YYERROR_DEFINE])[
310 ]AT_RAW_YYLEX[
311 ]AT_MAIN_DEFINE[
314 AT_FULL_COMPILE([input])
316 # When api.token.raw, the yytranslate table should not be included.
318 # yacc.c, glr.c and glr.cc use 'yytranslate' (and YYTRANSLATE).
319 # lalr1.cc uses 'translate_table' (and yytranslate_).
320 # lalr1.d uses 'byte[] translate_table =' (and yytranslate_).
321 # lalr1.java uses 'byte[] translate_table_ =' (and yytranslate_).
322 AT_CHECK([[$EGREP -c 'yytranslate\[\]|translate_table\[\]|translate_table =|translate_table_ =' input.]AT_LANG_EXT],
323          [ignore],
324          [AT_D_IF([AT_TOKEN_RAW_IF([0], [0])],
325                   [AT_TOKEN_RAW_IF([0], [1])])[
329 AT_PARSER_CHECK([input], 0,
330 [[-1
333 AT_BISON_OPTION_POPDEFS
334 AT_CLEANUP
337 m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc], [glr2.cc], [lalr1.java], [lalr1.d]],
338 [AT_TEST([%skeleton "]b4_skel["])
339  AT_TEST([%skeleton "]b4_skel[" %define api.token.raw])])
341 AT_TEST([%skeleton "lalr1.cc" %define api.token.raw %define api.value.type variant %define api.token.constructor])])
343 m4_popdef([AT_MAIN_DEFINE(java)])
344 m4_popdef([AT_MAIN_DEFINE(d)])
345 m4_popdef([AT_TEST])