?
Solved

My program compiles but does not run to completion.

Posted on 2004-12-01
5
Medium Priority
?
314 Views
Last Modified: 2010-04-01
Here's my code for my program.  I get a source code from a text file, retrieve the tokens from the file, and see what type they are.  What my program should do is print the type and the token to another text file.  My program compiles, but when it executes I only see the messages on the screen that the file to be read and the file to written wear openned with no problem.  Then the program stops and I get an execution error which I have no clue what it means.  I've never got the chance to see if it does what it suppose to do.  Can anyone please look over my code and see what might be wrong.  Any advice or comments would be greatly appreciated!  Thanks!!!!

/*********************************************************************/
/* Marco A Morales  CS 380 Compilers 30 Nov 04                       */
/*                                                                   */
/* Parse program for the Tiny program                                */
/*                                                                   */
/*********************************************************************/
#include<ctype.h>
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<fstream>

using std::ofstream;
using std::ifstream;
using std::cout;
using std::cin;
using std::endl;

#define BMAX 256 //maximum length for the input buffer
#define MAXTL 40 //maximum lentgth of the token
#define MAXRESERVED 8

//the six states that the scanner can be in
typedef enum {START,INASSIGN,INCOMMENT,INNUM,INID,DONE}
State;

typedef enum
{ENDFILE, ERROR, // book-keeping tokens
IF, THEN, ELSE, END, REPEAT, UNTIL, READ, WRITE, // reserved words
ID, NUM, // multicharacter tokens
ASSIGN, EQ, LT, GT, PLUS, MINUS, TIMES, OVER, LPAREN, RPAREN, SEMI} // special symbols
TokenType;

static char lineBuf[BMAX]; //array to hold the a line of the Tiny file

static int linenum = 0; //counter to track the number of lines
static int bufsz = 0; //current length of array
static int EoFflag = false; //end of file flag
static int linepos = 0; //marker for the array of "lineBuf"

//modiffied functions from instructor's code
int getNxChar(); //function to get next character from  
void ungetNxChar(); //fucntion to go back if not the end of Tiny file
void getTok(); //function to determine token
void classToken ( TokenType );
void printToFile();
 
static char tokString[MAXTL+1];
 
//pointers for input and output files
FILE *tokfile, *symbfile;


//main program to use the functions from instructor's code
int main()
{
      if((tokfile = fopen("tokens.txt","rt")) == NULL) //open Tiny file
            {
                  cout<<"Error..."<<endl; //give error message if file cannot open
                  exit(0);
            }
      else
            cout<<"No Error"<<endl; //give message that file was able to be open

      if(( symbfile = fopen("symbols.txt","wt")) == NULL) //open tokens file
            {
                  cout<<"Error..."<<endl; //give error message if file cannot open
                  exit(0);
            }
      else
            cout<<"No Error"<<endl; //give message that file was able to be open
      
      while(!feof(tokfile))
      {

            getNxChar();
            ungetNxChar();
            getTok();
 
      
 
      }
            
      return 0;

} //end of main
 
//function to get token from file
int getNxChar()
{
       if(!(linepos < bufsz))
       {
             linenum++;
             
             if(fgets(lineBuf, BMAX-1, tokfile))
             {
                   fprintf(symbfile,"%4d: %s",linenum,lineBuf);
                   bufsz = strlen(lineBuf);
                   linepos = 0;
                   return lineBuf[linepos++];
             }
             else
             {
                   EoFflag = true;
                   return EOF;
             }
       }
             
       else
       {
             return lineBuf[linepos++];
       }
 
} //end of getNxChar function


//fucntion to go back if it is not the end of the Tiny file and decrement the position in array
 void ungetNxChar()
 {
             if(!EoFflag)
              linepos--;
 
 } //end of ungetNxChar function

 static struct
{ char* str;
TokenType token;
} reservedWords[MAXRESERVED]
= {{"if", IF},{"else", ELSE},{"end", END},
{"repeat", REPEAT},{"until", UNTIL},
{"read", READ},{"write", WRITE}};

