[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/4] tests: restructure for clarity
From: |
Akim Demaille |
Subject: |
[PATCH 4/4] tests: restructure for clarity |
Date: |
Sun, 23 Jun 2019 19:31:03 +0200 |
* tests/calc.at (AT_CALC_MAIN, AT_CALC_LEX): Rewrite on top of
AT_LANG_DISPATCH.
---
tests/calc.at | 297 +++++++++++++++++++++++++++-----------------------
1 file changed, 159 insertions(+), 138 deletions(-)
diff --git a/tests/calc.at b/tests/calc.at
index 77537610..79c40ac6 100644
--- a/tests/calc.at
+++ b/tests/calc.at
@@ -19,44 +19,13 @@
## Compile the grammar described in the documentation. ##
## ---------------------------------------------------- ##
+# -------------- #
+# AT_CALC_MAIN. #
+# -------------- #
-# ------------------------- #
-# Helping Autotest macros. #
-# ------------------------- #
+m4_pushdef([AT_CALC_MAIN], [AT_LANG_DISPATCH([$0], $@)])
-
-# _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
-# -----------------------------------------------
-# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or
-# 'calc-lex.cc'.
-#
-# Don't call this macro directly, because it contains some occurrences
-# of '$1' etc. which will be interpreted by m4. So you should call it
-# with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does.
-#
-# When %defines is not passed, generate a single self-contained file.
-# Otherwise, generate three: calc.y with the parser, calc-lex.c with
-# the scanner, and calc-main.c with "main()". This is in order to
-# stress the use of the generated parser header. To avoid code
-# duplication, AT_CALC_LEX and AT_CALC_MAIN contain the body of these
-# two later files.
-m4_define([_AT_DATA_CALC_Y],
-[m4_if([$1$2$3], $[1]$[2]$[3], [],
- [m4_fatal([$0: Invalid arguments: $@])])dnl
-
-AT_D_IF([m4_pushdef([AT_CALC_MAIN],
-[[int main (string[] args)
-{
- semantic_value result = 0;
- int count = 0;
-
- File input = args.length == 2 ? File (args[1], "r") : stdin;
- auto l = calcLexer (input);
- auto p = new YYParser (l);
- return !p.parse ();
-}
-]])],
-[m4_pushdef([AT_CALC_MAIN],
+m4_define([AT_CALC_MAIN(c)],
[[#include <assert.h>
#include <unistd.h>
@@ -113,9 +82,127 @@ main (int argc, const char **argv)
assert (global_count == count); (void) count;
return status;
}
-]])])
+]])
-AT_D_IF([m4_pushdef([AT_CALC_LEX],
+m4_copy([AT_CALC_MAIN(c)], [AT_CALC_MAIN(c++)])
+
+m4_define([AT_CALC_MAIN(d)],
+[[int main (string[] args)
+{
+ semantic_value result = 0;
+ int count = 0;
+
+ File input = args.length == 2 ? File (args[1], "r") : stdin;
+ auto l = calcLexer (input);
+ auto p = new YYParser (l);
+ return !p.parse ();
+}
+]])
+
+
+
+# --------------- #
+# AT_CALC_YYLEX. #
+# --------------- #
+
+m4_pushdef([AT_CALC_YYLEX], [AT_LANG_DISPATCH([$0], $@)])
+
+
+m4_define([AT_CALC_YYLEX(c)],
+[[#include <ctype.h>
+
+]AT_YYLEX_DECLARE_EXTERN[
+
+]AT_LOCATION_IF([
+static AT_YYLTYPE last_yylloc;
+])[
+static int
+get_char (]AT_YYLEX_FORMALS[)
+{
+ int res = getc (input);
+ ]AT_USE_LEX_ARGS[;
+]AT_LOCATION_IF([
+ last_yylloc = AT_LOC;
+ if (res == '\n')
+ {
+ AT_LOC_LAST_LINE++;
+ AT_LOC_LAST_COLUMN = 1;
+ }
+ else
+ AT_LOC_LAST_COLUMN++;
+])[
+ return res;
+}
+
+static void
+unget_char (]AT_YYLEX_PRE_FORMALS[ int c)
+{
+ ]AT_USE_LEX_ARGS[;
+]AT_LOCATION_IF([
+ /* Wrong when C == '\n'. */
+ AT_LOC = last_yylloc;
+])[
+ ungetc (c, input);
+}
+
+static int
+read_integer (]AT_YYLEX_FORMALS[)
+{
+ int c = get_char (]AT_YYLEX_ARGS[);
+ int res = 0;
+
+ ]AT_USE_LEX_ARGS[;
+ while (isdigit (c))
+ {
+ res = 10 * res + (c - '0');
+ c = get_char (]AT_YYLEX_ARGS[);
+ }
+
+ unget_char (]AT_YYLEX_PRE_ARGS[ c);
+
+ return res;
+}
+
+
+/*---------------------------------------------------------------.
+| Lexical analyzer returns an integer on the stack and the token |
+| NUM, or the ASCII character read if not a number. Skips all |
+| blanks and tabs, returns 0 for EOF. |
+`---------------------------------------------------------------*/
+
+]AT_YYLEX_PROTOTYPE[
+{
+ int c;
+ /* Skip white spaces. */
+ do
+ {
+]AT_LOCATION_IF(
+[ AT_LOC_FIRST_COLUMN = AT_LOC_LAST_COLUMN;
+ AT_LOC_FIRST_LINE = AT_LOC_LAST_LINE;
+])[
+ }
+ while ((c = get_char (]AT_YYLEX_ARGS[)) == ' ' || c == '\t');
+
+ /* Process numbers. */
+ if (isdigit (c))
+ {
+ unget_char (]AT_YYLEX_PRE_ARGS[ c);
+ ]AT_VAL[.ival = read_integer (]AT_YYLEX_ARGS[);
+ return ]AT_TOKEN_PREFIX[NUM;
+ }
+
+ /* Return end-of-file. */
+ if (c == EOF)
+ return ]AT_TOKEN_PREFIX[CALC_EOF;
+
+ /* Return single chars. */
+ return c;
+}
+]])
+
+m4_copy([AT_CALC_YYLEX(c)], [AT_CALC_YYLEX(c++)])
+
+m4_define([AT_CALC_YYLEX(d)],
[[import std.range.primitives;
import std.stdio;
@@ -216,99 +303,32 @@ class CalcLexer(R) : Lexer
return c;
}
}
-]])],
-[m4_pushdef([AT_CALC_LEX],
-[[#include <ctype.h>
-
-]AT_YYLEX_DECLARE_EXTERN[
-
-]AT_LOCATION_IF([
-static AT_YYLTYPE last_yylloc;
-])[
-static int
-get_char (]AT_YYLEX_FORMALS[)
-{
- int res = getc (input);
- ]AT_USE_LEX_ARGS[;
-]AT_LOCATION_IF([
- last_yylloc = AT_LOC;
- if (res == '\n')
- {
- AT_LOC_LAST_LINE++;
- AT_LOC_LAST_COLUMN = 1;
- }
- else
- AT_LOC_LAST_COLUMN++;
-])[
- return res;
-}
-
-static void
-unget_char (]AT_YYLEX_PRE_FORMALS[ int c)
-{
- ]AT_USE_LEX_ARGS[;
-]AT_LOCATION_IF([
- /* Wrong when C == '\n'. */
- AT_LOC = last_yylloc;
-])[
- ungetc (c, input);
-}
-
-static int
-read_integer (]AT_YYLEX_FORMALS[)
-{
- int c = get_char (]AT_YYLEX_ARGS[);
- int res = 0;
-
- ]AT_USE_LEX_ARGS[;
- while (isdigit (c))
- {
- res = 10 * res + (c - '0');
- c = get_char (]AT_YYLEX_ARGS[);
- }
-
- unget_char (]AT_YYLEX_PRE_ARGS[ c);
-
- return res;
-}
-
+]])
-/*---------------------------------------------------------------.
-| Lexical analyzer returns an integer on the stack and the token |
-| NUM, or the ASCII character read if not a number. Skips all |
-| blanks and tabs, returns 0 for EOF. |
-`---------------------------------------------------------------*/
-]AT_YYLEX_PROTOTYPE[
-{
- int c;
- /* Skip white spaces. */
- do
- {
-]AT_LOCATION_IF(
-[ AT_LOC_FIRST_COLUMN = AT_LOC_LAST_COLUMN;
- AT_LOC_FIRST_LINE = AT_LOC_LAST_LINE;
-])[
- }
- while ((c = get_char (]AT_YYLEX_ARGS[)) == ' ' || c == '\t');
-
- /* Process numbers. */
- if (isdigit (c))
- {
- unget_char (]AT_YYLEX_PRE_ARGS[ c);
- ]AT_VAL[.ival = read_integer (]AT_YYLEX_ARGS[);
- return ]AT_TOKEN_PREFIX[NUM;
- }
+# -------------- #
+# AT_DATA_CALC. #
+# -------------- #
- /* Return end-of-file. */
- if (c == EOF)
- return ]AT_TOKEN_PREFIX[CALC_EOF;
- /* Return single chars. */
- return c;
-}
-]])
-])
+# _AT_DATA_CALC_Y($1, $2, $3, [BISON-DIRECTIVES])
+# -----------------------------------------------
+# Produce 'calc.y' and, if %defines was specified, 'calc-lex.c' or
+# 'calc-lex.cc'.
+#
+# Don't call this macro directly, because it contains some occurrences
+# of '$1' etc. which will be interpreted by m4. So you should call it
+# with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does.
+#
+# When %defines is not passed, generate a single self-contained file.
+# Otherwise, generate three: calc.y with the parser, calc-lex.c with
+# the scanner, and calc-main.c with "main()". This is in order to
+# stress the use of the generated parser header. To avoid code
+# duplication, AT_CALC_YYLEX and AT_CALC_MAIN contain the body of these
+# two later files.
+m4_define([_AT_DATA_CALC_Y],
+[m4_if([$1$2$3], $[1]$[2]$[3], [],
+ [m4_fatal([$0: Invalid arguments: $@])])dnl
AT_DATA_GRAMMAR([calc.y],
[[/* Infix notation calculator--calc */
@@ -381,15 +401,15 @@ void location_print (FILE *o, Span s);
%code
{
-#include <assert.h>
-#include <string.h>
-#define USE(Var)
+ #include <assert.h>
+ #include <string.h>
+ #define USE(Var)
-FILE *input;
-static int power (int base, int exponent);
+ FILE *input;
+ static int power (int base, int exponent);
-]AT_YYERROR_DECLARE[
-]AT_YYLEX_DECLARE_EXTERN[
+ ]AT_YYERROR_DECLARE[
+ ]AT_YYLEX_DECLARE_EXTERN[
}
]])[
@@ -484,20 +504,18 @@ location_print (FILE *o, Span s)
]])])[
]AT_YYERROR_DEFINE[
]AT_DEFINES_IF([],
-[AT_CALC_LEX
+[AT_CALC_YYLEX
AT_CALC_MAIN])])
AT_DEFINES_IF([AT_DATA_SOURCE([[calc-lex.]AT_LANG_EXT],
[[#include "calc.]AT_LANG_HDR["
-]AT_CALC_LEX])
+]AT_CALC_YYLEX])
AT_DATA_SOURCE([[calc-main.]AT_LANG_EXT],
[[#include "calc.]AT_LANG_HDR["
]AT_CALC_MAIN])
])
-m4_popdef([AT_CALC_MAIN])
-m4_popdef([AT_CALC_LEX])
])# _AT_DATA_CALC_Y
@@ -902,3 +920,6 @@ AT_CHECK_CALC_LALR1_D([%define parse.error verbose %debug
%verbose])
#AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %verbose
%parse-param {semantic_value *result} %parse-param {int *count}])
#AT_CHECK_CALC_LALR1_D([%locations %define parse.error verbose %debug %define
api.prefix {calc} %verbose %parse-param {semantic_value *result} %parse-param
{int *count}])
+
+m4_popdef([AT_CALC_MAIN])
+m4_popdef([AT_CALC_YYLEX])
--
2.21.0