Mercurial > ~dholland > hg > ag > index.cgi
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]])(); + } +} + +