diff tests/agcl/examples/good/mas.cpp @ 0:13d2b8934445

Import AnaGram (near-)release tree into Mercurial.
author David A. Holland
date Sat, 22 Dec 2007 17:52:45 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/agcl/examples/good/mas.cpp	Sat Dec 22 17:52:45 2007 -0500
@@ -0,0 +1,1221 @@
+/*
+ * AnaGram, a System for Syntax Directed Programming
+ * C Macro preprocessor
+ * Macro argument substitution module
+ *
+ * Copyright 1993-2000 Parsifal Software. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#include "mpp.h"
+
+
+/*
+ * AnaGram, A System for Syntax Directed Programming
+ * File generated by: ...
+ *
+ * AnaGram Parsing Engine
+ * Copyright 1993-2002 Parsifal Software. All Rights Reserved.
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef MAS_H
+#include "mas.h"
+#endif
+
+#ifndef MAS_H
+#error Mismatched header file
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+
+#define RULE_CONTEXT (&((PCB).cs[(PCB).ssx]))
+#define ERROR_CONTEXT ((PCB).cs[(PCB).error_frame_ssx])
+#define CONTEXT ((PCB).cs[(PCB).ssx])
+
+
+#define CHANGE_REDUCTION(x) mas_change_reduction(mas_##x##_token)
+int mas_change_reduction(mas_token_type);
+
+#define INPUT_VALUE(type) *(type *) &(PCB).input_value
+
+#line - "mas.syn"
+                                      // Embedded C
+#include "array.h"                     // AnaGram\CLASSLIB\INCLUDE\array.h
+#include "stack.h"                     // AnaGram\CLASSLIB\INCLUDE\stack.h
+
+
+// Macro Definitions
+
+#define INPUT_CODE(T) (T).id
+#define PCB (*mas_pcb)
+#define SYNTAX_ERROR syntax_error(PCB.error_message);
+
+
+// Static variables
+
+typedef stack<unsigned>   unsigned_stack;      // accomodate broken compilers
+
+static unsigned_stack     active_macros(200,20);
+static token            **args;
+static int                args_only = 0;
+static mas_pcb_type      *mas_pcb;
+static int                n_concats = 0;
+static int                n_args;
+static unsigned          *params;
+static token_accumulator  space_stack(100);
+
+
+/*
+
+expand_text() is a shell procedure which calls the mas parser a
+number of times. It is used to expand arguments before substituting
+them into a macro, and to expand the body of a macro. Notice that
+expand_text() is recursive, since macros encountered during the an
+expansion process may themselves need to be expanded.
+
+expand_text() takes three explicit arguments:
+  token *text:
+    points to a string of tokens, terminated by an eof token.
+
+  int n:
+    specifies the number of arguments. Defaults to 0. The arguments
+    themselves are token strings on the token accumulator stack.
+    expand_text() makes copies of them and stores pointers to them in
+    the args array.
+
+  unsigned *p:
+    An array of n dictionary indices which gives the names of the
+    parameters for which the arguments are to be substituted. p
+    defaults to NULL.
+
+global switches
+  Two global switches affect the expansion of text: if_clause and
+  args_only.  Setting if_clause affects the treatment of the token
+  "defined". Setting args_only causes only macro parameters to be
+  expanded.
+
+*/
+
+void expand_text(token *text, int n, unsigned *p) {
+  mas_pcb_type pcb;
+
+// Save old status
+  mas_pcb_type *save_pcb = mas_pcb;
+  int save_n_args = n_args;
+  token **save_args = args;
+  unsigned *save_params = params;
+  int save_switch = args_only;
+
+// pop args from accumlator stack and expand them
+  args_only = 0;
+  token **new_args;
+  int k = n;
+  if (n) {
+    new_args = new token*[n];
+    args_only = 1;
+    while (k--) {
+    token t;
+    token top = *(token *) ta;
+    while (top.id == SPACE) ta >> t;             //trim space on right
+    array<token> arg_tokens(ta, size(ta) + 1);
+    token *tp = arg_tokens;
+    while (tp->id == SPACE) tp++;                //trim space on left
+    --ta;
+    mas_pcb = &pcb;
+    pcb.pointer = tp;
+    ++ta;
+    mas();
+      new_args[k] = copy(ta);
+      --ta;
+    }
+    args_only = 0;
+  }
+  else new_args = NULL;
+
+// Expand text
+  args = new_args;
+  n_args = n;
+  params = p;
+  pcb.pointer = text;
+  mas_pcb = &pcb;
+  ++ta;
+  ++active_macros;
+  n_concats = 0;
+  mas();
+
+// If any new tokens were created by concatenation, rescan
+  while (n_concats) {
+    array<token> expansion(ta,size(ta) + 1);
+    --ta;
+    pcb.pointer = expansion;
+    ++ta;
+    n_concats = 0;
+    n = size(active_macros);
+
+#ifdef _MSC_VER                  //Cope with peculiarity of MSVC++
+    while (n--) macro[*((unsigned *)active_macros + n)].busy_flag = 1;
+#else
+    while (n--) macro[active_macros[n]].busy_flag = 1;
+#endif
+    mas();
+  }
+  n = size(active_macros);
+#ifdef _MSC_VER                  //Cope with peculiarity of MSVC++
+    while (n--) macro[*((unsigned *)active_macros + n)].busy_flag = 0;
+#else
+  while (n--) macro[active_macros[n]].busy_flag = 0;
+#endif
+  --active_macros;
+
+// Discard argument strings
+
+  n = n_args;
+  while (n--) delete [] args[n];
+  if (n_args) delete [] args;
+
+// Restore old status
+
+  args_only = save_switch;
+  args = save_args;
+  n_args = save_n_args;
+  params = save_params;
+  mas_pcb = save_pcb;
+}
+
+/*
+
+expand_macro() is a shell procedure which sets up a call to
+expand_text for a specific macro.
+
+*/
+
+void expand_macro(token t, unsigned n_args) {
+  unsigned id = macro_id[t.handle];
+  token *body = macro[id].body;
+  assert(n_args == macro[id].n_args);
+  if (body == NULL) {
+    while (n_args--) --ta;
+    ++ta;
+    return;
+  }
+  expand_text(body,n_args,macro[id].arg_names);
+}
+
+/*
+
+expand_arg() is another shell procedure for expand_text() which does
+a complete expansion of a single macro argument.
+
+*/
+
+static void expand_arg(unsigned n) {
+  expand_text(args[n]);
+  concat(ta);
+}
+
+/*
+
+id_macro() is very nearly the same as id_macro() in TS.SYN. The
+primary difference is that this one deals in tokens, the other in
+character strings.
+
+*/
+
+static token id_macro(token t) {
+  unsigned n = n_args;
+  unsigned id;
+
+  while (n--) if (t.handle == params[n]) {
+    CHANGE_REDUCTION(parameter_name);
+    t.handle = n;
+    return t;
+  }
+  if (args_only) return t;
+  if (if_clause && t.handle == defined_value) {
+    CHANGE_REDUCTION(defined);
+    return t;
+  }
+  id = macro_id[t.handle];
+  if (id == 0) return t;
+  if (macro[id].busy_flag) return t;
+  active_macros << id;
+  if (macro[id].parens) CHANGE_REDUCTION(macro);
+  else CHANGE_REDUCTION(simple_macro);
+  return t;
+}
+
+/*
+
+defined() is very nearly the same as defined() in TS.SYN. The primary
+difference is that this one deals in tokens, the other in character
+strings.
+
+*/
+
+static token defined(unsigned handle) {
+  token t;
+  t.id = DECconstant;
+  t.handle = macro_id[handle] ? one_value : zero_value;
+  return t;
+}
+
+/*
+
+concatenate() implements the splicing together of two tokens by the
+"##" operator in a macro definition. Because of the way the grammar
+has been written, spaces have already been trimmed on both sides of the
+## by the parser.
+
+If there are actually two tokens to concatenate, the last token on
+the left is popped off, its string value is obtained from the token
+dictionary and pushed onto the string accumulator, ditto for the
+first token on the right. The string is then identified and the token
+is classified. If the new token is the name of a macro, a new scan
+will be required to expand it.
+
+*/
+
+static void concatenate(void) {
+  array<token> right_arg(ta, size(ta) + 1);
+  token t;
+  token *tp = right_arg;
+
+  --ta;                // discard right argument from stack
+
+  if (size(ta) && tp->id != END_OF_FILE) {
+    ta >> t;                               // pop left token
+    ++sa << td[t.handle] << td[tp->handle];      // left string + right string
+    t.handle = td << sa.top();             // identify string
+    t.id  = classify_token(sa.top());      // classify token
+    --sa;                                  // discard string
+    ++tp;                                  // discard old token on right
+    if (macro_id[t.handle]) n_concats++;      // if macro, signal rescan
+    ta << t;                               // output new token
+  }
+  ta << tp;                                // remainder of right side
+}
+
+/*
+
+make_string() implements the '#' operator in macro expansions, that
+is, it turns its operand into a string constant. To do this it must
+provide "" marks and must quote any embedded " or \ characters with
+the \ character.
+
+*/
+
+static token make_string(unsigned n) {
+  token *tp;
+  token t;
+
+  tp = args[n];
+  ++sa << '"';
+  while (tp->id != END_OF_FILE) {
+    char *p = td[tp->handle];
+    char c;
+    while ((c = *p++) != 0) {
+      if (c == '"' || c == '\\') sa << '\\';
+      sa << c;
+    }
+    tp++;
+  }
+  sa << '"';
+  t.id = STRINGliteral;
+  t.handle = td << sa.top();
+  --sa;
+  return t;
+}
+
+#line - "mas.cpp"
+
+#ifndef CONVERT_CASE
+#define CONVERT_CASE(c) (c)
+#endif
+#ifndef TAB_SPACING
+#define TAB_SPACING 8
+#endif
+
+static void ag_rp_1(void) {
+#line - "mas.syn"
+  reset(space_stack);
+#line - "mas.cpp"
+}
+
+static void ag_rp_2(token s) {
+#line - "mas.syn"
+if (args_only) space_stack << s;
+#line - "mas.cpp"
+}
+
+static void ag_rp_3(void) {
+#line - "mas.syn"
+  ta << space_stack;
+#line - "mas.cpp"
+}
+
+static void ag_rp_4(void) {
+#line - "mas.syn"
+  ta << space_stack;
+#line - "mas.cpp"
+}
+
+static void ag_rp_5(token t) {
+#line - "mas.syn"
+  ta << t << space_stack;
+#line - "mas.cpp"
+}
+
+static void ag_rp_6(token t) {
+#line - "mas.syn"
+  ta << t;
+#line - "mas.cpp"
+}
+
+static void ag_rp_7(token n) {
+#line - "mas.syn"
+  ta << make_string(n.handle);
+#line - "mas.cpp"
+}
+
+static void ag_rp_8(token t) {
+#line - "mas.syn"
+  ta << t;
+#line - "mas.cpp"
+}
+
+static void ag_rp_9(token t) {
+#line - "mas.syn"
+  expand_macro(t,0), concat(ta);
+#line - "mas.cpp"
+}
+
+static void ag_rp_10(token t, unsigned n) {
+#line - "mas.syn"
+  expand_macro(t,n), concat(ta);
+#line - "mas.cpp"
+}
+
+static void ag_rp_11(token n) {
+#line - "mas.syn"
+  ta << defined(n.handle);
+#line - "mas.cpp"
+}
+
+static token ag_rp_12(token n) {
+#line - "mas.syn"
+  return n;
+#line - "mas.cpp"
+}
+
+static token ag_rp_13(token n) {
+#line - "mas.syn"
+  return n;
+#line - "mas.cpp"
+}
+
+static token ag_rp_14(token n) {
+#line - "mas.syn"
+  return id_macro(n);
+#line - "mas.cpp"
+}
+
+static void ag_rp_15(token name) {
+#line - "mas.syn"
+  expand_arg(name.handle), ta << space_stack;
+#line - "mas.cpp"
+}
+
+static void ag_rp_16(token name) {
+#line - "mas.syn"
+  ta << args[name.handle], concatenate();
+#line - "mas.cpp"
+}
+
+static void ag_rp_17(void) {
+#line - "mas.syn"
+  concatenate();
+#line - "mas.cpp"
+}
+
+static void ag_rp_18(token n) {
+#line - "mas.syn"
+  ta << args[n.handle], ++ta;
+#line - "mas.cpp"
+}
+
+static void ag_rp_19(void) {
+#line - "mas.syn"
+  ++ta;
+#line - "mas.cpp"
+}
+
+static void ag_rp_20(token t) {
+#line - "mas.syn"
+  ta << t, ++ta;
+#line - "mas.cpp"
+}
+
+static void ag_rp_21(void) {
+#line - "mas.syn"
+  ++ta;
+#line - "mas.cpp"
+}
+
+static void ag_rp_22(token t) {
+#line - "mas.syn"
+  ta << t;
+#line - "mas.cpp"
+}
+
+static void ag_rp_23(token n) {
+#line - "mas.syn"
+  ta << make_string(n.handle);
+#line - "mas.cpp"
+}
+
+static void ag_rp_24(token t) {
+#line - "mas.syn"
+  ta << t;
+#line - "mas.cpp"
+}
+
+static unsigned ag_rp_25(void) {
+#line - "mas.syn"
+  return 0;
+#line - "mas.cpp"
+}
+
+static unsigned ag_rp_26(void) {
+#line - "mas.syn"
+  return 1;
+#line - "mas.cpp"
+}
+
+static unsigned ag_rp_27(unsigned n) {
+#line - "mas.syn"
+  return n+1;
+#line - "mas.cpp"
+}
+
+static void ag_rp_28(token t) {
+#line - "mas.syn"
+  ++ta << t;
+#line - "mas.cpp"
+}
+
+static void ag_rp_29(token t) {
+#line - "mas.syn"
+  ta << t;
+#line - "mas.cpp"
+}
+
+static void ag_rp_30(token t) {
+#line - "mas.syn"
+  ta << t;
+#line - "mas.cpp"
+}
+
+static void ag_rp_31(token t) {
+#line - "mas.syn"
+  concat(ta) << t;
+#line - "mas.cpp"
+}
+
+static void ag_rp_32(token t) {
+#line - "mas.syn"
+  ++ta << t;
+#line - "mas.cpp"
+}
+
+static void ag_rp_33(token t) {
+#line - "mas.syn"
+  ta << t;
+#line - "mas.cpp"
+}
+
+
+#ifndef AG_TRACE_FILE_NAME
+#define AG_TRACE_FILE_NAME "mas.etr"
+#endif
+
+static void ag_trace_error(void) {
+  FILE *ag_file = fopen(AG_TRACE_FILE_NAME, "w");
+  int i;
+  if (ag_file == NULL) return;
+  fprintf(ag_file, "%d\n", (PCB).ssx);
+  for (i = 0; i < (PCB).ssx; i++) fprintf(ag_file, "%d\n", (PCB).ss[i]);
+  fprintf(ag_file, "%d\n", (PCB).sn);
+  fprintf(ag_file, "%d\n", (PCB).token_number);
+  fclose(ag_file);
+}
+
+
+#define READ_COUNTS 
+#define WRITE_COUNTS 
+#undef V
+#define V(i,t) (*t (&(PCB).vs[(PCB).ssx + i]))
+#undef VS
+#define VS(i) (PCB).vs[(PCB).ssx + i]
+
+#ifndef GET_CONTEXT
+#define GET_CONTEXT CONTEXT = (PCB).input_context
+#endif
+
+typedef enum {
+  ag_action_1,
+  ag_action_2,
+  ag_action_3,
+  ag_action_4,
+  ag_action_5,
+  ag_action_6,
+  ag_action_7,
+  ag_action_8,
+  ag_action_9,
+  ag_action_10,
+  ag_action_11,
+  ag_action_12
+} ag_parser_action;
+
+
+#ifndef NULL_VALUE_INITIALIZER
+#define NULL_VALUE_INITIALIZER = { 0 }
+#endif
+
+static mas_vs_type const ag_null_value NULL_VALUE_INITIALIZER;
+
+static const unsigned char ag_rpx[] = {
+    0,  0,  0,  0,  0,  0,  1,  2,  0,  3,  4,  5,  6,  7,  8,  9, 10, 11,
+   12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,  0,  0,  0,  0, 25,
+   26, 27, 28, 29, 30, 31,  0,  0, 32,  0, 33
+};
+
+#define AG_TCV(x) ag_tcv[(x)]
+
+static const unsigned char ag_tcv[] = {
+    6, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,  7, 34, 34, 13,
+   34, 34, 34, 34, 17, 19, 34, 34, 28, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 25, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 22, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
+   34, 34, 34, 34
+};
+
+#ifndef SYNTAX_ERROR
+#define SYNTAX_ERROR fprintf(stderr,"%s\n", (PCB).error_message)
+#endif
+
+#ifndef PARSER_STACK_OVERFLOW
+#define PARSER_STACK_OVERFLOW {fprintf(stderr, \
+  "\nParser stack overflow\n");}
+#endif
+
+#ifndef REDUCTION_TOKEN_ERROR
+#define REDUCTION_TOKEN_ERROR {fprintf(stderr, \
+  "\nReduction token error\n");}
+#endif
+
+
+#ifndef INPUT_CODE
+#define INPUT_CODE(T) (T)
+#endif
+
+
+
+static const int ag_rtt[] = {
+   15, 14, 16, 11, 20,  0
+};
+
+static const unsigned char ag_tstt[] = {
+34,28,22,19,17,13,7,6,0,1,2,
+34,28,22,19,17,13,7,6,0,3,4,5,8,9,10,11,14,15,16,20,23,
+34,28,22,19,17,13,7,0,1,
+22,17,7,0,1,21,
+22,0,14,
+34,28,25,22,19,17,13,7,6,0,1,
+34,28,25,22,19,17,13,7,6,0,1,
+34,28,25,22,19,17,13,7,6,0,1,
+34,28,25,22,19,17,13,7,6,0,1,
+34,28,22,19,17,13,0,3,8,9,10,11,14,15,16,20,23,
+6,0,
+34,28,22,19,17,13,7,0,11,14,15,16,20,24,26,
+22,17,7,0,
+25,7,0,
+25,17,7,0,
+25,7,0,
+25,7,0,
+22,0,14,
+22,7,0,1,
+34,28,25,22,19,17,13,7,0,1,18,
+22,7,0,
+34,25,22,17,13,7,0,27,29,31,
+28,19,0,
+19,7,0,1,
+34,28,25,22,19,17,13,7,0,31,32,
+34,25,22,17,13,7,0,31,32,
+34,25,22,17,13,7,0,1,
+19,7,0,
+34,28,25,22,19,17,13,7,0,31,32,
+34,25,22,17,13,7,0,27,29,31,
+34,25,22,17,13,7,0,31,32,
+
+};
+
+
+static unsigned const char ag_astt[244] = {
+  4,4,4,4,4,4,4,4,7,1,0,2,2,2,2,2,1,10,8,7,1,1,1,1,1,1,1,1,2,2,1,1,4,4,4,4,4,
+  4,4,7,1,4,4,4,7,1,2,2,7,2,4,4,4,4,4,4,4,4,4,7,1,4,4,4,4,4,4,4,4,4,7,1,4,4,
+  4,4,4,4,4,4,4,7,1,4,4,4,4,4,4,4,4,4,7,1,2,2,2,2,2,1,5,3,3,1,1,1,1,2,2,1,1,
+  3,7,2,2,2,2,2,1,10,7,2,2,2,2,2,2,2,2,1,10,7,2,10,4,2,1,10,4,2,10,4,2,10,4,
+  2,7,2,4,4,7,1,4,4,4,4,4,4,4,4,7,1,1,1,10,7,2,2,2,2,2,10,4,1,1,1,1,2,7,4,4,
+  7,1,2,10,2,2,2,2,2,2,7,1,3,2,2,2,2,2,2,4,1,3,4,4,4,4,4,4,7,1,2,10,7,2,10,2,
+  2,2,2,2,2,7,1,3,2,2,2,2,2,10,7,1,1,1,2,2,2,2,2,2,4,1,3
+};
+
+
+static const unsigned char ag_pstt[] = {
+6,6,6,6,6,6,6,6,0,1,0,
+12,12,20,12,12,4,7,10,1,9,9,10,9,8,7,6,5,14,15,3,2,
+6,6,6,6,6,6,6,2,11,
+6,6,6,3,12,17,
+20,4,13,
+6,6,6,6,6,6,6,6,6,5,13,
+6,6,6,6,6,6,6,6,6,6,14,
+6,6,6,6,6,6,6,6,6,7,15,
+6,6,6,6,6,6,6,6,6,8,16,
+12,12,20,12,12,4,4,2,2,8,7,6,5,14,15,3,2,
+5,10,
+28,28,20,28,28,17,7,11,30,22,30,30,30,23,30,
+18,18,7,12,
+24,7,21,
+26,19,7,11,
+27,7,10,
+25,7,9,
+20,17,29,
+6,6,18,20,
+6,6,6,6,6,6,6,6,19,21,22,
+23,7,20,
+38,38,38,44,38,7,35,25,25,24,
+26,16,22,
+6,6,23,27,
+40,46,40,40,39,44,40,40,24,28,45,
+40,40,40,44,40,40,36,28,43,
+6,6,6,6,6,6,26,29,
+19,7,27,
+40,46,40,40,41,44,40,40,28,28,45,
+38,38,38,44,38,7,29,30,30,24,
+40,40,40,44,40,40,37,28,43,
+
+};
+
+
+static const unsigned char ag_sbt[] = {
+     0,  11,  32,  41,  47,  50,  61,  72,  83,  94, 111, 113, 128, 132,
+   135, 139, 142, 145, 148, 152, 163, 166, 176, 179, 183, 194, 203, 211,
+   214, 225, 235, 244
+};
+
+
+static const unsigned char ag_sbe[] = {
+     8,  19,  39,  44,  48,  59,  70,  81,  92, 100, 112, 120, 131, 134,
+   138, 141, 144, 146, 150, 160, 165, 172, 178, 181, 191, 200, 209, 213,
+   222, 231, 241, 244
+};
+
+
+static const unsigned char ag_fl[] = {
+  1,1,2,0,1,3,0,2,1,2,2,2,1,2,1,1,5,2,2,6,1,2,3,3,3,3,3,3,1,2,1,1,1,1,1,
+  1,2,4,1,2,1,2,1,2,1,2,2
+};
+
+static const unsigned char ag_ptt[] = {
+    0,  4,  4,  5,  5,  2,  1,  1,  3,  3,  3,  3,  9,  9,  9,  9,  9,  9,
+   21, 21, 15,  8, 10, 10, 23, 23, 23, 23, 24, 24, 24, 26, 26, 26, 26, 18,
+   18, 18, 29, 29, 32, 32, 27, 27, 31, 31, 31
+};
+
+static const unsigned char  *ag_valid(int ag_k) {
+  const unsigned char  *ag_tp = &ag_tstt[ag_sbt[(PCB).sn+1]];
+  while (*--ag_tp != (unsigned char) ag_k) if (*ag_tp == 0) return NULL;
+  return ag_tp;
+}
+
+int mas_change_reduction(mas_token_type ag_k) {
+  if (!ag_valid(ag_k)) return 0;
+  (PCB).reduction_token = ag_k;
+  return 1;
+}
+
+static void ag_default(const  int *ag_tp) {
+  (PCB).ag_dsn = (PCB).sn;
+  (PCB).ag_dtl = ag_tp;
+  while (!ag_valid((mas_token_type) *ag_tp)) ag_tp++;
+  (PCB).reduction_token = (mas_token_type) *ag_tp;
+}
+
+
+
+static void ag_ra(void)
+{
+  switch(ag_rpx[(PCB).ag_ap]) {
+    case 1: ag_rp_1(); break;
+    case 2: ag_rp_2(V(1,(token *))); break;
+    case 3: ag_rp_3(); break;
+    case 4: ag_rp_4(); break;
+    case 5: ag_rp_5(V(0,(token *))); break;
+    case 6: ag_rp_6(V(0,(token *))); break;
+    case 7: ag_rp_7(V(1,(token *))); break;
+    case 8: ag_rp_8(V(0,(token *))); break;
+    case 9: ag_rp_9(V(0,(token *))); break;
+    case 10: ag_rp_10(V(0,(token *)), V(3,(unsigned *))); break;
+    case 11: ag_rp_11(V(1,(token *))); break;
+    case 12: V(0,(token *)) = ag_rp_12(V(1,(token *))); break;
+    case 13: V(0,(token *)) = ag_rp_13(V(3,(token *))); break;
+    case 14: ag_default(&ag_rtt[0]); V(0,(token *)) = ag_rp_14(V(0,(token *))); break;
+    case 15: ag_rp_15(V(0,(token *))); break;
+    case 16: ag_rp_16(V(2,(token *))); break;
+    case 17: ag_rp_17(); break;
+    case 18: ag_rp_18(V(0,(token *))); break;
+    case 19: ag_rp_19(); break;
+    case 20: ag_rp_20(V(0,(token *))); break;
+    case 21: ag_rp_21(); break;
+    case 22: ag_rp_22(V(0,(token *))); break;
+    case 23: ag_rp_23(V(1,(token *))); break;
+    case 24: ag_rp_24(V(0,(token *))); break;
+    case 25: V(0,(unsigned *)) = ag_rp_25(); break;
+    case 26: V(0,(unsigned *)) = ag_rp_26(); break;
+    case 27: V(0,(unsigned *)) = ag_rp_27(V(0,(unsigned *))); break;
+    case 28: ag_rp_28(V(0,(token *))); break;
+    case 29: ag_rp_29(V(1,(token *))); break;
+    case 30: ag_rp_30(V(0,(token *))); break;
+    case 31: ag_rp_31(V(1,(token *))); break;
+    case 32: ag_rp_32(V(0,(token *))); break;
+    case 33: ag_rp_33(V(1,(token *))); break;
+  }
+  (PCB).la_ptr = (PCB).pointer;
+}
+
+#define TOKEN_NAMES mas_token_names
+const char *const mas_token_names[35] = {
+  "grammar",
+  "space",
+  "grammar",
+  "parse unit",
+  "",
+  "",
+  "eof",
+  "' '",
+  "parameter expansion",
+  "simple parse unit",
+  "concatenation",
+  "macro",
+  "",
+  "'#'",
+  "parameter name",
+  "variable",
+  "simple macro",
+  "'('",
+  "macro arg list",
+  "')'",
+  "defined",
+  "macro name",
+  "NAME",
+  "left side",
+  "right side",
+  "CONCAT",
+  "not parameter",
+  "arg elements",
+  "','",
+  "initial arg element",
+  "",
+  "nested elements",
+  "arg element",
+  "",
+  "",
+
+};
+
+#ifndef MISSING_FORMAT
+#define MISSING_FORMAT "Missing %s"
+#endif
+#ifndef UNEXPECTED_FORMAT
+#define UNEXPECTED_FORMAT "Unexpected %s"
+#endif
+#ifndef UNNAMED_TOKEN
+#define UNNAMED_TOKEN "input"
+#endif
+
+
+static void ag_diagnose(void) {
+  int ag_snd = (PCB).sn;
+  int ag_k = ag_sbt[ag_snd];
+
+  if (*TOKEN_NAMES[ag_tstt[ag_k]] && ag_astt[ag_k + 1] == ag_action_8) {
+    sprintf((PCB).ag_msg, MISSING_FORMAT, TOKEN_NAMES[ag_tstt[ag_k]]);
+  }
+  else if (ag_astt[ag_sbe[(PCB).sn]] == ag_action_8
+          && (ag_k = (int) ag_sbe[(PCB).sn] + 1) == (int) ag_sbt[(PCB).sn+1] - 1
+          && *TOKEN_NAMES[ag_tstt[ag_k]]) {
+    sprintf((PCB).ag_msg, MISSING_FORMAT, TOKEN_NAMES[ag_tstt[ag_k]]);
+  }
+  else if ((PCB).token_number && *TOKEN_NAMES[(PCB).token_number]) {
+    sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, TOKEN_NAMES[(PCB).token_number]);
+  }
+  else if (isprint(INPUT_CODE((*(PCB).pointer))) && INPUT_CODE((*(PCB).pointer)) != '\\') {
+    char buf[20];
+    sprintf(buf, "\'%c\'", (char) INPUT_CODE((*(PCB).pointer)));
+    sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, buf);
+  }
+  else sprintf((PCB).ag_msg, UNEXPECTED_FORMAT, UNNAMED_TOKEN);
+  (PCB).error_message = (PCB).ag_msg;
+
+
+}
+static int ag_action_1_r_proc(void);
+static int ag_action_2_r_proc(void);
+static int ag_action_3_r_proc(void);
+static int ag_action_4_r_proc(void);
+static int ag_action_1_s_proc(void);
+static int ag_action_3_s_proc(void);
+static int ag_action_1_proc(void);
+static int ag_action_2_proc(void);
+static int ag_action_3_proc(void);
+static int ag_action_4_proc(void);
+static int ag_action_5_proc(void);
+static int ag_action_6_proc(void);
+static int ag_action_7_proc(void);
+static int ag_action_8_proc(void);
+static int ag_action_9_proc(void);
+static int ag_action_10_proc(void);
+static int ag_action_11_proc(void);
+static int ag_action_8_proc(void);
+
+
+static int (*const  ag_r_procs_scan[])(void) = {
+  ag_action_1_r_proc,
+  ag_action_2_r_proc,
+  ag_action_3_r_proc,
+  ag_action_4_r_proc
+};
+
+static int (*const  ag_s_procs_scan[])(void) = {
+  ag_action_1_s_proc,
+  ag_action_2_r_proc,
+  ag_action_3_s_proc,
+  ag_action_4_r_proc
+};
+
+static int (*const  ag_gt_procs_scan[])(void) = {
+  ag_action_1_proc,
+  ag_action_2_proc,
+  ag_action_3_proc,
+  ag_action_4_proc,
+  ag_action_5_proc,
+  ag_action_6_proc,
+  ag_action_7_proc,
+  ag_action_8_proc,
+  ag_action_9_proc,
+  ag_action_10_proc,
+  ag_action_11_proc,
+  ag_action_8_proc
+};
+
+
+static int ag_action_10_proc(void) {
+  int ag_t = (PCB).token_number;
+  do {
+    (PCB).pointer = (PCB).la_ptr;
+    (PCB).token_number = (mas_token_type) AG_TCV(INPUT_CODE(*(PCB).la_ptr));
+    (PCB).la_ptr++;
+  } while ((PCB).token_number == (mas_token_type) ag_t);
+  (PCB).la_ptr = (PCB).pointer;
+  return 1;
+}
+
+static int ag_action_11_proc(void) {
+  int ag_t = (PCB).token_number;
+
+  do {
+    (*(token *) &(PCB).vs[(PCB).ssx]) = *(PCB).pointer;
+    (PCB).ssx--;
+    (PCB).pointer = (PCB).la_ptr;
+    ag_ra();
+    if ((PCB).exit_flag != AG_RUNNING_CODE) return 0;
+    (PCB).ssx++;
+    (PCB).token_number = (mas_token_type) AG_TCV(INPUT_CODE(*(PCB).la_ptr));
+    (PCB).la_ptr++;
+  }
+  while ((PCB).token_number == (mas_token_type) ag_t);
+  (PCB).la_ptr = (PCB).pointer;
+  return 1;
+}
+
+static int ag_action_3_r_proc(void) {
+  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
+  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
+  (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
+  ag_ra();
+  return (PCB).exit_flag == AG_RUNNING_CODE;
+}
+
+static int ag_action_3_s_proc(void) {
+  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
+  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
+  (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
+  ag_ra();
+  return (PCB).exit_flag == AG_RUNNING_CODE;
+}
+
+static int ag_action_4_r_proc(void) {
+  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
+  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
+  (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
+  return 1;
+}
+
+static int ag_action_2_proc(void) {
+  if ((PCB).ssx >= 128) {
+    ag_trace_error();
+    (PCB).exit_flag = AG_STACK_ERROR_CODE;
+    PARSER_STACK_OVERFLOW;
+  }
+  (*(token *) &(PCB).vs[(PCB).ssx]) = *(PCB).pointer;
+  (PCB).ss[(PCB).ssx] = (PCB).sn;
+  (PCB).ssx++;
+  (PCB).sn = (PCB).ag_ap;
+  (PCB).pointer = (PCB).la_ptr;
+  return 0;
+}
+
+static int ag_action_9_proc(void) {
+  if ((PCB).ssx >= 128) {
+    ag_trace_error();
+    (PCB).exit_flag = AG_STACK_ERROR_CODE;
+    PARSER_STACK_OVERFLOW;
+  }
+  (PCB).vs[(PCB).ssx] = ag_null_value;
+  (PCB).ss[(PCB).ssx] = (PCB).sn;
+  (PCB).ssx++;
+  (PCB).sn = (PCB).ag_ap;
+  (PCB).la_ptr = (PCB).pointer;
+  return (PCB).exit_flag == AG_RUNNING_CODE;
+}
+
+static int ag_action_2_r_proc(void) {
+  (PCB).ssx++;
+  (PCB).sn = (PCB).ag_ap;
+  return 0;
+}
+
+static int ag_action_7_proc(void) {
+  --(PCB).ssx;
+  (PCB).la_ptr = (PCB).pointer;
+  (PCB).exit_flag = AG_SUCCESS_CODE;
+  return 0;
+}
+
+static int ag_action_1_proc(void) {
+  (PCB).pointer = (PCB).la_ptr;
+  (PCB).exit_flag = AG_SUCCESS_CODE;
+  return 0;
+}
+
+static int ag_action_1_r_proc(void) {
+  (PCB).exit_flag = AG_SUCCESS_CODE;
+  return 0;
+}
+
+static int ag_action_1_s_proc(void) {
+  (PCB).exit_flag = AG_SUCCESS_CODE;
+  return 0;
+}
+
+static int ag_action_4_proc(void) {
+  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
+  (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
+  (*(token *) &(PCB).vs[(PCB).ssx]) = *(PCB).pointer;
+  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
+  else (PCB).ss[(PCB).ssx] = (PCB).sn;
+  (PCB).pointer = (PCB).la_ptr;
+  while ((PCB).exit_flag == AG_RUNNING_CODE) {
+    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
+    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
+    do {
+      unsigned ag_tx = (ag_t1 + ag_t2)/2;
+      if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
+      else ag_t2 = ag_tx;
+    } while (ag_t1 < ag_t2);
+    if (ag_tstt[ag_t1] != (PCB).reduction_token) {
+      (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; ag_trace_error();
+      REDUCTION_TOKEN_ERROR; break;}
+      (PCB).ag_ap = ag_pstt[ag_t1];
+    if ((ag_s_procs_scan[ag_astt[ag_t1]])() == 0) break;
+  }
+  return 0;
+}
+
+static int ag_action_3_proc(void) {
+  int ag_sd = ag_fl[(PCB).ag_ap] - 1;
+  (*(token *) &(PCB).vs[(PCB).ssx]) = *(PCB).pointer;
+  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
+  else (PCB).ss[(PCB).ssx] = (PCB).sn;
+  (PCB).pointer = (PCB).la_ptr;
+  (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
+  ag_ra();
+  while ((PCB).exit_flag == AG_RUNNING_CODE) {
+    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
+    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
+    do {
+      unsigned ag_tx = (ag_t1 + ag_t2)/2;
+      if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
+      else ag_t2 = ag_tx;
+    } while (ag_t1 < ag_t2);
+    if (ag_tstt[ag_t1] != (PCB).reduction_token) {
+      (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; ag_trace_error();
+      REDUCTION_TOKEN_ERROR; break;}
+      (PCB).ag_ap = ag_pstt[ag_t1];
+    if ((ag_s_procs_scan[ag_astt[ag_t1]])() == 0) break;
+  }
+  return 0;
+}
+
+static int ag_action_8_proc(void) {
+  ag_trace_error();
+  (PCB).la_ptr = (PCB).pointer;
+  (PCB).exit_flag = AG_SYNTAX_ERROR_CODE;
+  ag_diagnose();
+  SYNTAX_ERROR;
+  (PCB).la_ptr = ++(PCB).pointer;
+  return (PCB).exit_flag == AG_RUNNING_CODE;
+}
+
+static int ag_action_5_proc(void) {
+  int ag_sd = ag_fl[(PCB).ag_ap];
+  if (ag_sd) (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
+  else {
+    (PCB).ss[(PCB).ssx] = (PCB).sn;
+  }
+  (PCB).la_ptr = (PCB).pointer;
+  (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
+  ag_ra();
+  while ((PCB).exit_flag == AG_RUNNING_CODE) {
+    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
+    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
+    do {
+      unsigned ag_tx = (ag_t1 + ag_t2)/2;
+      if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
+      else ag_t2 = ag_tx;
+    } while (ag_t1 < ag_t2);
+    if (ag_tstt[ag_t1] != (PCB).reduction_token) {
+      (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; ag_trace_error();
+      REDUCTION_TOKEN_ERROR; break;}
+      (PCB).ag_ap = ag_pstt[ag_t1];
+    if ((ag_r_procs_scan[ag_astt[ag_t1]])() == 0) break;
+  }
+  return (PCB).exit_flag == AG_RUNNING_CODE;
+}
+
+static int ag_action_6_proc(void) {
+  int ag_sd = ag_fl[(PCB).ag_ap];
+  (PCB).reduction_token = (mas_token_type) ag_ptt[(PCB).ag_ap];
+  if (ag_sd) {
+    (PCB).sn = (PCB).ss[(PCB).ssx -= ag_sd];
+  }
+  else {
+    if ((PCB).ssx >= 128) {
+      ag_trace_error();
+      (PCB).exit_flag = AG_STACK_ERROR_CODE;
+      PARSER_STACK_OVERFLOW;
+    }
+    (PCB).vs[(PCB).ssx] = ag_null_value;
+    (PCB).ss[(PCB).ssx] = (PCB).sn;
+  }
+  (PCB).la_ptr = (PCB).pointer;
+  while ((PCB).exit_flag == AG_RUNNING_CODE) {
+    unsigned ag_t1 = ag_sbe[(PCB).sn] + 1;
+    unsigned ag_t2 = ag_sbt[(PCB).sn+1] - 1;
+    do {
+      unsigned ag_tx = (ag_t1 + ag_t2)/2;
+      if (ag_tstt[ag_tx] < (unsigned char)(PCB).reduction_token) ag_t1 = ag_tx + 1;
+      else ag_t2 = ag_tx;
+    } while (ag_t1 < ag_t2);
+    if (ag_tstt[ag_t1] != (PCB).reduction_token) {
+      (PCB).exit_flag = AG_REDUCTION_ERROR_CODE; ag_trace_error();
+      REDUCTION_TOKEN_ERROR; break;}
+      (PCB).ag_ap = ag_pstt[ag_t1];
+    if ((ag_r_procs_scan[ag_astt[ag_t1]])() == 0) break;
+  }
+  return (PCB).exit_flag == AG_RUNNING_CODE;
+}
+
+
+void init_mas(void) {
+  (PCB).la_ptr = (PCB).pointer;
+  (PCB).ss[0] = (PCB).sn = (PCB).ssx = 0;
+  (PCB).exit_flag = AG_RUNNING_CODE;
+}
+
+void mas(void) {
+  init_mas();
+  (PCB).exit_flag = AG_RUNNING_CODE;
+  while ((PCB).exit_flag == AG_RUNNING_CODE) {
+    unsigned ag_t1 = ag_sbt[(PCB).sn];
+    if (ag_tstt[ag_t1]) {
+      unsigned ag_t2 = ag_sbe[(PCB).sn] - 1;
+      (PCB).token_number = (mas_token_type) AG_TCV(INPUT_CODE(*(PCB).la_ptr));
+      (PCB).la_ptr++;
+      do {
+        unsigned ag_tx = (ag_t1 + ag_t2)/2;
+        if (ag_tstt[ag_tx] > (unsigned char)(PCB).token_number)
+          ag_t1 = ag_tx + 1;
+        else ag_t2 = ag_tx;
+      } while (ag_t1 < ag_t2);
+      if (ag_tstt[ag_t1] != (unsigned char)(PCB).token_number)
+        ag_t1 = ag_sbe[(PCB).sn];
+    }
+    (PCB).ag_ap = ag_pstt[ag_t1];
+    (ag_gt_procs_scan[ag_astt[ag_t1]])();
+  }
+}
+
+