CS441 - Homework #4
/*****************************************
Name: Thomas Heffron (tehqnf@umkc.edu)
Section: CS441 NET
Program: Homework #4 - Part 2
Due Date: Oct. 7, 2002
Desc: Program the parser for the BNF
language given in the assignment
Inputs: Sentence read from file input.par
located in the current directory
Outputs: Each token match is listed in order
and any reverse is noted. End of
string is noted and final display
of validity of string.
******************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUF_LEN 1024
/* Global vairables needed */
char sentence[BUF_LEN];
int master_sentinel = 0;
int token_sentinel = 0;
char token[50];
int main()
{
/* Local variables */
char strval;
/* Function definitions */
void read_file(char *value);
void check_token();
int proviso();
/* Read input */
read_file(sentence);
/* Call first sentence form */
if (proviso()) {
printf("This is a valid string in this language\n");
} else {
printf("This is NOT a valid string\n");
}
return 0;
}
/******************
Function to remove line feeds from string
******************/
void remove_crln(char *value)
{
int str_len, i = 0;
str_len = strlen(value);
while (value[i] != '\0') {
if (value[i] == '\n') {
if (value[i + 1] == '\0') {
value[i] = '\0';
} else {
value[i] = ' ';
}
}
i++;
}
}
/*********************
Function to read input from file
*********************/
void read_file(char *value)
{
FILE *in_file;
in_file = fopen("input.par", "r");
fgets(value, BUF_LEN, in_file);
remove_crln(value);
fclose(in_file);
}
/********************
Function to keep the master sentinel updated
********************/
void update_sentinel() {
master_sentinel = token_sentinel;
}
/********************
Function to get the next token in the string
and save it to the 'token' variable. This will
the skip all blank spaces. It will return any
single parentheses character or the next word
delimeted by blanks or parentheses.
********************/
void check_token()
{
int i = token_sentinel, j = 0;
strcpy(token, "\0");
if (sentence[i] != '\0') {
while (sentence[i] == ' ') {
i++;
token_sentinel++;
}
if (sentence[i] == '(') {
token[0] = '(';
token[1] = '\0';
i++;
} else if (sentence[i] == ')') {
token[0] = ')';
token[1] = '\0';
i++;
} else {
while ((sentence[i] != ' ')
&& (sentence[i] != '(')
&& (sentence[i] != ')')
&& (sentence[i] != '\0')) {
token[j] = sentence[i];
i++;
j++;
}
token[j] = '\0';
}
token_sentinel = i;
} else {
printf("Found end-of-string\n");
}
}
/************************
Function to determine if token is
<filledSlot>. Valid values are 'filled'
or 'partial'.
************************/
int filledSlot() {
int fill_sent = token_sentinel;
check_token();
if ( (strcmp(token, "filled") == 0)
|| (strcmp(token, "partial") == 0) ) {
printf("Token match: <filledSlot>\n");
update_sentinel;
return 1;
} else {
token_sentinel = fill_sent;
return 0;
}
}
/***********************
Function to determine if token is
<noDirectionFixed>. Valid values are
'stalled' or halted'.
***********************/
int noDirectionFixed() {
int noD_sent = token_sentinel;
check_token();
if ( (strcmp(token, "stalled") == 0)
|| (strcmp(token, "halted") == 0) ) {
printf("Token match: <noDirectionFixed>\n");
update_sentinel();
return 1;
} else {
token_sentinel = noD_sent;
return 0;
}
}
/***************************
Function to determine if token is
<factor>. Valid values are 'one-fourth',
'one-third', 'one-half', 'two-thirds',
or 'three-fourths'.
***************************/
int factor() {
int fact_sent = token_sentinel;
check_token();
if ( (strcmp(token, "one-fourth") == 0)
|| (strcmp(token, "one-third") == 0)
|| (strcmp(token, "one-half") == 0)
|| (strcmp(token, "two-thirds") == 0)
|| (strcmp(token, "three-fourths") == 0) ) {
printf("Token match: <factor>\n");
update_sentinel();
return 1;
} else {
token_sentinel = fact_sent;
return 0;
}
}
/**************************
Function to determine if token is
<bunch>. Valid values are 'gather'
and 'bundle'.
**************************/
int bunch() {
int bunc_sent = token_sentinel;
check_token();
if ( (strcmp(token, "gather") == 0)
|| (strcmp(token, "bundle") == 0) ) {
printf("Token match: <bunch>\n");
update_sentinel();
return 1;
} else {
token_sentinel = bunc_sent;
return 0;
}
}
/**************************
Function to determine if token is <enhanceGreatly>.
**************************/
int enhanceGreatly() {
int EG_sent = token_sentinel;
check_token();
if ( (strcmp(token, "EG") == 0)
|| (strcmp(token, "DG") == 0)
|| (strcmp(token, "PDG") == 0)
|| (strcmp(token, "PEG") == 0)
|| (strcmp(token, "both") == 0) ) {
printf("Token match: <enhanceGreatly>\n");
update_sentinel();
return 1;
} else {
token_sentinel = EG_sent;
return 0;
}
}
/************************
Function to determine if token is
<direction>. Valid values are 'north',
'south', 'east', and 'west'.
************************/
int direction() {
int dire_sent = token_sentinel;
check_token();
if ( (strcmp(token, "east") == 0)
|| (strcmp(token, "west") == 0)
|| (strcmp(token, "north") == 0)
|| (strcmp(token, "south") == 0) ) {
printf("Token match: <direction>\n");
update_sentinel();
return 1;
} else {
token_sentinel = dire_sent;
return 0;
}
}
/***********************
Function to determine if token is <oneTime>.
***********************/
int oneTime() {
int oneT_sent = token_sentinel;
if (filledSlot()
|| direction()
|| noDirectionFixed()
|| bunch() ) {
return 1;
} else {
token_sentinel = oneT_sent;
check_token();
if ( (strcmp(token, "doNot") == 0) ) {
printf("Token match: doNot\n");
if (oneTime()) {
return 1;
} else {
return 0;
}
} else if ( (strcmp(token, "(") == 0) ) {
printf("Token match: (\n");
if (thisHappens()) {
check_token();
if ((strcmp(token, ")")== 0) ) {
printf("Token match: )\n");
update_sentinel();
return 1;
} else {
token_sentinel = oneT_sent;
return 0;
}
}
} else {
token_sentinel = oneT_sent;
return 0;
}
}
}
/*****************
Function to determine if token is <enhancer>.
*****************/
int enhancer() {
int enha_sent = token_sentinel;
check_token();
if ( (strcmp(token, "enhanced") == 0)
|| (strcmp(token, "unenhanced") == 0)
|| (strcmp(token, "otherwise") == 0) ) {
printf("Token match: <enhancer>\n");
update_sentinel();
return 1;
} else {
token_sentinel = enha_sent;
return 0;
}
}
/**********************
Function to determine if token is <semester>.
**********************/
int semester() {
int sem_sent = token_sentinel;
if (oneTime()) {
} else {
return 0;
}
while(enhanceGreatly()) {
if (factor()) {
} else {
return 0;
}
}
return 1;
}
/***************************
Function to determine if token is <between>.
***************************/
int between() {
int betw_sent = token_sentinel;
check_token();
if ( (strcmp(token, "assign") == 0)
|| (strcmp(token, "decrease") == 0)
|| (strcmp(token, "mightDecrease") == 0)
|| (strcmp(token, "mightIncrease") == 0)
|| (strcmp(token, "increase") == 0)
|| (strcmp(token, "within") == 0) ) {
printf("Token match: <between>\n");
update_sentinel();
return 1;
} else {
token_sentinel = betw_sent;
return 0;
}
}
/*****************************
Function to determine if token is <once>.
*****************************/
int once() {
int once_sent = token_sentinel;
int dir_and_sem = 0;
if (direction()) {
if (semester()) {
dir_and_sem = 1;
} else {
printf("Must reparse previous token.\n");
}
}
if (!(dir_and_sem)) {
token_sentinel = once_sent;
if (semester()) {
} else {
return 0;
}
}
while (enhancer()) {
if (semester()) {
} else {
return 0;
}
}
return 1;
}
/********************************
Function to determine if token is <thisWillOccur>.
Valid values are 'thisWillOccur' of 'thatWillOccur'.
********************************/
int thisWillOccur() {
int thisW_sent = token_sentinel;
check_token();
if ( (strcmp(token, "thisWillOccur") == 0)
|| (strcmp(token, "thatWillOccur") == 0) ) {
printf("Token match: <thisWillOccur>\n");
update_sentinel();
return 1;
} else {
return 0;
}
}
/*********************************
Function to determine if tokens make <thisHappens>
*********************************/
int thisHappens() {
int thisH_sent = token_sentinel;
if (once()) {
if (between()) {
if (once()) {
return 1;
} else {
return 0;
}
} else {
return 1;
}
} else {
return 0;
}
}
/***************************
Function to determine if tokens make
***************************/
int proviso() {
int i = token_sentinel;
check_token();
if (strcmp(token, "provided") == 0) {
printf("Token match: provided\n");
update_sentinel();
} else {
return 0;
}
if (thisHappens()) {
} else {
return 0;
}
check_token();
if (strcmp(token, "subsequently") == 0) {
printf("Token match: subsequently\n");
update_sentinel();
} else {
return 0;
}
if (thisWillOccur()) {
} else {
return 0;
}
check_token();
if (token[0] == '\0') {
return 1;
} else if (strcmp(token, "however") == 0) {
printf("Token match: however\n");
update_sentinel();
if (thisWillOccur()) {
return 1;
} else {
return 0;
}
check_token();
if (token[0] == '\0') {
update_sentinel();
return 1;
} else {
return 0;
}
} else {
return 0;
}
}