//lookup identifier to see if it is a reserved word
static TokenType tokenLookUpTable (char * t)
{
      int i;
      for (i=0; i<MAXRESERVED; i++)
            if(!strcmp(t, reservedWords[i].str))
                  return reservedWords[i].token;
            return ID;
}

 //function to match up tokens
void getTok()
 {
       int tokStrInd = 0;
       TokenType currentToken;
       State state = START;
      
       bool keep, noKeep;

       noKeep = false;
      
       while (state != DONE)
       {
             int a = getNxChar();
             keep = true;

             switch(state)
             {
             case START:
                   if(isdigit(a))
                         state = INNUM;
                   else if(isalpha(a))
                         state = INID;
                   else if(a == ':')
                         state = INASSIGN;
                   else if((a == ' ')||(a == '\t')||(a == '\n'))
                         keep = false;
                   else if(a == '{')
                   {
                         keep = false;
                         state = INCOMMENT;
                   }
                   else
                   {
                         state = DONE;
                         
                         switch(a)
                         {
                         case EOF:
                               keep = false;
                               currentToken = ENDFILE;
                               break;
                         case'=':
                               currentToken = EQ;
                               break;
                         case'<':
                               currentToken = LT;
                               break;
                         case'>':
                               currentToken = GT;
                               break;
                         case'(':
                               currentToken = LPAREN;
                               break;
                         case')':
                               currentToken = RPAREN;
                               break;
                         case';':
                               currentToken = SEMI;
                               break;
                         case'+':
                               currentToken = PLUS;
                               break;
                         case'-':
                               currentToken = MINUS;
                               break;
                         case'*':
                               currentToken = TIMES;
                               break;
                         case'/':
                               currentToken = OVER;
                               break;
                         default:
                               currentToken = ERROR;
                               break;
                         }
                   }
                   break;
                                                             
             case INCOMMENT:
                   keep = false;
                   if(a == '}')
                         state = START;
                   break;
             case INASSIGN:
                   state = DONE;
                   if(a == '=')
                   currentToken = ASSIGN;
                   else
                   {
                         ungetNxChar();
                         keep = false;
                         currentToken = ERROR;
                   }
                  
                   break;
             case INNUM:
                   if(!isdigit(a))
                   {
                         ungetNxChar();
                         keep = false;
                         state = DONE;
                         currentToken = NUM;
                   }
                   break;
             case INID:
                   if(!isalpha(a))
                   {
                         ungetNxChar();
                         keep = false;
                         state = DONE;
                         currentToken = ID;
                   }
                   break;
             case DONE:
             default:
                   fprintf(symbfile,"Scanner Bug: state= %d\n", state);
                   state = DONE;
                   currentToken = ERROR;
                   break;
             }

            if((keep) && (tokStrInd <= MAXTL))
                  tokString[tokStrInd++] = (char)a;
             if(state == DONE)
             {
                   tokString[tokStrInd] = '\0';
                  
                   if(currentToken == ID)
                   {
                         currentToken = tokenLookUpTable(tokString);
                   }
                       classToken(currentToken);
                  
             }

                         
             if (noKeep)
             {
                   fprintf(tokfile,"%s","Error in source file line number:");
                   fprintf(tokfile,"%d\n",linenum);
             }

             
      }

} //end of getTok function
 

