Input There are two input files course data and queries See

Input:

        There are two input files: course data and queries. See cs2123p2Driver.c for more information.

Read the infix expressions

Convert the infix to postfix

Evaluate the postfix expression, producing an array of booleans (one entry for each course).

Print the infix expression, the postfix form of the expression, and evaluated result. The driver does this.

Approaches for Evaluating Operators

Approach #1: Iterate over the list of courses and then evaluate the query for each course. The operator evaluation result is simply true or false (since only one course is considered).

For N courses, this approach evaluates the same query N times.

The operator result (i.e., a boolean) must be stacked.

Additional functions provided:

void printQueryResult(Course courseM[], int iNumCourse, QueryResult resultM[])

Prints the courses which have a corresponding element in the resultM array turned on.

int never(Course *pCourse, Attr attr)

Determines whether a course has a particular attribute (type and value). If it doesn\'t, never returns TRUE; otherwise, it returns FALSE.

int getCourseData(Course courseM[])

Gets course data and their corresponding attributes (type and values).

Use of union

Since the evaluation needs two types of elements, we will use union as shown in the include file.

Some Files for your use:

p2Query.txt - data file containing infix expressions which are evaluated as queries

p2Course.txt - course data file similar to program #0.

cs2123p2.h - include file for Program #2

cs2123p2Driver.c - driver program that I provided. It has several useful routines to help reduce your effort. Please review this code

Your coding:

Create your code in cs2123p2.c (not cs2123p2Driver.c). Based on what the driver calls, you need to create these functions:

int convertToPostFix(char *pszInfix, Out out)   

It returns 0 if it converted successfully. Otherwise, it returns a value which indicates an error in

the infix data (e.g., missing left paren, missing right paren)

It populates the out array using the addOut function (provided in the driver).

void printCourseData(Course courseM[], int iNumCourse)

This was done in program #0.

void evaluatePostfix(PostfixOut out, Course courseM[], int iNumCourse

       , QueryResult resultM[])

This evaluates a postfix expression (which is in out) using the courseM array. For each course satisfying the posftfix query,

it sets its corresponding position in resultM to TRUE.

int atLeastOne(Course *pCourse, Attr attr)

Determines whether a course has a particular attribute (type and value). If it does, atLeastOne returns TRUE; otherwise, it returns FALSE.

int only(Course *pCourse, Attr attr)

This looks at EACH attribute in the course\'s attrM array for the specified course. If the attribute\'s szAttrType matches the specified szAttrType, then its corresponding szAttrValue must match the specfied attribute value. If it doesn\'t match the attribute value, FALSE is returned. only examines each of the attributes for the specified course.

You will also have to provide code for AND and OR.

Requirements:

You should not have to modify cs2123p2Driver.c.

Make certain you free up allocated memory (e.g., stack).

Sample Output (partial):

ID         Course Name        

                      Attr       Value      

CS1083     Intro I            

                      LANG       JAVA       

                      PROF       ROBBINS    

                      PROF       HOLLAND    

                      PROF       SHERETTE   

                      PROF       ROBINSON   

                      PROF       ZHU        

                      RECIT      N          

                      DEPT       CS         

MAT2233    Discrete Math      

                      PREREQ     MAT1214    

                      PREREQ     CS1713     

                      PROF       SHERETTE   

                      PROF       TANG       

                      RECIT      N          

                      DEPT       MAT         

MAT3333    Math Found         

                      PREREQ     MAT1223    

                      PREREQ     CS1713     

                      PROF       SHERETTE   

                      PROF       TANG       

                      RECIT      N          

                      DEPT       MAT        

CS1713     Intro II           

                      PREREQ     CS1083      

                      LANG       C          

                      PROF       CLARK      

                      PROF       HOLLAND    

                      PROF       SHERETTE   

                      PROF       ROBINSON   

                      PROF       ZHU        

                      RECIT      Y          

                      DEPT       CS         

CS2123     Data Structures    

                      PREREQ     CS1713     

                      LANG       C          

                      PROF       CLARK      

                      PROF       SHERETTE   

                      PROF       ROBINSON   

                      PROF       KORKMAZ    

                      PROF       TOSUN      

                      RECIT      Y          

                      DEPT       CS         

