bison-patches
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]