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.]])
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 YYTokenType.EOF;
131 auto c = input.front;
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;
152 m4_pushdef([AT_MAIN_DEFINE(d)],
156 auto p = new YYParser (l);
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]],
182 %token <int> NUM "number"
188 %token <val> NUM "number"
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; }
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],
232 [AT_TOKEN_RAW_IF([0], [1])[
235 AT_PARSER_CHECK([input], 0,
239 AT_BISON_OPTION_POPDEFS
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)])