CS3843     Comp Org           

                      PREREQ     CS2123     

                      LANG       C          

                      LANG       IA32       

                      PROF       CLARK      

                      PROF       TIAN       

                      PROF       MUZAHID    

                      RECIT      Y          

                      DEPT       CS         

CS3723     Pgm Lang            

                      PREREQ     CS3443     

                      PREREQ     MAT2233    

                      LANG       C          

                      LANG       CPP        

                      LANG       JAVA       

                      LANG       LISP       

                      LANG       PYTHON     

                      PROF       CLARK      

                      RECIT      N          

                      DEPT       CS         

CS3423     Sys Pgm            

                      PREREQ     CS2123     

                      PROF       MAYNARD    

                      PROF       LAMA       

                      PROF       CLARK      

                      LANG       C          

                      LANG       PERL       

                      LANG       BASH       

                      RECIT      Y          

                      DEPT       CS         

CS3443     App Pgm            

                      PREREQ     CS2123     

                      PROF       BYLANDER   

                      PROF       ROBINSON   

                      PROF       NIU        

                      RECIT      N          

                      DEPT       CS         

                      LANG       JAVA        

CS4713     Compiler           

                      PREREQ     CS3723     

                      PREREQ     CS3843     

                      PROF       CLARK      

                      RECIT      N          

                      DEPT       CS         

                      LANG       JAVA       

CS3343     Anlys of Algo      

                      PREREQ     CS2123     

                      PREREQ     MAT3333    

                      PREREQ     MAT2233    

                      PROF       SHERETTE   

                      PROF       GIBSON     

                      PROF       BYLANDER   

                      RECIT      Y          

                      DEPT       CS         

                      LANG       JAVA       

Query # 1: RECIT = N

       RECIT N =

       Query Result:

       ID       Course Name        

       CS1083   Intro I            

       MAT2233 Discrete Math      

       MAT3333 Math Found         

       CS3723   Pgm Lang           

       CS3443   App Pgm            

       CS4713   Compiler           

Query # 2: RECIT = Y

       RECIT Y =

       Query Result:

       ID       Course Name        

       CS1713   Intro II           

       CS2123   Data Structures    

       CS3843   Comp Org           

       CS3423   Sys Pgm            

       CS3343   Anlys of Algo      

Query # 3: PROF = CLARK

       PROF CLARK =

       Query Result:

       ID       Course Name        

       CS1713   Intro II           

       CS2123   Data Structures    

       CS3843   Comp Org           

       CS3723   Pgm Lang           

       CS3423   Sys Pgm            

       CS4713   Compiler           

Query # 4: PROF NEVER CLARK

       PROF CLARK NEVER

       Query Result:

       ID       Course Name        

       CS1083   Intro I            

       MAT2233 Discrete Math      

       MAT3333 Math Found         

       CS3443   App Pgm            

       CS3343   Anlys of Algo      

Query # 5: PROF ONLY CLARK

       PROF CLARK ONLY

       Query Result:

       ID       Course Name        

       CS3723   Pgm Lang           

       CS4713   Compiler           

Query # 6: PROF = CLARK AND RECIT = N

       PROF CLARK = RECIT N = AND

       Query Result:

       ID       Course Name        

       CS3723   Pgm Lang           

       CS4713   Compiler   

Input files

p2Course.txt

p2Query.txt

Solution

cs2123p2Driver.c

#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include \"cs2123p2.h\"

