wyatt8740

parser 2

Jan 3rd, 2017
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.49 KB | None | 0 0
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <ctype.h> /* isspace() */
  4.  
  5. /* initial defines - pre-set limits. Subject to future changes.*/
  6. #define MAX_KEY_STRING_LEN 51 /* a 'key' can only be 50 chars long, not
  7.                                * including '[]'. This was chosen arbitrarily
  8.                                * to simplify programming and waste fewer CPU
  9.                                * cycles. '51' includes the null termination
  10.                                * byte.*/
  11.  
  12. #define DEBUG 1
  13.  
  14.  
  15. /* global vars */
  16. FILE *fp;    /* file pointer should be accessible anywhere in the parser */
  17.  
  18. int  pos = -1; /* position in file */
  19.  
  20. char chr;    /* value of current char in file, as grabbed by fgetc(). */
  21.  
  22. char key[MAX_KEY_STRING_LEN]; /* char array containing key name being operated
  23.                                * on*/
  24.  
  25. char *value; /* pointer to a string containing the value of a key in string
  26.               * form */
  27.  
  28. /*
  29.  * current offset (position) in file. becomes zero the first time nextChar()
  30.  * is called, and is added to on each subsequent call. This is here in case I
  31.  * need to use fseek() at some point.
  32.  */
  33.  
  34. /* end of global vars */
  35.  
  36. int nextChar() /* set chr to char and return 0 unless EOF reached, skip white
  37.                  * space */
  38. {
  39.   chr = fgetc(fp);
  40.   pos = pos + 1;
  41.  
  42.   /* keep going until we find non-whitespace. characters. */
  43.   while ( isspace(chr) != 0 ) { /* isspace() returns non-zero for whitespace. */
  44.     chr = fgetc(fp);
  45.     pos = pos + 1;
  46.   }
  47.  
  48.   if ( chr == EOF ) {
  49.     return (4); /* End-Of-Transmission character */
  50.   }
  51.  
  52.   return (0);
  53. }
  54.  
  55.  
  56. int nextCharInclSpace() {/* basically a wrapper to fgetc(), but it also
  57.                          * increments where we are in the file. */
  58.  
  59.                         /* also it does not return a char, but rather sets
  60.                          * 'chr'. Sorry if you hate it, it made more sense to
  61.                          * me because I'm an insane assembly programmer at
  62.                          * heart. Feel free to fix it, or I might later if
  63.                          * the urge strikes me.
  64.                          */
  65.  
  66.   chr = fgetc(fp);
  67.   pos = pos + 1;
  68.  
  69.   if ( chr == EOF ) {
  70.     return (4); /* End-Of-Transmission character */
  71.   }
  72.  
  73.   return (0);
  74. }
  75.  
  76.  
  77.  
  78. int openFile(char *filename) {
  79.   /* open file (first arg) in read-only mode */
  80.   fp=fopen(filename,"r");
  81.  
  82.   /* make sure file was readable */
  83.   if(fp == NULL) {
  84.     printf("Error reading file. Check permissions!\n");
  85.     return (-1);
  86.   }
  87.   return (0);
  88. }
  89.  
  90.  
  91. int getValString() {
  92.   int i = 0;
  93.   long int oldpos=ftell(fp); /* starting point to return to once we've
  94.                                 * checked how long our string is.*/
  95.   int len;
  96.   /* first, find out how long the string is */
  97.  
  98.   /* skip opening quote mark */
  99.   nextCharInclSpace();
  100.   i = 1;
  101.  
  102.   while( (chr != '"') && (chr != EOF) ) {
  103.     nextCharInclSpace();
  104.     i = i + 1;
  105.   }
  106.   if(chr == '"') {
  107.     len = i; /* not `i - 1` since the end quote will become a null terminator. */
  108.     printf("length %d\n",len);
  109.   }
  110.  
  111.   /* now, set a value length to match */
  112.   char val[len];
  113.  
  114.   /* seek back to where we were before doing this and this time read the value
  115.    * into the buffer we've allocated */
  116.  
  117.   fseek(fp,oldpos,SEEK_SET);
  118.   /* could also probably make it SEEK_CUR and move negative `i` places. */
  119.  
  120.   /* skip opening quote mark, again */
  121.   nextCharInclSpace();
  122.  
  123.  
  124.   pos = pos - i + 1;
  125.   /* TODO - might need to move one further back sine 'i' starts at 0? */
  126.   /* if there are bugs, this is one of the likely spots. */
  127.  
  128.   i=0;
  129.   while (i<len) {
  130.     val[i]=chr;
  131.     nextCharInclSpace();
  132.     i = i + 1;
  133.   }
  134.  
  135.   val[len - 1] = '\0';
  136.  
  137.   #ifdef DEBUG
  138.     printf("value name is %s\n",val);
  139.   #endif
  140.  
  141.  
  142.  
  143.   /* now catch things that go wrong */
  144.  
  145.   if ( chr == EOF ) {
  146.     printf("Malformed save data! Reached end-of-file while looking for ']'\n");
  147.     exit(EXIT_FAILURE);    
  148.   }
  149.  
  150.   if ( i == (MAX_KEY_STRING_LEN) ) {
  151.     key[MAX_KEY_STRING_LEN - 1] = '\0'; /* force null termination */
  152.  
  153.     printf("Malformed save data!\n"
  154.             "key name starting with '%s'\n"
  155.             "is too long!\n"
  156.             "(maximum length: %d characters)\n",key,MAX_KEY_STRING_LEN);
  157.     exit(EXIT_FAILURE);
  158.   }
  159.  
  160.   if (chr == ']') {
  161.     key[i] = '\0'; /* replace ']' with null terminator. */
  162.     return (0);
  163.   }
  164.  
  165.   /* Error if we reached this point. Should be unreachable. */
  166.   return (-1);
  167.  
  168. } /* int getValString() */
  169.  
  170.  
  171.  
  172.  
  173. int getKeyName() {
  174.   int i = 0;
  175.  
  176.   /*
  177.    * called to get a key name, when the next byte to be read from the file is
  178.    * immediately proceeding a '['.
  179.    */
  180.   while ( (chr != ']') && (chr != EOF) && ( i < ( MAX_KEY_STRING_LEN ) ) ) {
  181.     /* start grabbing chars */
  182.     nextChar(fp);
  183. /*    pos = pos + 1; */ /* nextChar() handles incrementing. Only needed if
  184.                          * using fgetc() directly. */
  185.  
  186.  
  187.     key[i] = chr;
  188.     i = i + 1;
  189.   }
  190.  
  191.   if (chr == ']') {
  192.     key[i - 1] = '\0'; /* replace ']' with null terminator. */
  193.     return (0);
  194.   }
  195.  
  196.   /* now catch things that go wrong */
  197.  
  198.   if ( chr == EOF ) {
  199.     printf("Malformed save data! Reached end-of-file while looking for ']'\n");
  200.     exit(EXIT_FAILURE);    
  201.   }
  202.  
  203.   if ( i == (MAX_KEY_STRING_LEN) ) {
  204.     key[MAX_KEY_STRING_LEN - 1] = '\0'; /* force null termination */
  205.  
  206.     printf("Malformed save data!\n"
  207.             "key name starting with '%s'\n"
  208.             "is too long!\n"
  209.             "(maximum length: %d characters)\n",key,MAX_KEY_STRING_LEN);
  210.     exit(EXIT_FAILURE);
  211.   }
  212.  
  213.   /* Error if we reached this point. Should be unreachable. */
  214.   return (-1);
  215.  
  216. } /* int getKeyName() */
  217.  
  218.  
  219. int parse(){
  220.   /* first, check if item is an array. This is determined by if a curly brace
  221.    * appears in text prior to a semicolon (if a semicolon is first, it is not
  222.    * an array; just a value).
  223.    */
  224.  
  225.   while ( (nextChar() == 0) ) { /* as long as we are able to read data */
  226.  
  227. /* first we need a 'key,' which is enclosed in square brackets ([]), then we
  228.  * need a 'value,' which is enclosed in double quote marks ("").
  229.  */
  230.  
  231.     if (chr == '[') { /* get a new key name. */
  232.       getKeyName(); /* this function sets 'key' to a string containing the key
  233.                      * value */
  234.  
  235.       #ifdef DEBUG
  236.         printf("key name is %s\n",key);
  237.       #endif
  238.  
  239.     /* done getting key name */
  240.     } /* if(chr == '[') */
  241.  
  242.  
  243.     if (chr == '=') { /* set key to value(s) within the next quote or '{' */
  244.       /* first, seek for the special chars ( '{' and '"' ). */
  245.       while( ( chr != '{' ) && ( chr != '"' ) && ( chr != EOF )) {
  246.         nextChar();
  247.       }
  248.  
  249.  
  250.       /* now, we've found the value presumably.
  251.        * the next byte we read will be the 1st char after the quote or '{'.
  252.        * if it's a quote, we know the next value is part of the stored data
  253.        * string. Otherwise, we have to do the same thing we just did to find
  254.        * another key-value pair, separate from the first one.
  255.        */
  256.  
  257.          
  258.       if ( chr == '"' ) {
  259.  
  260.       /* once we have found quote marks, start getting the value within.
  261.        * IT IS IMPORTANT TO NOT USE NEXTCHAR() FOR THIS PART, AS WITHIN THE
  262.        * QUOTE MARKS, SPACES ARE IMPORTANT. */
  263.         getValString();
  264.        
  265.  
  266.       } /* if ( chr == '"' ) */
  267.  
  268.     } /* if (chr == '=') */
  269.  
  270.  
  271.   } /*  while ( (nextChar() == 0) ) */
  272.  
  273.  
  274. /* TODO */
  275. /* if nothing else is true, print a warning message,
  276.  * and try again. If EOF is reached, error. */
  277.  
  278. return 0;  
  279. } /* int parse() */
  280.  
  281.  
  282.  
  283.  
  284.  
  285. int main(int argc, char *argv[]) {
  286.  
  287.   /* make sure file name was given */
  288.   if(argc <=1) { /* no arguments passed */
  289.     printf("Error: No file argument was given.\n");
  290.     exit(EXIT_FAILURE);
  291.   }
  292.  
  293.   /* open file, exit if it goes wrong */
  294.   if(openFile(argv[1]) != 0) {
  295.     /* something went wrong opening the file; check in openFile() function */
  296.     exit(EXIT_FAILURE);
  297.   }
  298.  
  299.   else {
  300.     /* we're golden. start parsing HERE. */
  301.     return parse();  
  302.  
  303.   }
  304. }
  305.  
  306.  
  307.  
  308.  
  309. /* internal memory structure:
  310.  * the first item in any object struct is a string identifying it.
  311.  *
  312.  * the player can hold up to ten items, so the inventory array contains
  313.  * ten item structs, and each item struct contains an item name and an item
  314.  * quantity (a char array and an int).
  315.  */
  316.  
  317. /* this code just checks for hardcoded keys to start work on.
  318.  * arrays/objects cannot be embedded in other arrays/objects to
  319.  * simplify things for me. so for player->inventory, we do a separate
  320.  * key called 'player.inventory'.*/
Advertisement
Add Comment
Please, Sign In to add comment