/* c code generated by "tr/translate.c.pss" */ /* note: the translation script has not been debugged expect unusual results! */ #include #include #include #include #include "colours.h" #include "tapecell.h" #include "tape.h" #include "buffer.h" #include "charclass.h" #include "command.h" #include "parameter.h" #include "instruction.h" #include "labeltable.h" #include "program.h" #include "machine.h" #include "exitcode.h" #include "machine.methods.h" int main() { struct Machine machine; struct Machine * mm = &machine; newMachine(mm, stdin, 100, 10); script: while (!mm->peep != EOF) { if (mm->peep == EOF) { break; } else { readChar(mm); } /* read */ // Unlike Crockfords grammar, I will just completely ignore whitespace, // but this may not be acceptable in a rigorous application. Also, I // am just using the ctype.h definition of whitespace, whatever that // may be. if (workspaceInClassType(mm, "[:space:]")) { mm->buffer.workspace[0] = '\0'; /* clear */ goto parse; } if (workspaceInClassType(mm, "[0-9]")) { while (((mm->peep >= '0') && ('9' >= mm->peep)) && readc(mm)) {} /* while */ put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "integer*"); push(mm); goto parse; } if (workspaceInClassType(mm, "[a-z]") || workspaceInClassType(mm, "[A-Z]")) { while (((mm->peep >= 'a') && ('z' >= mm->peep)) && readc(mm)) {} /* while */ if (0 != strcmp(mm->buffer.workspace, "true") && 0 != strcmp(mm->buffer.workspace, "false") && 0 != strcmp(mm->buffer.workspace, "null") && 0 != strcmp(mm->buffer.workspace, "e") && 0 != strcmp(mm->buffer.workspace, "E")) { // handle error put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "Unknown value '"); get(mm); add(mm, "' at line "); lines(mm); add(mm, " (character "); chars(mm); add(mm, ").\n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } put(mm); if (0 == strcmp(mm->buffer.workspace, "e") || 0 == strcmp(mm->buffer.workspace, "E")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "E*"); push(mm); goto parse; } mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "value*"); push(mm); goto parse; } if (0 == strcmp(mm->buffer.workspace, "\"")) { // save line number for error message mm->buffer.workspace[0] = '\0'; /* clear */ lines(mm); put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ until(mm, "\""); if (mm->peep == EOF) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "Unterminated quote (\") char, starting at line "); get(mm); add(mm, "\n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } /* clip */ if (*mm->buffer.workspace != 0) { mm->buffer.workspace[strlen(mm->buffer.workspace)-1] = '\0'; } put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "string*"); push(mm); goto parse; } // literal tokens if (0 == strcmp(mm->buffer.workspace, ".") || 0 == strcmp(mm->buffer.workspace, ",") || 0 == strcmp(mm->buffer.workspace, ":") || 0 == strcmp(mm->buffer.workspace, "-") || 0 == strcmp(mm->buffer.workspace, "+") || 0 == strcmp(mm->buffer.workspace, "[") || 0 == strcmp(mm->buffer.workspace, "]") || 0 == strcmp(mm->buffer.workspace, "{") || 0 == strcmp(mm->buffer.workspace, "}")) { put(mm); add(mm, "*"); push(mm); goto parse; } // here check if the workspace is empty. If not it is an error. if (0 != strcmp(mm->buffer.workspace, "")) { put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error at line "); lines(mm); add(mm, ", char "); chars(mm); add(mm, ": unquoted '"); get(mm); add(mm, "' character.\n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } parse: // just for debugging while (pop(mm)); /* unstack */ add(mm, "\n"); printf("%s", mm->buffer.workspace); /* print */ /* clip */ if (*mm->buffer.workspace != 0) { mm->buffer.workspace[strlen(mm->buffer.workspace)-1] = '\0'; } while(push(mm)); /* stack */ // The parse/compile phase // -------------- // 2 tokens pop(mm); pop(mm); //----------- // Two token errors (not necessarily a complete list) // comma errors if (0 == strcmp(mm->buffer.workspace, "{*,*") || 0 == strcmp(mm->buffer.workspace, ",*}*") || 0 == strcmp(mm->buffer.workspace, "[*,*") || 0 == strcmp(mm->buffer.workspace, ",*,*") || 0 == strcmp(mm->buffer.workspace, ",*]*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error at line "); lines(mm); add(mm, ", char "); chars(mm); add(mm, " (extra or misplaced ',' comma)\n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } // exponent errors (e/E must be followed by an int or signed int) if (0 != strcmp(mm->buffer.workspace, "E*") && strncmp(mm->buffer.workspace, "E*", strlen("E*")) == 0 && !endsWith(mm->buffer.workspace, "integer*") && !endsWith(mm->buffer.workspace, "-*") && !endsWith(mm->buffer.workspace, "+*") && !endsWith(mm->buffer.workspace, "number*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): misplaced exponent 'e' or 'E' \n"); add(mm, "In JSON syntax, e/E may only precede an int or signed int.\n"); add(mm, "for example: 33e+01 \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } // exponent errors (e/E must be followed by an int or signed int) if (0 != strcmp(mm->buffer.workspace, "E*") && endsWith(mm->buffer.workspace, "E*") && strncmp(mm->buffer.workspace, "integer*", strlen("integer*")) != 0 && strncmp(mm->buffer.workspace, "sign.integer*", strlen("sign.integer*")) != 0 && strncmp(mm->buffer.workspace, "decimal*", strlen("decimal*")) != 0) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): misplaced exponent 'e' or 'E' \n"); add(mm, "In JSON syntax, e/E may only be preceded by an int, signed int.\n"); add(mm, "or decimal eg: 33e+01 \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } // sign errors (+/- must be followed by an integer if (0 != strcmp(mm->buffer.workspace, "-*") && strncmp(mm->buffer.workspace, "-*", strlen("-*")) == 0 && !endsWith(mm->buffer.workspace, "integer*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "Json syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): misplaced negative '-' sign\n"); add(mm, "In JSON syntax, - may only precede a number \n"); add(mm, "for example: -33.01 \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } // sign errors (+/- must be followed by an integer) if (0 != strcmp(mm->buffer.workspace, "+*") && strncmp(mm->buffer.workspace, "+*", strlen("+*")) == 0 && !endsWith(mm->buffer.workspace, "integer*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "Json syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): misplaced positive '+' sign\n"); add(mm, "In JSON syntax, + may only precede a number \n"); add(mm, "for example: +33.01 \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } // dot errors (. must be followed by an integer) if (0 != strcmp(mm->buffer.workspace, ".*") && strncmp(mm->buffer.workspace, ".*", strlen(".*")) == 0 && !endsWith(mm->buffer.workspace, "integer*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "Json syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): misplaced dot '.' sign\n"); add(mm, "In JSON syntax, dots may only be used in decimal numbers \n"); add(mm, "for example: -33.01 \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } // dot errors (. must be preceded by an integer or signed integer) if (0 != strcmp(mm->buffer.workspace, ".*") && endsWith(mm->buffer.workspace, ".*") && strncmp(mm->buffer.workspace, "integer*", strlen("integer*")) != 0 && strncmp(mm->buffer.workspace, "sign.integer*", strlen("sign.integer*")) != 0) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): misplaced dot '.' sign\n"); add(mm, "In JSON syntax, dots may only be used in decimal numbers \n"); add(mm, "for example: -33.01, but .44 is not a legal JSON number \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } // eg errors "items*:*","members*:*",",*:*","[*:*","{*:*" // A colon must be preceded by a string. Using logic if (endsWith(mm->buffer.workspace, ":*") && 0 != strcmp(mm->buffer.workspace, ":*") && strncmp(mm->buffer.workspace, "string*", strlen("string*")) != 0) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "Json syntax error near line "); lines(mm); add(mm, ", char "); chars(mm); add(mm, " (misplaced colon ':') \n"); add(mm, "A ':' can only occur after a string key in an object structure \n"); add(mm, "Example: {\"cancelled\":true} \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } // more colon errors if (0 != strcmp(mm->buffer.workspace, ":*") && strncmp(mm->buffer.workspace, ":*", strlen(":*")) == 0) { if (endsWith(mm->buffer.workspace, "}*") || endsWith(mm->buffer.workspace, ",*") || endsWith(mm->buffer.workspace, "]*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error near line "); lines(mm); add(mm, ", char "); chars(mm); add(mm, " (misplaced colon ':' or missing value?) \n"); add(mm, "A ':' only occur as part of an object member \n"); add(mm, "Example: {\"cancelled\":true} \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } } // catch object member errors // also need to check that not only 1 token in on the stack // hence the !"member*" construct if (strncmp(mm->buffer.workspace, "member*", strlen("member*")) == 0 || strncmp(mm->buffer.workspace, "members*", strlen("members*")) == 0) { if (0 != strcmp(mm->buffer.workspace, "member*") && 0 != strcmp(mm->buffer.workspace, "members*") && !endsWith(mm->buffer.workspace, ",*") && !endsWith(mm->buffer.workspace, "}*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error after object member near line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, ")\n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } } // catch array errors if (strncmp(mm->buffer.workspace, "items*", strlen("items*")) == 0 && 0 != strcmp(mm->buffer.workspace, "items*") && !endsWith(mm->buffer.workspace, ",*") && !endsWith(mm->buffer.workspace, "]*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "Error after an array item near line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, ")\n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } if (strncmp(mm->buffer.workspace, "array*", strlen("array*")) == 0 || strncmp(mm->buffer.workspace, "object*", strlen("object*")) == 0) { if (0 != strcmp(mm->buffer.workspace, "array*") && 0 != strcmp(mm->buffer.workspace, "object*") && !endsWith(mm->buffer.workspace, ",*") && !endsWith(mm->buffer.workspace, "}*") && !endsWith(mm->buffer.workspace, "]*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error near line "); lines(mm); add(mm, " char "); chars(mm); add(mm, ")\n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } } // invalid string sequence if (strncmp(mm->buffer.workspace, "string*", strlen("string*")) == 0) { if (0 != strcmp(mm->buffer.workspace, "string*") && !endsWith(mm->buffer.workspace, ",*") && !endsWith(mm->buffer.workspace, "]*") && !endsWith(mm->buffer.workspace, "}*") && !endsWith(mm->buffer.workspace, ":*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error after a string near line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, ")\n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } } // transmogrify into array item, start array if (0 == strcmp(mm->buffer.workspace, "[*number*") || 0 == strcmp(mm->buffer.workspace, "[*string*") || 0 == strcmp(mm->buffer.workspace, "[*value*") || 0 == strcmp(mm->buffer.workspace, "[*array*") || 0 == strcmp(mm->buffer.workspace, "[*object*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "[*items*"); push(mm); push(mm); goto parse; } // exponents (e-403, E+120, E04), this slightly simplifies number parsing if (0 == strcmp(mm->buffer.workspace, "E*sign.integer*") || 0 == strcmp(mm->buffer.workspace, "E*integer*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "^"); increment(mm); /* ++ */ get(mm); if (mm->tape.currentCell > 0) mm->tape.currentCell--; /* -- */ put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "exponent*"); push(mm); goto parse; } // JSON scientific format (23e-10, -201E+33) if (0 == strcmp(mm->buffer.workspace, "integer*exponent*") || 0 == strcmp(mm->buffer.workspace, "sign.integer*exponent*")) { mm->buffer.workspace[0] = '\0'; /* clear */ get(mm); // enforce multidigit zero rules // But is "0e44" legal JSON number syntax? That would seem odd // if it is. if (strncmp(mm->buffer.workspace, "+", strlen("+")) == 0) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "JSON syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): \n"); add(mm, "In JSON syntax, the number part may not have a positive sign \n"); add(mm, "eg: +0.12e34 (error!) \n"); add(mm, "eg: 0.12e+34 (OK!) \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } if (strncmp(mm->buffer.workspace, "-", strlen("-")) == 0) { clop(mm); } if (0 != strcmp(mm->buffer.workspace, "0") && strncmp(mm->buffer.workspace, "0", strlen("0")) == 0) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "Json syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): \n"); add(mm, "In JSON syntax, multidigit numbers must begin with 1-9 \n"); add(mm, "eg: -0234.01E+9 (error) \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } mm->buffer.workspace[0] = '\0'; /* clear */ get(mm); increment(mm); /* ++ */ get(mm); if (mm->tape.currentCell > 0) mm->tape.currentCell--; /* -- */ put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "number*"); push(mm); goto parse; } // JSON scientific format (-0.23e10, 10.2E+33) if (0 == strcmp(mm->buffer.workspace, "decimal*exponent*")) { mm->buffer.workspace[0] = '\0'; /* clear */ get(mm); increment(mm); /* ++ */ get(mm); if (mm->tape.currentCell > 0) mm->tape.currentCell--; /* -- */ put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "number*"); push(mm); goto parse; } // where does a number terminate, this is the problem // It terminates at the tokens ,* }* ]* and maybe space but // this script doesnt have a space* token. if (0 == strcmp(mm->buffer.workspace, "sign.integer*,*") || 0 == strcmp(mm->buffer.workspace, "integer*,*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "number*,*"); push(mm); push(mm); goto parse; } // transmog if (0 == strcmp(mm->buffer.workspace, "sign.integer*]*") || 0 == strcmp(mm->buffer.workspace, "integer*]*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "items*]*"); push(mm); push(mm); goto parse; } if (0 == strcmp(mm->buffer.workspace, "sign.integer*}*") || 0 == strcmp(mm->buffer.workspace, "integer*}*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "number*}*"); push(mm); push(mm); goto parse; } // convert decimals to numbers with token lookahead if (0 == strcmp(mm->buffer.workspace, "decimal*}*") || 0 == strcmp(mm->buffer.workspace, "decimal*]*") || 0 == strcmp(mm->buffer.workspace, "decimal*,*")) { replace(mm, "decimal*", "number*"); /* replace */ push(mm); push(mm); goto parse; } // signed numbers if (0 == strcmp(mm->buffer.workspace, "-*integer*") || 0 == strcmp(mm->buffer.workspace, "+*integer*")) { mm->buffer.workspace[0] = '\0'; /* clear */ get(mm); increment(mm); /* ++ */ get(mm); if (mm->tape.currentCell > 0) mm->tape.currentCell--; /* -- */ put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "sign.integer*"); push(mm); goto parse; } // signed numbers if (0 == strcmp(mm->buffer.workspace, "-*integer*") || 0 == strcmp(mm->buffer.workspace, "+*integer*")) { mm->buffer.workspace[0] = '\0'; /* clear */ get(mm); increment(mm); /* ++ */ get(mm); if (mm->tape.currentCell > 0) mm->tape.currentCell--; /* -- */ put(mm); mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "sign.integer*"); push(mm); goto parse; } // empty arrays are legal json if (0 == strcmp(mm->buffer.workspace, "[*]*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "array*"); push(mm); goto parse; } // empty objects are legal json if (0 == strcmp(mm->buffer.workspace, "{*}*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "object*"); push(mm); goto parse; } // -------------- // 3 tokens pop(mm); //--------------- // Some three token errors // Object errors // A negative logic doesnt work because of the lookahead required for numbers if (0 == strcmp(mm->buffer.workspace, "{*string*}*") || 0 == strcmp(mm->buffer.workspace, "{*integer*}*") || 0 == strcmp(mm->buffer.workspace, "{*sign.integer*}*") || 0 == strcmp(mm->buffer.workspace, "{*array*}*") || 0 == strcmp(mm->buffer.workspace, "{*object*}*") || 0 == strcmp(mm->buffer.workspace, "{*value*}*") || 0 == strcmp(mm->buffer.workspace, "{*decimal*}*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "Json syntax error near line "); lines(mm); add(mm, ", char "); chars(mm); add(mm, " (misplaced brace '}' or bad object) \n"); add(mm, "A '}' can only occur to terminate an object structure \n"); add(mm, "Example: {\"hour\":21.00, \"cancelled\":true} \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } // transmogrify number into array item if (0 == strcmp(mm->buffer.workspace, "[*number*,*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "[*items*,*"); push(mm); push(mm); push(mm); goto parse; } // decimal numbers eg -4.334 or +4.3 or 0.1 if (0 == strcmp(mm->buffer.workspace, "sign.integer*.*integer*")) { mm->buffer.workspace[0] = '\0'; /* clear */ get(mm); if (strncmp(mm->buffer.workspace, "+", strlen("+")) == 0) { //error, no positive signed decimals in JSON add(mm, "Json syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): misplaced positive '+' sign\n"); add(mm, "In JSON syntax, decimal numbers are not positively signed\n"); add(mm, "eg: +33.01 (error) \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } if (strncmp(mm->buffer.workspace, "-0", strlen("-0")) == 0 && 0 != strcmp(mm->buffer.workspace, "-0")) { add(mm, "Json syntax error at line "); lines(mm); add(mm, " (char "); chars(mm); add(mm, "): \n"); add(mm, "In JSON syntax, multidigit numbers must begin with 1-9 \n"); add(mm, "eg: -0234.01E+9 (error) \n"); printf("%s", mm->buffer.workspace); /* print */ exit(0); } mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "decimal*"); push(mm); goto parse; } // decimal numbers eg -4.334 or +4.3 or 0.1 if (0 == strcmp(mm->buffer.workspace, "integer*.*integer*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "decimal*"); push(mm); goto parse; } // arrays, if (0 == strcmp(mm->buffer.workspace, "[*items*]*") || 0 == strcmp(mm->buffer.workspace, "[*number*]*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "array*"); push(mm); goto parse; } // if (0 == strcmp(mm->buffer.workspace, "items*,*string*") || 0 == strcmp(mm->buffer.workspace, "items*,*value*") || 0 == strcmp(mm->buffer.workspace, "items*,*array*") || 0 == strcmp(mm->buffer.workspace, "items*,*object*") || 0 == strcmp(mm->buffer.workspace, "items*,*number*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "items*"); push(mm); goto parse; } // object members //"string*:*integer*", if (0 == strcmp(mm->buffer.workspace, "string*:*number*") || 0 == strcmp(mm->buffer.workspace, "string*:*string*") || 0 == strcmp(mm->buffer.workspace, "string*:*value*") || 0 == strcmp(mm->buffer.workspace, "string*:*object*") || 0 == strcmp(mm->buffer.workspace, "string*:*array*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "member*"); push(mm); goto parse; } // multiple elements of an object if (0 == strcmp(mm->buffer.workspace, "member*,*member*") || 0 == strcmp(mm->buffer.workspace, "members*,*member*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "members*"); push(mm); goto parse; } // if (0 == strcmp(mm->buffer.workspace, "{*members*}*") || 0 == strcmp(mm->buffer.workspace, "{*member*}*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "object*"); push(mm); goto parse; } pop(mm); // -------------- // 4 tokens if (0 == strcmp(mm->buffer.workspace, "items*,*items*,*") || 0 == strcmp(mm->buffer.workspace, "items*,*number*,*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "items*,*"); push(mm); push(mm); goto parse; } // numbers require a lookahead token, unfortunately if (0 == strcmp(mm->buffer.workspace, "string*:*number*,*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "member*,*"); push(mm); push(mm); goto parse; } // numbers require a lookahead token, unfortunately if (0 == strcmp(mm->buffer.workspace, "string*:*number*}*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "member*}*"); push(mm); push(mm); goto parse; } // multiple elements of an object with lookahead if (0 == strcmp(mm->buffer.workspace, "member*,*member*,*") || 0 == strcmp(mm->buffer.workspace, "members*,*member*,*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "members*,*"); push(mm); push(mm); goto parse; } // multiple elements of an object with lookahead if (0 == strcmp(mm->buffer.workspace, "member*,*member*}*") || 0 == strcmp(mm->buffer.workspace, "members*,*member*}*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "members*}*"); push(mm); push(mm); goto parse; } pop(mm); // -------------- // 5 tokens // need this clumsy rule for numbers which get resolved when // a ] is seen. This is the lookahead if (0 == strcmp(mm->buffer.workspace, "[*items*,*items*]*") || 0 == strcmp(mm->buffer.workspace, "[*items*,*number*]*")) { mm->buffer.workspace[0] = '\0'; /* clear */ add(mm, "array*"); push(mm); goto parse; } push(mm); push(mm); push(mm); push(mm); push(mm); if (mm->peep == EOF) { while (pop(mm)); /* unstack */ if (0 == strcmp(mm->buffer.workspace, "object*") || 0 == strcmp(mm->buffer.workspace, "array*") || 0 == strcmp(mm->buffer.workspace, "value*") || 0 == strcmp(mm->buffer.workspace, "string*") || 0 == strcmp(mm->buffer.workspace, "integer*") || 0 == strcmp(mm->buffer.workspace, "decimal*") || 0 == strcmp(mm->buffer.workspace, "number*")) { while(push(mm)); /* stack */ add(mm, "(Appears to be) valid JSON syntax. Top level structure was '"); printf("%s", mm->buffer.workspace); /* print */ mm->buffer.workspace[0] = '\0'; /* clear */ pop(mm); /* clip */ if (*mm->buffer.workspace != 0) { mm->buffer.workspace[strlen(mm->buffer.workspace)-1] = '\0'; } add(mm, "'\n"); printf("%s", mm->buffer.workspace); /* print */ mm->buffer.workspace[0] = '\0'; /* clear */ exit(0); } while(push(mm)); /* stack */ add(mm, "(maybe) Invalid JSON \n"); add(mm, "The parse stack was \n"); printf("%s", mm->buffer.workspace); /* print */ mm->buffer.workspace[0] = '\0'; /* clear */ while (pop(mm)); /* unstack */ add(mm, "\n"); printf("%s", mm->buffer.workspace); /* print */ } } }