static struct
{
    char szSymbol[MAX_TOKEN + 1];   // token symbol such as \"(\"
    int iCategory;                  // CAT_OPERATOR, CAT_OPERAND, CAT_LPAREN or CAT_RPAREN
    int iPrecedence;                // 0 - lowest precedence, 3 - highest precedence
} symbolDefM[] =
{
      {\"(\",      CAT_LPAREN,   0}
    , {\")\",      CAT_RPAREN,   0}
    , {\"=\",      CAT_OPERATOR, 2}
    , {\"NEVER\", CAT_OPERATOR, 2}
    , {\"ONLY\",   CAT_OPERATOR, 2}
    , {\"AND\",    CAT_OPERATOR, 1}
    , {\"OR\",     CAT_OPERATOR, 1}
    , {\"\", 0, 0}
};
void push(Stack stack, Element value)
{
    if (stack->iCount >= MAX_STACK_ELEM)
        ErrExit(ERR_STACK_USAGE
        , \"Attempt to PUSH more than %d values on the array stack\"
        , MAX_STACK_ELEM);

    stack->stackElementM[stack->iCount] = value;
    stack->iCount++;
}
Element pop(Stack stack)
{
    if (isEmpty(stack))
        ErrExit(ERR_STACK_USAGE
        , \"Attempt to POP an empty array stack\");
    stack->iCount--;
    return stack->stackElementM[stack->iCount];

}
Element topElement(Stack stack)
{
    if (isEmpty(stack))
        ErrExit(ERR_STACK_USAGE
        , \"Attempt to examine topElement of an empty array stack\");
    return stack->stackElementM[stack->iCount-1];    // return the top
}
int isEmpty(Stack stack)
{
    return stack->iCount <= 0;
}

Stack newStack()
{
    Stack stack = (Stack) malloc(sizeof(StackImp));
    stack->iCount = 0;
    return stack;
}

void freeStack(Stack stack)
{
    free (stack);
}
FILE *pFileCourse;    // Used with the -c Course File
FILE *pFileQuery;       // Used with the -q Query File
int main(int argc, char *argv[])
{
    Course courseM[MAX_COURSE];     // Course array
    int iNumberOfCourses = 0;       // Number of courses
    char *pszCourseFileNm = NULL;     // Pointer to an argv[] for course file name
    char *pszQueryFileNm = NULL;        // Pointer to an argv[] for query file name
    processCommandSwitches(argc, argv, &pszCourseFileNm, &pszQueryFileNm);

    if (pszCourseFileNm == NULL)
        exitUsage(USAGE_ERR, ERR_MISSING_SWITCH, \"-c\");
    pFileCourse = fopen(pszCourseFileNm, \"r\");
    if (pFileCourse == NULL)
        exitUsage(USAGE_ERR, \"Invalid course file name, found \"
        , pszCourseFileNm);
    if (pszQueryFileNm == NULL)
        exitUsage(USAGE_ERR, ERR_MISSING_SWITCH, \"-q\");
    pFileQuery = fopen(pszQueryFileNm, \"r\");
    if (pFileQuery == NULL)
        exitUsage(USAGE_ERR, \"Invalid query file name, found \"
        , pszQueryFileNm);
    iNumberOfCourses = getCourseData(courseM);
    fclose(pFileCourse);
    printCourseData(courseM, iNumberOfCourses);
    readAndProcessQueries(courseM, iNumberOfCourses);
    fclose(pFileQuery);
    printf(\"\ \");
    fclose(stdout);
    return 0;
}
void readAndProcessQueries(Course courseM[], int iNumberOfCourses)
{
    PostfixOut postfixOut = malloc(sizeof(PostfixOutImp));
    QueryResult queryResultM[MAX_COURSE];
    char szInputBuffer[100];            // entire input line
    int rc;
    int iLineCount = 0;
    while (fgets(szInputBuffer, 100, pFileQuery) != NULL)
    {
        iLineCount++;
        if (szInputBuffer[0] == \'\ \')
            continue;
        printf(\"Query # %d: %s\", iLineCount, szInputBuffer);
        postfixOut->iPostfixOutCount = 0;   // reset out to empty
        rc = convertToPostfix(szInputBuffer, postfixOut);
        switch (rc)
        {
            case 0: // ok so print the postfix and evaluate it
                printPostfixOut(postfixOut);
                evaluatePostfix(postfixOut, courseM, iNumberOfCourses, queryResultM);
                printQueryResult(courseM, iNumberOfCourses, queryResultM);
                break;
            case WARN_MISSING_LPAREN:
                printf(\"\\tWarning: missing left parenthesis\ \");
                break;
            case WARN_MISSING_RPAREN:
                printf(\"\\tWarning: missing right parenthesis\ \");
                break;
            case WARN_MISSING_OPERATOR:
                printf(\"\\tWarning: missing operator\ \");
                break;
            case WARN_MISSING_OPERAND:
                printf(\"\\tWarning: missing operand\ \");
                break;
            default:
                printf(\"\\t warning = %d\ \", rc);
        }
      
    }
    printf(\"\ \");
    free(postfixOut);
}
void printQueryResult(Course courseM[], int iNumCourse, QueryResult resultM[])
{
    int i;
    printf(\"\\tQuery Result:\ \");
    printf(\"\\t%-7s %-20s\ \", \"ID\", \"Course Name\");
    for (i = 0; i < iNumCourse; i++)
    {
        if (resultM[i])
            printf(\"\\t%-7s %-20s\ \", courseM[i].szCourseId
                , courseM[i].szCourseName);
    }
}
int never(Course *pCourse, Attr attr)
{
    int i = 100;
    if (pCourse == NULL)
        ErrExit(ERR_ALGORITHM
        , \"function never() received a NULL pointer\");
    for (i = 0; i < (pCourse->iNumberOfAttrs); i++)
    {
        if (strcmp(pCourse->attrM[i].szAttrType, attr.szAttrType) == 0
            && strcmp(pCourse->attrM[i].szAttrValue, attr.szAttrValue) == 0)
            return FALSE;
    }
    return TRUE;
}
void addPostfixOut(PostfixOut postfixOut, Element element)
{
    if (postfixOut->iPostfixOutCount >= MAX_OUT_ITEM)
        ErrExit(ERR_OUT_OVERFLOW
        , \"Overflow in the postfixOut array\");
    postfixOut->postfixOutM[postfixOut->iPostfixOutCount] = element;
    postfixOut->iPostfixOutCount++;
}
void printPostfixOut(PostfixOut postfixOut)
{
    int i;
    if (postfixOut == NULL)
    {
        printf(\"*** ERROR PostfixOut is NULL\ \");
        return;
    }
    printf(\"\\t\");
    for (i = 0; i < postfixOut->iPostfixOutCount; i++)
    {
        printf(\"%s \", postfixOut->postfixOutM[i].szToken);
        if ((i + 1) % 18 == 0)
            printf(\"\ \\t\");
    }
    printf(\"\ \");
}
void categorize(Element *pElement)
{
    int i;
    for (i = 0; symbolDefM[i].szSymbol[0] != \'\\0\'; i++)
    {
        if (strcmp(pElement->szToken, symbolDefM[i].szSymbol) == 0)
        {   // matched, so use its precedence and category
            pElement->iPrecedence = symbolDefM[i].iPrecedence;
            pElement->iCategory = symbolDefM[i].iCategory;
            return;
        }
    }
    pElement->iPrecedence = 0;
    pElement->iCategory = CAT_OPERAND;
}
int getCourseData(Course courseM[])
{
    char szInputBuffer[MAX_LINE_SIZE + 1]; // input buffer for fgets

    int iNumAttr = 0;                       // Number of attributes for the current course
    char szRecordType[11];                  // record type of either COURSE or ATTR
    int i = -1;                             // current course subscript. -1 indicates
                                            // not on a course yet
    int iScanfCnt;                          // scanf returns the number of successful inputs
    char *pszRemainingTxt;                  // After grabbing a token, this is the next
                                            // position. This will be after the delimiter
                                            // unless the string was terminated by a zero
                                            // byte, then it will be on the zero byte.
    while (fgets(szInputBuffer, MAX_LINE_SIZE, pFileCourse) != NULL)
    {
        if (szInputBuffer[0] == \'\ \')
            continue;
        pszRemainingTxt = getToken(szInputBuffer, szRecordType, sizeof(szRecordType) - 1);
        if (strcmp(szRecordType, \"COURSE\") == 0)
        {
            i++;
            if (i >= MAX_COURSE)
                ErrExit(ERR_TOO_MANY_COURSE
                , \"Invalid input file, max courses is %d\"
                , MAX_COURSE);

            iNumAttr = 0;   // since we have a new course, reset his/her number of attributes
            courseM[i].iNumberOfAttrs = iNumAttr;
            iScanfCnt = sscanf(pszRemainingTxt, \"%7s %20[^\ ]\ \"
                , courseM[i].szCourseId
                , courseM[i].szCourseName);
            if (iScanfCnt < 2)
            {
                WARNING(\"Expected ID and name, received %d successful values\ Input text: %s\ \"
                    , iScanfCnt, szInputBuffer);
                continue;
            }
        }
        else if (strcmp(szRecordType, \"ATTR\") == 0)
        {
            if (i < 0)
                ErrExit(ERR_BAD_COURSE
                , \"ATTR record without COURSE\ Input Text: %s\ \"
                , szInputBuffer);

            // what if we have too many attributes
            if (iNumAttr >= MAX_ATTR)
                ErrExit(ERR_BAD_COURSE
                , \"Too many attributes for Course ID %s, only %d attributes allowed\"
                , courseM[i].szCourseId
                , MAX_ATTR);

            iScanfCnt = sscanf(pszRemainingTxt, \"%10s %12s\"
                , courseM[i].attrM[iNumAttr].szAttrType
                , courseM[i].attrM[iNumAttr].szAttrValue);

            // Check for bad input. scanf returns the number of valid conversions
            if (iScanfCnt < 2)
            {
                WARNING(
                    \"Expected attribute type and value, received %d successful values\"
                    , iScanfCnt);
                continue;
            }
            iNumAttr++;
            courseM[i].iNumberOfAttrs = iNumAttr;
        }
        else
        {
            WARNING(\"Bad Command in input, found \'%s\'\"
                , szRecordType);
            continue;
        }
    }
    return i + 1;
}
void processCommandSwitches(int argc, char *argv[], char **ppszCourseFileName
    , char **ppszQueryFileName)
{
    int i;
    // Examine each of the command arguments other than the name of the program.
    for (i = 1; i < argc; i++)
    {
        // check for a switch
        if (argv[i][0] != \'-\')
            exitUsage(i, ERR_EXPECTED_SWITCH, argv[i]);
        // determine which switch it is
        switch (argv[i][1])
        {
        case \'c\':                   // Course File Name
            if (++i >= argc)
                exitUsage(i, ERR_MISSING_ARGUMENT, argv[i - 1]);
            // check for too long of a file anme
            else
                *ppszCourseFileName = argv[i];
            break;
        case \'q\':                   // Query File Name
            if (++i >= argc)
                exitUsage(i, ERR_MISSING_ARGUMENT, argv[i - 1]);
            else
                *ppszQueryFileName = argv[i];
            break;
        case \'?\':
            exitUsage(USAGE_ONLY, \"\", \"\");
            break;
        default:
            exitUsage(i, ERR_EXPECTED_SWITCH, argv[i]);
        }
    }
}

void ErrExit(int iexitRC, char szFmt[], ... )
{
    va_list args;               // This is the standard C variable argument list type
    va_start(args, szFmt);      // This tells the compiler where the variable arguments
                                // begins. They begin after szFmt.
    printf(\"ERROR: \");
    vprintf(szFmt, args);       // vprintf receives a printf format string and a
                                // va_list argument
    va_end(args);               // let the C environment know we are finished with the
                                // va_list argument
    printf(\"\ \\tEncountered in file %s\ \", __FILE__); // this 2nd arg is filled in by
                                // the pre-compiler
    exit(iexitRC);
}
void exitUsage(int iArg, char *pszMessage, char *pszDiagnosticInfo)
{
    switch (iArg)
    {
        case USAGE_ERR:
            fprintf(stderr, \"Error: %s %s\ \"
                , pszMessage
                , pszDiagnosticInfo);
            break;
        case USAGE_ONLY:
            break;
        default:
            fprintf(stderr, \"Error: bad argument #%d. %s %s\ \"
                , iArg
                , pszMessage
                , pszDiagnosticInfo);
    }
    // print the usage information for any type of command line error
    fprintf(stderr, \"p2 -c courseFileName -q queryFileName\ \");
    if (iArg == USAGE_ONLY)
        exit(USAGE_ONLY);
    else
        exit(ERR_COMMAND_LINE);
}
char * getToken(char *pszInputTxt, char szToken[], int iTokenSize)
{
    int iDelimPos;                      // found position of delim
    int iCopy;                          // number of characters to copy
    char szDelims[20] = \" \ \ \";        // delimiters
    szToken[0] = \'\\0\';
    if (pszInputTxt == NULL)
        ErrExit(ERR_ALGORITHM
        , \"getToken passed a NULL pointer\");
    if (*pszInputTxt == \'\\0\')
        return NULL;
    iDelimPos = strcspn(pszInputTxt, szDelims);
    if (iDelimPos == 0)
        return NULL;
    if (iDelimPos > iTokenSize)
        iCopy = iTokenSize;             // truncated size
    else
        iCopy = iDelimPos;
    memcpy(szToken, pszInputTxt, iCopy);
    szToken[iCopy] = \'\\0\';              // null terminate

    // advance the position
    pszInputTxt += iDelimPos;
    if (*pszInputTxt == \'\\0\')
        return pszInputTxt;
    else
        return pszInputTxt + 1;
}


cs2123p2.h

#define MAX_STACK_ELEM 20          // Maximum number of elements in the stack array
#define MAX_TOKEN 50               // Maximum number of actual characters for a token
#define MAX_OUT_ITEM 50            // Maximum number of PostfixOut items
#define MAX_COURSE 30              // Maximum number of courses
#define MAX_ATTR 12                // Maximum number of attributes per course     
#define MAX_LINE_SIZE 100          // Maximum number of character per input line
#define ERR_COMMAND_LINE    900    // invalid command line argument
#define ERR_STACK_USAGE    901
#define ERR_OUT_OVERFLOW   902
#define ERR_ALGORITHM      903     // Unexpected error in algorithm
#define ERR_TOO_MANY_COURSE 1      // Too many courses
#define ERR_TOO_MANY_ATTR 2        // Too many attributes
#define ERR_BAD_COURSE 3           // Bad Course Data
#define ERR_MISSING_SWITCH          \"missing switch\"
#define ERR_EXPECTED_SWITCH         \"expected switch, found\"
#define ERR_MISSING_ARGUMENT        \"missing argument for\"
#define USAGE_ONLY          0      // user only requested usage information
#define USAGE_ERR           -1     // usage error, show message and usage information
#define WARN_MISSING_RPAREN 801
#define WARN_MISSING_LPAREN 802
#define WARN_MISSING_OPERATOR 803
#define WARN_MISSING_OPERAND 804
#define CAT_LPAREN 1        // (
#define CAT_RPAREN 2        // )
#define CAT_OPERATOR 3      // Operators are =, NEVER, ONLY /
#define CAT_OPERAND 4       // These are attribute types or values
#define FALSE 0
#define TRUE 1

typedef struct
{
    char szAttrType[11];        // Attr Type can be one of:
    char szAttrValue[MAX_TOKEN+1];       // This corresponds to the Attr Type:
} Attr;
typedef struct
{
    char szCourseId[8];               // Course Identifier
    char szCourseName[21];            // Course Full Name
    int iNumberOfAttrs;              // Particular number of attributes for each course
    Attr attrM[MAX_ATTR];
} Course;

typedef int QueryResult;

int getCourseData(Course courseM[]);
void printCourseData(Course courseM[], int iNumCourse);
typedef char Token[MAX_TOKEN + 1];
typedef union
{
    struct
    {
        Token szToken;      // token from the query
        int iCategory;      // category CAT_LPAREN, CAT_RPAREN, CAT_OPERATOR, CAT_OPERAND
        int iPrecedence;    // operator precedence with 0 being lowest
    };
    struct
    {
        Token szBoolean;    // This is to aid in debugging
        int bInclude;       // TRUE - intermediate include result, FALSE - intermediate don\'t include
    };
} Element;
typedef struct
{
    int iCount;             // number of elements in stack. 0 is empty
    Element stackElementM[MAX_STACK_ELEM];
} StackImp;
typedef StackImp *Stack;
typedef struct
{
    int iPostfixOutCount;
    Element postfixOutM[MAX_OUT_ITEM];
} PostfixOutImp;
typedef PostfixOutImp *PostfixOut;

void printCourseData(Course courseM[], int iNumCourse);
int convertToPostfix(char *pszInfix, PostfixOut postfixOut);
int PrintOutRest(Stack stack2, int bFoundOperand2, Element popped2, PostfixOut out2);
void evaluatePostfix(PostfixOut postfixOut, Course courseM[], int iNumCourse, QueryResult resultM[]);
int atLeastOne(Course *pCourse, Attr attr);
int only(Course *pCourse, Attr attr);
void operatorCheck(Stack stack, Element element, Element popped, PostfixOut postfixOut);
void rightParentCheck(Stack stack, Element popped, PostfixOut postfixOut);
void push(Stack stack, Element value);
Element pop(Stack stack);
int isEmpty(Stack stack);
Stack newStack();
void freeStack(Stack stack);
Element topElement(Stack stack);
void categorize(Element *pElement);
void addPostfixOut(PostfixOut postfixOut, Element element);
void printPostfixOut(PostfixOut postfixOut);
void printQueryResult(Course courseM[], int iNumCourse, QueryResult resultM[]);
int getCourseData(Course courseM[]);
void readAndProcessQueries(Course courseM[], int iNumberOfCourses);
int never(Course *pCourse, Attr attr);
void processCommandSwitches(int argc, char *argv[], char **ppszCourseFileName
    , char **ppszQueryFileName);
void exitUsage(int iArg, char *pszMessage, char *pszDiagnosticInfo);
void ErrExit(int iexitRC, char szFmt[], ...);
char * getToken(char *pszInputTxt, char szToken[], int iTokenSize);

#define WARNING(szFmt, ...) do {    \\
    printf(\"\\tWARNING: \");          \\
    printf(szFmt, __VA_ARGS__);     \\
    printf(\"\ \");                   \\
    } while (0)
  
cs2123p2.c

#include \"cs2123p2.h\"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>

void printCourseData(Course courseM[], int iNumCourse)
{
    int i;
    int j;
    printf(\"%-8s %-21s\ \\t\\t\\t\\t\\t\\t %-7s %-8s\ \"
           ,\"ID\"
           ,\"Course Name\"
           ,\"Attr\"
           ,\"Value\");
  
    for (i = 0; i < iNumCourse; i++)
    {
        printf(\"%-8s %-21s\ \", courseM[i].szCourseId, courseM[i].szCourseName);
        for (j = 0; j < courseM[i].iNumberOfAttrs; j++)
        {
            printf(\"\\t\\t\\t\\t\\t\\t%-7s %-8s\ \", courseM[i].attrM[j].szAttrType, courseM[i].attrM[j].szAttrValue);
        }
    }
}
int convertToPostfix(char *pszInfix, PostfixOut out){
        int bFoundOperand=TRUE;//Used to see if there\'s a missing Operand
        int bFoundOperator=TRUE;//Used to see if there\'s a missing Operator
        int bFoundLeftParen;//Used to find if there\'s a missing Left Parantheses
        Stack stack=newStack();//Stack where we cram everything in to
        Element element;//Store all values in here
        Element popped;//Structure used to a store a temp element structure
        pszInfix=getToken(pszInfix, element.szToken, MAX_TOKEN); //Used to input the token into the element structure
        categorize(&element); //Used to store values inside the element strucutre

    while (pszInfix!=NULL){
        categorize(&element);
        switch(element.iCategory)
            {
                case CAT_LPAREN:
                    bFoundLeftParen=TRUE;
                    push(stack,element);
                    break;

                case CAT_RPAREN:
                    bFoundLeftParen=FALSE;
                    while(!isEmpty(stack))
                    {
                        popped=pop(stack);
                        if(popped.iCategory == CAT_LPAREN)
                        {
                            bFoundLeftParen=TRUE;
                            break;
                        }
                        addPostfixOut(out, popped);
                    }
                    if(bFoundLeftParen==FALSE){
                        free(stack);
                        return WARN_MISSING_LPAREN;
                    }
                    break;

                case CAT_OPERATOR:
                if(bFoundOperator==TRUE)
                {
                    free(stack);
                    return WARN_MISSING_OPERAND;
                    break;
                }
                else{
                    bFoundOperator=TRUE;
                    bFoundOperand=TRUE;
                    while(!isEmpty(stack))
                    {  
                        if((element.iPrecedence > topElement(stack).iPrecedence))
                            {
                                break;
                            }
                            popped=pop(stack);
                            addPostfixOut(out, popped);
                        }
                            push(stack, element);
                            break;
                    }

                    case CAT_OPERAND:
                    if(bFoundOperator == FALSE){
                        free(stack);
                        return WARN_MISSING_OPERATOR;
                        break;
                    }
                    else if(bFoundOperator == FALSE){
                        free(stack);
                        return WARN_MISSING_OPERAND;
                        break;
                    }
                    else
                    {
                        addPostfixOut(out, element);
                        bFoundOperator=FALSE;
                        bFoundOperand=FALSE;
                        break;
                    }
               }

         pszInfix=getToken(pszInfix, element.szToken, MAX_TOKEN);
    }

return PrintOutRest(stack, bFoundOperand, popped, out);
}
int PrintOutRest(Stack stack2, int bFoundOperand2, Element popped2, PostfixOut out2)
{
    while(!isEmpty(stack2))
        {
            if(bFoundOperand2==TRUE)
            {
                free(stack2);
                return WARN_MISSING_OPERAND;
            }
            popped2=pop(stack2);
            if(popped2.iCategory == CAT_LPAREN)
            {
                free(stack2);
                return WARN_MISSING_RPAREN;
            }
                     
            addPostfixOut(out2, popped2);
        }
    freeStack(stack2);
    return 0;
}

void evaluatePostfix(PostfixOut postfixOut, Course courseM[], int iNumCourse, QueryResult resultM[])
{  
   int i,j;
   Element postElem;
   Stack stack = newStack();
   Element temp1, temp2, booleanCheck;
   Attr tempAttr;
   for(i = 0; i < iNumCourse; i++){
       for(j = 0; j < postfixOut->iPostfixOutCount; j++)
       {
           postElem = postfixOut->postfixOutM[j];
          
          
           switch(postElem.iCategory)
           {
               case(CAT_OPERAND):
                   push(stack, postElem);
                   break;//END OF CASE OPERAND
              
              
               case(CAT_OPERATOR):  
                   //pop the last 2 elements
                   temp1 = pop(stack);
                   strcpy(tempAttr.szAttrValue, temp1.szToken);
                   temp2 = pop(stack);
                   strcpy(tempAttr.szAttrType, temp2.szToken);
                                      
                   //If token is an equal sign
                   if(strcmp(postElem.szToken, \"=\")==0)
                   {                                                  
                       postElem.bInclude = atLeastOne(&courseM[i], tempAttr);
                       push(stack, postElem);          
                              
                       break;
                   }
                   //If token is NEVER
                   if(strcmp(postElem.szToken, \"NEVER\")==0)
                   {
                       postElem.bInclude = never(&courseM[i], tempAttr);                  
                       push(stack, postElem);                  
                       break;
                   }
                   if(strcmp(postElem.szToken, \"ONLY\")==0)
                   {
                       postElem.bInclude = only(&courseM[i], tempAttr);                  
                       push(stack, postElem);                  
                       break;
                   }
                   if(strcmp(postElem.szToken, \"OR\")==0)
                   {                                              
                       if(temp1.bInclude == TRUE || temp2.bInclude == TRUE)
                           postElem.bInclude = TRUE;
                       else
                           postElem.bInclude = FALSE;      
                      
                       push(stack, postElem);          
                          
                   }
                   if(strcmp(postElem.szToken, \"AND\")==0)
                   {
                       if(temp1.bInclude == TRUE && temp2.bInclude == TRUE)
                           postElem.bInclude = TRUE;
                       else
                           postElem.bInclude = FALSE;
                       push(stack, postElem);
                   }  
           }//End of switch      
       }//End of inner for loop
       while( !isEmpty(stack))
       {
           booleanCheck = pop(stack);
           if(booleanCheck.bInclude == FALSE)
           {
               resultM[i] = FALSE;
               break;
           }
           else
           {
           resultM[i] = TRUE;
           }
       }//End of while loop
          
   }//End of outer for loop
   freeStack(stack);
  
}//End of function

int atLeastOne(Course *pCourse, Attr attr)
{
   int i = 100;
    if (pCourse == NULL)
        ErrExit(ERR_ALGORITHM
        , \"function never() received a NULL pointer\");
    for (i = 0; i < (pCourse->iNumberOfAttrs); i++)
    {  
        if (strcmp(pCourse->attrM[i].szAttrType, attr.szAttrType) == 0
            && strcmp(pCourse->attrM[i].szAttrValue, attr.szAttrValue) == 0)
            return TRUE;
    }
    return FALSE;
}

int only(Course *pCourse, Attr attr)
{
   int i = 100;
    if (pCourse == NULL)
        ErrExit(ERR_ALGORITHM
        , \"function never() received a NULL pointer\");
    for (i = 0; i < (pCourse->iNumberOfAttrs); i++)
    {
        if (strcmp(pCourse->attrM[i].szAttrType, attr.szAttrType) == 0
            && strcmp(pCourse->attrM[i].szAttrValue, attr.szAttrValue) != 0)
            return FALSE;
    }
    return TRUE;
}

Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev
Input: There are two input files: course data and queries. See cs2123p2Driver.c for more information. Read the infix expressions Convert the infix to postfix Ev

Get Help Now

Submit a Take Down Notice

Tutor
Tutor: Dr Jack
Most rated tutor on our site