3 Replies - 686 Views - Last Post: 30 October 2011 - 11:11 AM Rate Topic: -----

#1 dragstang86  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 26
  • Joined: 28-September 09

Small Output issue with my Java program that parses C++ programs

Posted 29 October 2011 - 04:18 PM

I am having one issue with my program that I can not figure out. It is within the doStatement() method. It places the semi colon following the while() in the do/while loop on the following line. When testing it with a standard while loop it formats the code correctly. All other methods work perfectly other than doStatement(). The current output is below the code. The doStatement() method is on line 229 of the Format Class. The problem with the output is line 23/24 of the output. I have been stuck on this last small issue for days! Please help! Thanks!

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)
        ;
    }



Is This A Good Question/Topic? 0
  • +

Replies To: Small Output issue with my Java program that parses C++ programs

#2 GregBrannon  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2198
  • View blog
  • Posts: 5,226
  • Joined: 10-September 10

Re: Small Output issue with my Java program that parses C++ programs

Posted 30 October 2011 - 02:36 AM

After a very superficial look at your code, it occurs to me that your while parser has to handle two cases: Case 1, when the while is a while statement only, and Case 2, when the while is part of a do/while statement.
Was This Post Helpful? 0
  • +
  • -

#3 dragstang86  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 26
  • Joined: 28-September 09

Re: Small Output issue with my Java program that parses C++ programs

Posted 30 October 2011 - 11:00 AM

Thanks. I know that is the issue but I am struggling to figure out a solution
Was This Post Helpful? 0
  • +
  • -

#4 GregBrannon  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2198
  • View blog
  • Posts: 5,226
  • Joined: 10-September 10

Re: Small Output issue with my Java program that parses C++ programs

Posted 30 October 2011 - 11:11 AM

Solutions cost extra. If you knew that was the problem, you should have said so.

Right now, the do parser is separate from the while parser. That's fine, but I would think you'd set a flag, for example do = true, to let the while parser know that it is part of a do/while loop rather than simply a while loop. Then when your while parser runs with do = true, the placement of the ';' will be adjusted appropriately.

The second option is to parse the while portion of the do/while loop as a part of the do parser, but I prefer the first option as less repetitive.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1