FORMAT CLASS
class Format
{
private Lexer lexer;
private Output output;
private Token token;
// The constructor establishes the input lexer and the output
// private data members.
public Format(Lexer lexer, Output output)
{
this.lexer = lexer;
this.output = output;
}
// file is the only public method. External
// declarations are formatted until a function is found, at
// which time functionBody is called to format it.
public void file()
{
token = lexer.getNextToken();
while (token != Token.END_OF_FILE)
if (externalDeclaration())
functionBody();
}
// functionBody formats the declarations and statements in a
// function body.
private void functionBody()
{
output.endLine(true);
while (token == Token.TYPE_SPECIFIER ||
token == Token.SC_SPECIFIER ||
token == Token.STRUCT || token == Token.UNION ||
token == Token.UPPER_CASE_IDENTIFIER)
parameterDeclaration();
output.indent();
output.endLine(false);
output.skipLine();
compoundStatement();
output.unindent();
output.endLine(false);
output.endPage();
}
// compoundStatement formats a multiple statement block
private void compoundStatement()
{
int noOfDeclarations= 0;
token = lexer.getNextToken();
output.endLine(false);
while (token == Token.TYPE_SPECIFIER ||
token == Token.SC_SPECIFIER ||
token == Token.STRUCT || token == Token.UNION ||
token == Token.UPPER_CASE_IDENTIFIER)
{
declaration();
noOfDeclarations++;
}
if (noOfDeclarations > 0)
output.skipLine();
while (token != Token.RIGHT_BRACE)
statement();
token = lexer.getNextToken();
output.endLine(false);
}
// statement determines the type of statement and calls the
// appropriate function to format it.
private void statement()
{
if (token == Token.IDENTIFIER)
if ((token = lexer.getNextToken()) == Token.COLON)
token = lexer.getNextToken();
else
{
token = Token.IDENTIFIER;
lexer.putLastToken();
}
switch (token)
{
case LEFT_BRACE:
compoundStatement();
break;
case SWITCH:
switchStatement();
break;
case BREAK:
case CONTINUE:
verifyNextToken(Token.SEMICOLON);
output.endLine(false);
break;
case RETURN:
if ((token = lexer.getNextToken()) != Token.SEMICOLON)
{
expression(Token.SEMICOLON);
token = lexer.getNextToken();
}
else
token = lexer.getNextToken();
output.endLine(false);
break;
case GOTO:
verifyNextToken(Token.IDENTIFIER);
verifyNextToken(Token.SEMICOLON);
output.endLine(false);
break;
case FOR:
forStatement();
break;
case IF:
ifStatement();
break;
case WHILE:
whileStatement();
break;
case DO:
doStatement();
break;
default:
expression(Token.SEMICOLON);
token = lexer.getNextToken();
output.endLine(false);
}
}
// switchStatement formats a switch statement.
private void switchStatement()
{
verifyNextToken(Token.LEFT_PARENTHESIS);
expression(Token.RIGHT_PARENTHESIS);
token = lexer.getNextToken();
output.endLine(false);
output.indent();
verifyCurrentToken(Token.LEFT_BRACE);
output.endLine(false);
while (token == Token.CASE || token == Token.DEFAULT)
{
expression(Token.COLON);
lexer.adjustSpacing(Lexer.SUPPRESS_LEADING_SPACE);
token = lexer.getNextToken();
output.endLine(false);
output.indent();
while (token != Token.CASE && token != Token.DEFAULT &&
token != Token.RIGHT_BRACE)
statement();
output.unindent();
}
verifyCurrentToken(Token.RIGHT_BRACE);
output.endLine(false);
output.unindent();
}
private void ifStatement()
{
verifyNextToken(Token.LEFT_PARENTHESIS);
expression(Token.RIGHT_PARENTHESIS);
token = lexer.getNextToken();
output.endLine(false);
output.indent();
statement();
if (token == Token.ELSE)
{
output.unindent();
token = lexer.getNextToken();
expression(token);
output.endLine(false);
output.indent();
statement();
}
//expression(Token.SEMICOLON);
output.endLine(false);
output.unindent();
}
private void forStatement()
{
/*verifyNextToken(Token.LEFT_PARENTHESIS);
expression(Token.RIGHT_PARENTHESIS);
token = lexer.getNextToken();
output.endLine(false);
output.indent();
verifyCurrentToken(Token.LEFT_BRACE);
output.endLine(false);
expression(Token.SEMICOLON);
lexer.adjustSpacing(Lexer.SUPPRESS_LEADING_SPACE);
token = lexer.getNextToken();
output.endLine(false);
output.unindent();
verifyCurrentToken(Token.RIGHT_BRACE);
output.endLine(false);
output.unindent();*/
verifyNextToken(Token.LEFT_PARENTHESIS);
expression(Token.RIGHT_PARENTHESIS);
token = lexer.getNextToken();
output.endLine(false);
output.indent();
statement();
output.endLine(false);
output.unindent();
}
private void whileStatement()
{
verifyNextToken(Token.LEFT_PARENTHESIS);
expression(Token.RIGHT_PARENTHESIS);
//if(token != Token.SEMICOLON){
//output.endLine(false);
//}
token = lexer.getNextToken();
output.endLine(false);
output.indent();
statement();
output.endLine(false);
output.unindent();
}
private void doStatement()
{
//verifyNextToken(Token.LEFT_PARENTHESIS);
token = lexer.getNextToken();
expression(token);
output.endLine(false);
output.indent();
statement();
output.endLine(false);
output.unindent();
}
// externalDeclarations formats external declarations such as
// global variables and function prototypes. It returns if
// it encounters a function heading.
private boolean externalDeclaration()
{
int braceCount = 0;
boolean indentAtSemicolon = false;
Token lastToken = Token.NOT_FOUND;
while ((braceCount > 0) || (token != Token.SEMICOLON))
{
lexer.checkDeclarationSpacing(token);
if (token == Token.LEFT_BRACE)
{
output.endLine(false);
output.indent();
lastToken = token;
token = lexer.getNextToken();
output.endLine(false);
braceCount++;
}
else if (token == Token.RIGHT_BRACE)
{
lastToken = token;
token = lexer.getNextToken();
indentAtSemicolon = true;
braceCount--;
}
else if (token == Token.LEFT_PARENTHESIS)
{
lastToken = token;
token = lexer.getNextToken();
}
else if (token == Token.RIGHT_PARENTHESIS)
{
lastToken = token;
token = lexer.getNextToken();
if (token != Token.SEMICOLON)
return true;
}
else if (token == Token.ASSIGNMENT_OPERATOR)
while (token != Token.SEMICOLON)
{
lastToken = token;
token = lexer.getNextToken();
lexer.checkExpressionSpacing(token, lastToken);
}
else if (token == Token.SEMICOLON)
{
lastToken = token;
token = lexer.getNextToken();
if (braceCount > 0)
output.endLine(false);
if (indentAtSemicolon)
{
output.indent();
indentAtSemicolon = false;
}
}
else
{
lastToken = token;
token = lexer.getNextToken();
}
}
token = lexer.getNextToken();
output.endLine(false);
if (indentAtSemicolon)
output.indent();
return false;
}
// parameterDeclaration formats parameter declarations.
private void parameterDeclaration()
{
int braceCount = 0;
while ((braceCount > 0) || (token != Token.SEMICOLON))
{
lexer.checkDeclarationSpacing(token);
if (token == Token.LEFT_BRACE)
{
output.endLine(false);
output.indent();
token = lexer.getNextToken();
output.endLine(false);
braceCount++;
}
else if (token == Token.RIGHT_BRACE)
{
token = lexer.getNextToken();
output.indent();
braceCount--;
}
else if ((braceCount > 0 ) && (token == Token.SEMICOLON))
{
token = lexer.getNextToken();
output.endLine(false);
}
else
token = lexer.getNextToken();
}
token = lexer.getNextToken();
output.endLine(false);
}
// declaration formats local declarations.
private void declaration()
{
int braceCount = 0;
boolean indentAtSemicolon = false;
while ((braceCount > 0) || (token != Token.SEMICOLON))
{
lexer.checkDeclarationSpacing(token);
if (token == Token.LEFT_BRACE)
{
output.endLine(false);
output.indent();
token = lexer.getNextToken();
output.endLine(false);
braceCount++;
}
else if (token == Token.RIGHT_BRACE)
{
token = lexer.getNextToken();
indentAtSemicolon = true;
braceCount--;
}
else if (token == Token.SEMICOLON)
{
token = lexer.getNextToken();
if (braceCount > 0)
output.endLine(false);
if (indentAtSemicolon)
{
output.indent();
indentAtSemicolon = false;
}
}
else if (token == Token.ASSIGNMENT_OPERATOR)
expression(Token.SEMICOLON);
else
token = lexer.getNextToken();
}
token = lexer.getNextToken();
output.endLine(false);
if (indentAtSemicolon)
output.indent();
}
// expression formats an expression. The delimiting token must
// be provided.
private void expression(Token terminator)
{
Token lastToken;
lastToken = Token.NOT_FOUND;
while (token != terminator)
{
lexer.checkExpressionSpacing(token, lastToken);
if (token == Token.LEFT_PARENTHESIS)
{
if (lastToken == Token.IDENTIFIER ||
lastToken == Token.UPPER_CASE_IDENTIFIER)
lexer.adjustSpacing(Lexer.SUPPRESS_LEADING_SPACE);
token = lexer.getNextToken();
expression(Token.RIGHT_PARENTHESIS);
}
lastToken = token;
token = lexer.getNextToken();
}
}
// Gets the next token and then verifies that the supplied token is
// the required token.
private void verifyNextToken(Token requiredToken)
{
token = lexer.getNextToken();
verifyCurrentToken(requiredToken);
}
// Verifies that the supplied token is the current token.
// Displays an error message if it is not.
private void verifyCurrentToken(Token requiredToken)
{
if (token != requiredToken)
output.outputError("MISSING " + requiredToken.name());
else
token = lexer.getNextToken();
}
}
OUTPUT CLASS
import java.io.*;
class Output
{
private static final int INDENT_INCREMENT = 4, LEFT_MARGIN = 0, LINES_PER_PAGE = 56,
HEADING_LENGTH = 70, CHARACTERS_PER_LINE = 78;
private PrintWriter file;
private int linesOnPage;
private int pageNumber;
private int indentation;
private String buffer = "";
private String heading;
// added this to avoid massive file on infinite loop
private final int MAX_OUTPUT_LINES = 1000;
private int outputLineCount = 0;
// The constructor initializes the private instance variables. It constructs
// a page heading containing the input file name.
public Output(String fileName) throws FileNotFoundException, IOException
{
file = new PrintWriter(new FileWriter(fileName + ".txt"));
linesOnPage = LINES_PER_PAGE;
pageNumber = 1;
indentation = LEFT_MARGIN;
heading = fileName;
for (int i = 0; i < HEADING_LENGTH - fileName.length(); i++)
heading += ' ';
}
// Closes output file
public void close()
{
file.close();
}
// outputToken outputs the token string adjusting spacing specified by the
// spacing word.
public void outputToken(String token, int spacing)
{
if (buffer.length() + token.length() > CHARACTERS_PER_LINE)
{
outputLine(buffer);
buffer = "";
}
if ((spacing & Lexer.SUPPRESS_LEADING_SPACE) != 0)
if (buffer.length() > 0 && buffer.charAt(buffer.length() - 1) == ' ')
buffer = buffer.substring(0, buffer.length() - 1);
buffer += token;
if ((spacing & Lexer.SUPPRESS_TRAILING_SPACE) == 0)
buffer += ' ';
}
// outputDirective prints out a compiler directive starting at the left
// margin.
public void outputDirective(String directive)
{
outputLine(directive);
}
// outputError prints out error messages.
public void outputError(String error)
{
file.println(error);
}
// indent increments the indentation variable.
public void indent()
{
indentation += INDENT_INCREMENT;
}
// unindent decrements the indentation variable.
public void unindent()
{
indentation -= INDENT_INCREMENT;
}
// endLine calls outputLine to write out a line. If the parameter
// forceNewPage is true then newPage is called.
public void endLine(boolean forceNewPage)
{
// added this check to avoid creating huge file on syntax error (infinite loop)
if( ++outputLineCount > MAX_OUTPUT_LINES )
throw new IllegalStateException("Output file exceeds maximum of " + MAX_OUTPUT_LINES);
if (forceNewPage && (linesOnPage > 0))
newPage();
if (buffer != "")
outputLine(buffer);
buffer = "";
}
// skipLine skips a line.
public void skipLine()
{
outputLine("");
}
// endPage sets linesOnPage to force a call to newPage.
public void endPage()
{
linesOnPage = LINES_PER_PAGE;
}
// newPage does a form feed and prints a new page heading.
public void newPage()
{
file.println("\f" + heading + "PAGE " + pageNumber++);
linesOnPage = 0;
}
// outputLine fills up margin number of spaces and prints a line
// from the buffer. It then increments lines per page.
public void outputLine(String line)
{
String buffer = "";
if (linesOnPage >= LINES_PER_PAGE)
newPage();
for (int space = 0; space < LEFT_MARGIN + indentation; space++)
buffer += ' ';
buffer += line;
file.println(buffer);
linesOnPage++;
}
}
CURRENT OUTPUT
PAGE 1
#include <stdio.h>
#include <stdlib.h>
PAGE 2
void main()
{
int value1 = 1, value2 = 81, value3 = 3, idx;
char c1 = 'a', c2 = 'b', c3 = 'c';
if (value2 == (int) c1)
idx = 1;
else
idx = 999;
for (idx = 0; idx < value3 * value3; idx++)
value2 = (int) c1 + idx;
idx = 1;
while (idx <= value3)
value2 *= value2;
do
value3--;
while (value3 > 0)
;
}

New Topic/Question
Reply




MultiQuote



|