I need help on Chapter 4, Problem 6PE in the Concepts of Programming Languages 1
ID: 3804608 • Letter: I
Question
I need help on Chapter 4, Problem 6PE in the Concepts of Programming Languages 10th Edition book. The problem is to convert the lexical analyzer (which is written in C) given in Section 4.2 to Java. Any help would be greatly appreciated!
Below is the code in C that needs to be converted to Java:
#include <stdio.h>
#include <ctype.h>
/* Global Declarations */
/* Variables */
int charClass;
char lexeme[100];
char nextChar;
int lexLen;
int token;
int nextToken;
FILE *in_fp, *fopen();
/* Function Declarations */
void addChar();
void getChar();
void getNonBlank();
int lex();
/* Character Classes */
#define LETTER 0
#define DIGIT 1
#define UNKNOWN 99
/* Token Codes */
#define INT_LIT 10
#define IDENT 11
#define ASSIGN_OP 20
#define ADD_OP 21
#define SUB_OP 22
#define MULT_OP 23
#define DIV_OP 24
#define LEFT_PAREN 25
#define RIGHT_PAREN 26
/* **************************************** */
/* Main Driver */
main() {
/* Open the input data file and process its contents */
if ((in_fp = fopen("front.in", "r")) == NULL)
printf("ERROR - cannot open front.in ");
else {
getChar();
do {
lex();
} while (nextToken != EOF);
}
}
/* **************************************** */
/* lookup - a function to lookup operators and parentheses
and return the token */
int lookup(char ch) {
switch (ch) {
case '(':
addChar();
nextToken = LEFT_PAREN;
break;
case ')':
addChar();
nextToken = RIGHT_PAREN;
break;
case '+':
addChar();
nextToken = ADD_OP;
break;
case '-':
addChar();
nextToken = SUB_OP;
break;
case '*':
addChar();
nextToken = MULT_OP;
break;
case '/':
addChar();
nextToken = DIV_OP;
break;
default:
addChar();
nextToken = EOF;
break;
}
return nextToken;
}
/* **************************************** */
/* addChar - a function to add nextChar to lexeme */
void addChar() {
if (lexLen <= 98) {
lexeme[lexLen++] = nextChar;
lexeme[lexLen] = 0;
}
else
printf("Error - lexeme is too long ");
}
/* **************************************** */
/* getChar - a function to get the next character
of input and determine its character class*/
void getChar() {
if ((nextChar = getc(in_fp)) != 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;
break;
/* parse integer literals and integers */
case DIGIT:
addChar();
getChar();
while(charClass == DIGIT){
addChar();
getChar();
}
nextToken = INT_LIT;
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 */
printf("Next token is: %d, Next lexeme is %s ",
nextToken, lexeme);
return nextToken;
} /* end of function lex */
Explanation / Answer
//Same Java code for given C code is as follows :
//It contains all methods with same functionality given in C program.
import java.io.*;
import java.util.*;
public class lex_convert
{
private static final int LETTER=0;
private static final int DIGIT=1;
private static final int UNKNOWN=99;
private static final int EOF=-1;
private static final int INT_LIT=10;
private static final int IDENT=11;
private static final int ASSIGN_OP=20;
private static final int ADD_OP=21;
private static final int SUB_OP=22;
private static final int MULT_OP=23;
private static final int DIV_OP=24;
private static final int LEFT_PAREN=25;
private static final int RIGHT_PAREN=26;
private static int charClass;
private static char lexeme[];
private static char nextChar;
private static int lexLen;
private static int token;
private static int nextToken;
private static File file;
private static FileInputStream fis;
public static int lookup(char ch)
{
switch (ch)
{
case '(':
addChar();
nextToken = LEFT_PAREN;
break;
case ')':
addChar();
nextToken = RIGHT_PAREN;
break;
case '+':
addChar();
nextToken = ADD_OP;
break;
case '-':
addChar();
nextToken = SUB_OP;
break;
case '*':
addChar();
nextToken = MULT_OP;
break;
case '/':
addChar();
nextToken = DIV_OP;
break;
default:
addChar();
nextToken = EOF;
break;
}
return nextToken;
}
public static void addChar()
{
if (lexLen <= 98)
{
lexeme[lexLen++] = nextChar;
// lexeme[lexLen] = 0;
}
else
System.out.println("Error -lexeme is too long ");
}
public static void getChar()
{
try
{
if(fis.available()>0)
{
nextChar=(char)fis.read();
if(Character.isLetter(nextChar))
charClass=LETTER;
else if(Character.isDigit(nextChar))
charClass=DIGIT;
else
charClass=UNKNOWN;
}
else
charClass=EOF;
// System.out.println(nextChar+" "+charClass);
}
catch(IOException e)
{
e.printStackTrace();
}
}
public static void getNonBlank()
{
while(Character.isSpaceChar(nextChar))
getChar();
}
public static int lex()
{
lexLen = 0;
getNonBlank();
switch (charClass)
{
/* parse identifiers */
case LETTER:
addChar();
getChar();
while (charClass == LETTER || charClass == DIGIT)
{
addChar();
getChar();
}
nextToken = IDENT;
break;
/* parse integer literals and integers */
case DIGIT:
addChar();
getChar();
while(charClass == DIGIT)
{
addChar();
getChar();
}
nextToken = INT_LIT;
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 */
System.out.print("Next token is :"+nextToken+" Next lexeme is :");
for(int i=0;i<lexLen;i++)
System.out.print(lexeme[i]);
System.out.println();
return nextToken;
}
public static void main(String args[])
{
lexLen=0;
lexeme=new char[100];
for(int i=0;i<100;i++)
lexeme[i]='0';
file = new File("input1.txt");
if (!file.exists())
{
System.out.println( "input1.txt does not exist.");
return;
}
if (!(file.isFile() && file.canRead()))
{
System.out.println(file.getName() + " cannot be read from.");
return;
}
try
{
fis = new FileInputStream(file);
char current;
while (fis.available() > 0)
{
getChar();
// System.out.println(nextChar+" "+charClass);
lex();
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
//Given input file input1.txt contains
asdafasdf 4234234 2
//Output :
G580:~/codes/schegg$ javac lex_convert.java
G580:~/codes/schegg$ java lex_convert
Next token is :11 Next lexeme is :asdafasdf
Next token is :10 Next lexeme is :4234234
Next token is :10 Next lexeme is :2
G580:~/codes/schegg$
Related Questions
drjack9650@gmail.com
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.