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.]])
25 m4_pushdef([AT_RAW_YYLEX], [AT_LANG_DISPATCH([$0], $@)])
27 m4_define([AT_RAW_YYLEX(c)],
28 [#include <stdlib.h> /* abort */
31 static const char* input = "0-(1+2)*3/9";
45 ]AT_VAL[.val = c - '0';
47 case '+': return PLUS;
48 case '-': return MINUS;
49 case '*': return STAR;
50 case '/': return SLASH;
51 case '(': return LPAR;
52 case ')': return RPAR;
59 m4_define([AT_RAW_YYLEX(c++)],
60 [#include <stdlib.h> /* abort */
63 static const char* input = "0-(1+2)*3/9";
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])[;
92 m4_define([AT_RAW_YYLEX(d)],
93 [[import std.range.primitives;
96 auto yyLexer(R)(R range)
97 if (isInputRange!R && is (ElementType!R : dchar))
99 return new YYLexer!R(range);
104 return yyLexer("0-(1+2)*3/9");
107 class YYLexer(R) : Lexer
108 if (isInputRange!R && is (ElementType!R : dchar))
118 YYSemanticType semanticVal_;
119 public final @property YYSemanticType semanticVal ()
126 import std.uni : isNumber;
129 return TokenKind.END;
131 auto c = input.front;
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;
152 m4_pushdef([AT_MAIN_DEFINE(d)],
156 auto p = new YYParser (l);
161 m4_pushdef([AT_MAIN_DEFINE(java)],
164 public static void main (String[] args) throws IOException
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 ();
176 m4_define([AT_RAW_YYLEX(java)],
177 [[class CalcLexer implements Calc.Lexer {
181 public CalcLexer (InputStream is)
183 st = new StreamTokenizer (new StringReader ("0-(1+2)*3/9"));
185 st.eolIsSignificant (true);
186 st.whitespaceChars ('\t', '\t');
187 st.whitespaceChars (' ', ' ');
188 st.wordChars ('0', '9');
191 public void yyerror (String s)
193 System.err.println (s);
198 public Object getLVal () {
202 public int yylex () throws IOException {
203 int ttype = st.nextToken ();
206 case StreamTokenizer.TT_EOF:
208 case StreamTokenizer.TT_EOL:
210 case StreamTokenizer.TT_WORD:
211 yylval = new Integer (st.sval);
226 throw new AssertionError ("invalid character: " + ttype);
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]],
245 ]AT_LANG_MATCH([[c\|c++]], [[
253 %define api.prefix {Calc}
254 %define api.parser.class {Calc}
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;
264 ]AT_LANG_MATCH([c\|c++\|d],
266 %token <int> NUM "number"
272 %token <val> NUM "number"
276 [[%token <Integer> NUM "number"
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])[
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],
324 [AT_TOKEN_RAW_IF([0], [1])[
328 AT_PARSER_CHECK([input], 0,
332 AT_BISON_OPTION_POPDEFS
336 m4_foreach([b4_skel], [[yacc.c], [glr.c], [lalr1.cc], [glr.cc], [glr2.cc], [lalr1.java], [lalr1.d]],
337 [AT_TEST([%skeleton "]b4_skel["])
338 AT_TEST([%skeleton "]b4_skel[" %define api.token.raw])])
340 AT_TEST([%skeleton "lalr1.cc" %define api.token.raw %define api.value.type variant %define api.token.constructor])])
342 m4_popdef([AT_MAIN_DEFINE(java)])
343 m4_popdef([AT_MAIN_DEFINE(d)])