C++ Lexical Analyzer I need to add a parsar and my program needs to be able to c
ID: 3679603 • Letter: C
Question
C++ Lexical Analyzer
I need to add a parsar and my program needs to be able to catch any syntax error if it doesn't follow the grammar rules.
For example, if the syntax is "if (TRUE) A = (x + 4) / 3", your program should output: "ERROR - missing a semicolon".
Another example, if the syntax is "if (TRUE) A (x + 4) / 3;", your program should output: "ERROR - missing an assignment operator".
I just need to add the syntax error to my code to make it have the output stated above.
My code:
#include
#include
#include
using namespace std;
/* Global declarations */
/* Variables */
int charClass;
char lexeme[100];
char nextChar;
int lexLen;
int token;
int nextToken;
ifstream in_fp("syntax.txt");
/* Function declarations */
void getChar();
void addChar();
void getNonBlank();
// Function to get the nextToken
int lex();
/* Character classes */
#define LETTER 0
#define DIGIT 1
#define UNKNOWN 99
/* Token codes */
#define INT_LIT 10
#define IDENT 11
#define ADD_OP 21
#define SUB_OP 22
#define MULT_OP 23
#define DIV_OP 24
#define LEFT_PAREN 25
#define RIGHT_PAREN 26
#define EQUAL_OP 27
#define SEMICOLON_OP 26
/******************************************************/
/* Main function */
int main()
{
/* Open the input data file and process its contents */
if (in_fp.fail())
{
cout << "File could not be opened ";
cin.get();
exit(1);
}
else
{
getChar();
do
{
lex(); // Getting the nextToken
} while (nextToken != EOF);
}
// Close the file
in_fp.close();
}
/*****************************************************/
/* lookup - a function to lookup operators and parentheses
and return the token */
int lookup(char ch)
{
switch (ch)
{
case '(':
addChar();
nextToken = LEFT_PAREN;
//cout << " Left paranthesis: ";
break;
case ')':
addChar();
nextToken = RIGHT_PAREN;
//cout << " right paranthesis: ";
break;
case '+':
addChar();
nextToken = ADD_OP;
//cout << " add operator: ";
break;
case '-':
addChar();
nextToken = SUB_OP;
//cout << " sub operator: ";
break;
case '*':
addChar();
nextToken = MULT_OP;
//cout << " mult operator: ";
break;
case '/':
addChar();
nextToken = DIV_OP;
//cout << " div operator: ";
break;
case '%':
addChar();
nextToken = DIV_OP;
//cout << " Remainder operator: ";
break;
case '=':
addChar();
nextToken = EQUAL_OP;
//cout << " Equal operator: ";
break;
case ';':
addChar();
nextToken = SEMICOLON_OP;
//cout << " Semicolon operator: ";
break;
default:
addChar();
nextToken = EOF;
//cout << " EOF: ";
break;
}
return nextToken;
}
/*****************************************************/
/* addChar - a function to add nextChar to lexeme */
void addChar()
{
if (lexLen <= 398)
{
lexeme[lexLen++] = nextChar;
lexeme[lexLen] = 0;
}
else
cout << " Error - lexeme is too long ";
}
/*****************************************************/
/* getChar - a function to get the next character of
input and determine its character class */
void getChar()
{
in_fp.get(nextChar);
if (in_fp.eof()) // if no more character in the file
nextChar = EOF;
if (nextChar != EOF)
{
if (isalpha(nextChar))
charClass = LETTER;
else if (isdigit(nextChar))
charClass = DIGIT;
else charClass = UNKNOWN;
}
else
charClass = EOF;
}
/*****************************************************/
/* getNonBlank - a function to call getChar until it
returns a non-whitespace character */
void getNonBlank()
{
while (isspace(nextChar))
getChar();
}
/***************************************************** /
/* lex - a simple lexical analyzer for arithmetic
expressions */
int lex()
{
lexLen = 0;
getNonBlank();
switch (charClass)
{
/* Parse identifiers */
case LETTER:
addChar();
getChar();
while (charClass == LETTER || charClass == DIGIT)
{
addChar();
getChar();
}
nextToken = IDENT;
//cout << " Identifier : ";
break;
/* Parse integer literals */
case DIGIT:
addChar();
getChar();
while (charClass == DIGIT)
{
addChar();
getChar();
}
nextToken = INT_LIT;
//cout << " Number: ";
break;
/* Parentheses and operators */
case UNKNOWN:
lookup(nextChar);
getChar();
break;
/* EOF */
case EOF:
nextToken = EOF;
lexeme[0] = 'E';
lexeme[1] = 'O';
lexeme[2] = 'F';
lexeme[3] = 0;
break;
} /* End of switch */
cout << "Next token is: " << nextToken << " Next lexeme is " << lexeme << " ";
return nextToken;
} /* End of function lex */
Explanation / Answer
#include <iostream>
#include <string>
#include<ifstream>>
using namespace std;
/* Global declarations */
/* Variables */
int charClass;
char lexeme[100];
char nextChar;
int lexLen;
int token;
int nextToken;
char recentChar;
ifstream in_fp("syntax.txt");
/* Function declarations */
void getChar();
void addChar();
void getNonBlank();
// Function to get the nextToken
int lex();
/* Character classes */
#define LETTER 0
#define DIGIT 1
#define UNKNOWN 99
/* Token codes */
#define INT_LIT 10
#define IDENT 11
#define ADD_OP 21
#define SUB_OP 22
#define MULT_OP 23
#define DIV_OP 24
#define LEFT_PAREN 25
#define RIGHT_PAREN 26
#define EQUAL_OP 27
#define SEMICOLON_OP 26
/******************************************************/
/* Main function */
int main()
{
/* Open the input data file and process its contents */
if (in_fp.fail())
{
cout << "File could not be opened ";
cin.get();
exit(1);
}
else
{
getChar();
do
{
lex(); // Getting the nextToken
} while (nextToken != EOF);
if(recentChar != SEMICOLON_OP ){
cout<<"your program should output: ERROR - missing an semicolon";
exit(1);
}
}
// Close the file
in_fp.close();
}
/*****************************************************/
/* lookup - a function to lookup operators and parentheses
and return the token */
int lookup(char ch)
{
if(ch == LEFT_PAREN && recentChar == IDENT ){
cout<<"your program should output: ERROR - missing an assignment operator";
exit(1);
}
switch (ch)
{
case '(':
addChar();
nextToken = LEFT_PAREN;
//cout << " Left paranthesis: ";
break;
case ')':
addChar();
nextToken = RIGHT_PAREN;
recentChar = RIGHT_PAREN;
//cout << " right paranthesis: ";
break;
case '+':
addChar();
nextToken = ADD_OP;
recentChar = ADD_OP;
//cout << " add operator: ";
break;
case '-':
addChar();
nextToken = SUB_OP;
recentChar = SUB_OP;
//cout << " sub operator: ";
break;
case '*':
addChar();
nextToken = MULT_OP;
recentChar = MULT_OP;
//cout << " mult operator: ";
break;
case '/':
addChar();
nextToken = DIV_OP;
recentChar = DIV_OP;
//cout << " div operator: ";
break;
case '%':
addChar();
nextToken = DIV_OP;
recentChar = DIV_OP;
//cout << " Remainder operator: ";
break;
case '=':
addChar();
nextToken = EQUAL_OP;
recentChar = EQUAL_OP;
//cout << " Equal operator: ";
break;
case ';':
addChar();
nextToken = SEMICOLON_OP;
recentChar = SEMICOLON_OP;
//cout << " Semicolon operator: ";
break;
default:
addChar();
nextToken = EOF;
recentChar = EOF;
//cout << " EOF: ";
break;
}
return nextToken;
}
/*****************************************************/
/* addChar - a function to add nextChar to lexeme */
void addChar()
{
if (lexLen <= 398)
{
lexeme[lexLen++] = nextChar;
lexeme[lexLen] = 0;
}
else
cout << " Error - lexeme is too long ";
}
/*****************************************************/
/* getChar - a function to get the next character of
input and determine its character class */
void getChar()
{
in_fp.get(nextChar);
if (in_fp.eof()) // if no more character in the file
nextChar = EOF;
if (nextChar != EOF)
{
if (isalpha(nextChar))
charClass = LETTER;
else if (isdigit(nextChar))
charClass = DIGIT;
else charClass = UNKNOWN;
}
else
charClass = EOF;
}
/*****************************************************/
/* getNonBlank - a function to call getChar until it
returns a non-whitespace character */
void getNonBlank()
{
while (isspace(nextChar))
getChar();
}
/***************************************************** /
/* lex - a simple lexical analyzer for arithmetic
expressions */
int lex()
{
lexLen = 0;
getNonBlank();
switch (charClass)
{
/* Parse identifiers */
case LETTER:
addChar();
getChar();
while (charClass == LETTER || charClass == DIGIT)
{
addChar();
getChar();
}
nextToken = IDENT;
recentChar = IDENT;
//cout << " Identifier : ";
break;
/* Parse integer literals */
case DIGIT:
addChar();
getChar();
while (charClass == DIGIT)
{
addChar();
getChar();
}
nextToken = INT_LIT;
//cout << " Number: ";
break;
/* Parentheses and operators */
case UNKNOWN:
lookup(nextChar);
getChar();
break;
/* EOF */
case EOF:
nextToken = EOF;
lexeme[0] = 'E';
lexeme[1] = 'O';
lexeme[2] = 'F';
lexeme[3] = 0;
break;
} /* End of switch */
cout << "Next token is: " << nextToken << " Next lexeme is " << lexeme << " ";
return nextToken;
} /* End of function lex */
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.