Mercurial > ~dholland > hg > ag > index.cgi
view tests/agcl/examples/good/mas.cpp @ 21:1c9dac05d040
Add lint-style FALLTHROUGH annotations to fallthrough cases.
(in the parse engine and thus the output code)
Document this, because the old output causes warnings with gcc10.
author | David A. Holland |
---|---|
date | Mon, 13 Jun 2022 00:04:38 -0400 |
parents | 13d2b8934445 |
children |
line wrap: on
line source
/* * 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]])(); } }