void classToken (TokenType token)
{      
 
      switch ( token)
                        {
                        case IF:
                        case THEN:
                        case ELSE:
                        case END:
                        case REPEAT:
                        case UNTIL:
                        case READ:
                        case WRITE:
                              fprintf (symbfile, "reserved word: %s\n",tokString);
                              break;
                        case ASSIGN: fprintf (symbfile, "operator: =\n"); break;
                        case LT: fprintf (symbfile, "operator: <\n"); break;
                        case GT: fprintf (symbfile, "operator: >\n"); break;
                        case EQ: fprintf (symbfile, "operator: ==\n"); break;
                        case LPAREN: fprintf (symbfile, "operator: (\n"); break;
                        case RPAREN: fprintf (symbfile, "operator: )\n"); break;
                        case SEMI: fprintf (symbfile, "operator: ;\n"); break;
                        case PLUS: fprintf (symbfile, "operator: +\n"); break;
                        case MINUS: fprintf (symbfile, "operator: -\n"); break;
                        case TIMES: fprintf (symbfile, "operator: *\n"); break;
                        case OVER: fprintf (symbfile, "operator: /\n"); break;
                        case ENDFILE: fprintf (symbfile, "operator: EOF\n"); break;
                        case NUM:
                              fprintf (symbfile, "NUM, val= %s\n", tokString);
                              break;
                        case ID:
                              fprintf (symbfile, "ID, name= %s\n", tokString);
                              break;
                        case ERROR:
                              fprintf (symbfile, "ERROR: %s\n", tokString);
                              break;
                        default: fprintf (symbfile, "Unknown token: %d\n", token);
                        }
      
      
}// end classToken (TokenType token)
0
Comment
Question by:morales7_0
  • 3
  • 2
5 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 12718744
Could you provide a sample "token.txt"? It's hard to test that without an input file...
0
 

Author Comment

by:morales7_0
ID: 12718906
This is a copy of the file "tokens.txt"  which are only a list of tokens.

read
x
;
if
0
<
x
then
fact
:=
1
;
repeat
fact
:=
fact
*
x
;
x
:=
x
-
1
until
x
=
0
;
write
fact
end

0
 

Author Comment

by:morales7_0
ID: 12718953
Here is a copy of the source code from the original program.  At first, the program took the tokens from this code and gave the reasult in the "tokens.txt" you see above.  After I made some modifications to dictate what type these tokens were is when the program stopped working.  

This is the "Tiny.txt" file that was used to come up with the  "tokens.txt" file.  

{ Sample program
  in TINY language-
  computes factorial
}
read x; { input an integer }
if 0 < x then { don't compute if x <= 0 }
  fact := 1;
  repeat
    fact := fact * x;
      x := x - 1
      until x = 0;
      write fact { output factorial of x }
end
0
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 12718967
There are two problems

- you had

#define MAXRESERVED 8

and only 7 elements in the array:

static struct
{ char* str;
TokenType token;
} reservedWords[MAXRESERVED]
= {{"if", IF},{"else", ELSE},{"end", END},
{"repeat", REPEAT},{"until", UNTIL},
{"read", READ},{"write", WRITE}};

make that

#define MAXRESERVED 7

- additionally, the lookup function nedds to be

//lookup identifier to see if it is a reserved word
static TokenType tokenLookUpTable (char * t)
{
    int i;
    for (i=0; i<MAXRESERVED-1; i++) // '-1' since indices are zero-based
         if(!strcmp(t, reservedWords[i].str))
              return reservedWords[i].token;
         return ID;
}
0
 
LVL 86

Expert Comment

by:jkr
ID: 12718977
BTW, with the above changes, it does not crash and produces

   1: read
reserved word: read
   2: x
ID, name= x
   3: ;
operator: ;
   4: if
reserved word: if
   5: 0
NUM, val= 0
   6: <
operator: <
   7: x
ID, name= x
   8: then
ID, name= then
   9: fact
ID, name= fact
  10: :=
operator: =
  11: 1
NUM, val= 1
  12: ;
operator: ;
  13: repeat
reserved word: repeat
  14: fact
ID, name= fact
  15: :=
operator: =
  16: fact
ID, name= fact
  17: *
operator: *
  18: x
ID, name= x
  19: ;
operator: ;
  20: x
ID, name= x
  21: :=
operator: =
  22: x
ID, name= x
  23: -
operator: -
  24: 1
NUM, val= 1
  25: until
reserved word: until
  26: x
ID, name= x
  27: =
operator: ==
  28: 0
NUM, val= 0
  29: ;
operator: ;
  30: write
ID, name= write
  31: fact
ID, name= fact
  32: endreserved word: end
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
Suggested Courses

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question