In: Computer Science
Take all the methods from this program and put it into single program and compile, and then test the program with some expressions. Should have two files: Lex.java and a output.txt file package lexicalanalyser; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.logging.Level; import java.util.logging.Logger; enum CharacterClass{ LETTER(0), DIGIT(1), UNKNOWN(99), EOF(-1); private int value; private CharacterClass(int value){ this.value = value; } public int getValue(){ return value; } } enum TokenCodes{ INT_LIT(10), IDENT(11), ASSIGN_OP(20), ADD_OP(21), SUB_OP(22), MULT_OP(23), DIV_OP(24), LEFT_PAREN(25), RIGHT_PAREN(26), SEMI_COLUMN(27), COMP_OP_SMALL(28), COMP_OP_LARGE(29), COMP_OP_EQUAL(30), EOF(-1), EOL(-2); private int value; private TokenCodes(int value){ this.value = value; } public int getValue(){ return value; } } public class LexicalAnalyser { /* Global Declarations */ /* Variables */ static CharacterClass charClass; static char[] lexeme = new char[100]; static char nextChar; static int count = 0; static int lexLen; static int token; static TokenCodes nextToken; static File in_fp; static FileReader fr; public static void main(String[] args) throws FileNotFoundException, IOException { /* Open the input data file and process its contents */ try{ in_fp = new File("front.in"); fr = new FileReader(in_fp); getChar(); do{ lex(); }while (nextToken != TokenCodes.EOF); System.out.println("Parsing Complete!"); }catch (FileNotFoundException e){ System.out.println("Error - File Not Found"); }catch (IOException e){ System.out.println("Error - IO Exception"); } } /* lookup - a function to lookup operators and parentheses and return the token*/ static void lookup(char ch){ switch(ch){ case '(': addChar(); nextToken = TokenCodes.LEFT_PAREN; break; case ')': addChar(); nextToken = TokenCodes.RIGHT_PAREN; break; case '+': addChar(); nextToken = TokenCodes.ADD_OP; break; case '-': addChar(); nextToken = TokenCodes.SUB_OP; break; case '*': addChar(); nextToken = TokenCodes.MULT_OP; break; case '/': addChar(); nextToken = TokenCodes.DIV_OP; break; case '=': addChar(); nextToken = TokenCodes.ASSIGN_OP; break; case ';': addChar(); nextToken = TokenCodes.SEMI_COLUMN; break; case '>': addChar(); nextToken = TokenCodes.COMP_OP_LARGE; break; case '<': addChar(); nextToken = TokenCodes.COMP_OP_SMALL; break; default: addChar(); nextToken = TokenCodes.EOF; break; } } /* addChar - a function to add nextChar to lexeme */ static void addChar(){ if(lexLen <= 98){ lexeme[lexLen++] = nextChar; lexeme[lexLen] = 0; }else{ System.out.println("Error - lexeme is too long"); } } /* getChar - a function to get the next character of of input and determine its character class*/ static void getChar(){ try { nextChar = (char)fr.read(); if(nextChar != 0){ if(Character.isLetter(nextChar)){ charClass = CharacterClass.LETTER; }else if(Character.isDigit(nextChar)){ charClass = CharacterClass.DIGIT; }else{ charClass = CharacterClass.UNKNOWN; } }else{ charClass = CharacterClass.EOF; } } catch (IOException ex) { Logger.getLogger(LexicalAnalyser.class.getName()).log(Level.SEVERE, null, ex); } } /* getNonBlank - a function to call getChar until it returns a non-whitespace character*/ static void getNonBlank(){ while(Character.isWhitespace(nextChar)){ getChar(); } } /* lex - a simple lexical analyzer for arithmetic expressions*/ static void lex(){ lexLen = 0; lexeme = new char[100]; getNonBlank(); //System.out.println("lex: c " + charClass); switch(charClass){ /* Parse Identifiers */ case LETTER: addChar(); getChar(); while(charClass == CharacterClass.LETTER || charClass == CharacterClass.DIGIT){ addChar(); getChar(); } nextToken = TokenCodes.IDENT; break; /* Parse integer literals */ case DIGIT: do{ addChar(); getChar(); }while (charClass == CharacterClass.DIGIT); nextToken = TokenCodes.INT_LIT; break; case UNKNOWN: lookup(nextChar); //System.out.println("NextToke: " + nextToken); getChar(); break; /* EOF */ case EOF: nextToken = TokenCodes.EOF; lexeme[0] = 'E'; lexeme[1] = 'O'; lexeme[2] = 'F'; lexeme[3] = 0; break; } System.out.printf("Next token is: %d, Next lexeme is %s\n",nextToken.getValue(),new String(lexeme)); } }
We are following the below approach :
1. output.txt file will be created if not exists in the current path.
2. Create FileWriter class object to write in text file.
3. If you want to append text in output file then provide true while creating FileWriter class object from output File class.
4. Change all the print statement to FileWriter_Object.write();
Please find the code snippet :
package lexicalanalyser;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
enum CharacterClass{
LETTER(0), DIGIT(1), UNKNOWN(99), EOF(-1);
private int value;
private CharacterClass(int value){
this.value = value;
}
public int getValue(){
return value;
}
}
enum TokenCodes{
INT_LIT(10), IDENT(11), ASSIGN_OP(20), ADD_OP(21),
SUB_OP(22), MULT_OP(23), DIV_OP(24), LEFT_PAREN(25),
RIGHT_PAREN(26), SEMI_COLUMN(27), COMP_OP_SMALL(28),
COMP_OP_LARGE(29), COMP_OP_EQUAL(30), EOF(-1), EOL(-2);
private int value;
private TokenCodes(int value){
this.value = value;
}
public int getValue(){
return value;
}
}
public class LexicalAnalyser {
/* Global Declarations */
/* Variables */
static CharacterClass charClass;
static char[] lexeme = new char[100];
static char nextChar;
static int count = 0;
static int lexLen;
static int token;
static TokenCodes nextToken;
static File in_fp;
static File out_fp;
static FileReader fr;
static FileWriter fr_out;
public static void main(String[] args) throws FileNotFoundException, IOException {
/* Open the input data file and process its contents */
try{
in_fp = new File("front.in");
out_fp = new File("output.txt");
if (!out_fp.exists()) {
out_fp.createNewFile();
System.out.println("Output File created: " + out_fp.getName());
} else {
System.out.println("Output File already exists.");
}
fr = new FileReader(in_fp);
// while creating File Writer class, provide true if you want to append in text file.
fr_out = new FileWriter(out_fp, true);
getChar();
do{
lex();
}while (nextToken != TokenCodes.EOF);
fr_out.write("Parsing Complete!");
}catch (FileNotFoundException e){
fr_out.write("Error - File Not Found");
}catch (IOException e){
fr_out.write("Error - IO Exception");
}
finally {
fr_out.close();
}
}
/* lookup - a function to lookup operators and parentheses
and return the token*/
static void lookup(char ch) throws IOException{
switch(ch){
case '(':
addChar();
nextToken = TokenCodes.LEFT_PAREN;
break;
case ')':
addChar();
nextToken = TokenCodes.RIGHT_PAREN;
break;
case '+':
addChar();
nextToken = TokenCodes.ADD_OP;
break;
case '-':
addChar();
nextToken = TokenCodes.SUB_OP;
break;
case '*':
addChar();
nextToken = TokenCodes.MULT_OP;
break;
case '/':
addChar();
nextToken = TokenCodes.DIV_OP;
break;
case '=':
addChar();
nextToken = TokenCodes.ASSIGN_OP;
break;
case ';':
addChar();
nextToken = TokenCodes.SEMI_COLUMN;
break;
case '>':
addChar();
nextToken = TokenCodes.COMP_OP_LARGE;
break;
case '<':
addChar();
nextToken = TokenCodes.COMP_OP_SMALL;
break;
default:
addChar();
nextToken = TokenCodes.EOF;
break;
}
}
/* addChar - a function to add nextChar to lexeme */
static void addChar() throws IOException{
if(lexLen <= 98){
lexeme[lexLen++] = nextChar;
lexeme[lexLen] = 0;
}else{
fr_out.write("Error - lexeme is too long");
}
}
/* getChar - a function to get the next character of
of input and determine its character class*/
static void getChar(){
try {
nextChar = (char)fr.read();
if(nextChar != 0){
if(Character.isLetter(nextChar)){
charClass = CharacterClass.LETTER;
}else if(Character.isDigit(nextChar)){
charClass = CharacterClass.DIGIT;
}else{
charClass = CharacterClass.UNKNOWN;
}
}else{
charClass = CharacterClass.EOF;
}
} catch (IOException ex) {
Logger.getLogger(LexicalAnalyser.class.getName()).log(Level.SEVERE, null, ex);
}
}
/* getNonBlank - a function to call getChar until it
returns a non-whitespace character*/
static void getNonBlank(){
while(Character.isWhitespace(nextChar)){
getChar();
}
}
/* lex - a simple lexical analyzer for arithmetic
expressions*/
static void lex() throws IOException{
lexLen = 0;
lexeme = new char[100];
getNonBlank();
//System.out.println("lex: c " + charClass);
switch(charClass){
/* Parse Identifiers */
case LETTER:
addChar();
getChar();
while(charClass == CharacterClass.LETTER ||
charClass == CharacterClass.DIGIT){
addChar();
getChar();
}
nextToken = TokenCodes.IDENT;
break;
/* Parse integer literals */
case DIGIT:
do{
addChar();
getChar();
}while (charClass == CharacterClass.DIGIT);
nextToken = TokenCodes.INT_LIT;
break;
case UNKNOWN:
lookup(nextChar);
//System.out.println("NextToke: " + nextToken);
getChar();
break;
/* EOF */
case EOF:
nextToken = TokenCodes.EOF;
lexeme[0] = 'E';
lexeme[1] = 'O';
lexeme[2] = 'F';
lexeme[3] = 0;
break;
}
fr_out.write("Next token is: "+nextToken.getValue()+", Next lexeme is "+new String(lexeme)+"\n");
}
}
Still if you have any question, please feel free to post in comment box. I would be glad to help you here.
If you like my explanation and answer, please give a thumbs up, it really motivates us to provide a good quality answer.