Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

C Program Formatter written in Java

Posted on 2013-11-17
1
Medium Priority
?
379 Views
Last Modified: 2013-11-18
I am working on a project to implement a Java program that adjusts the formatting of a C program.  A few weeks ago we implemented the lexical analyzer to do this and were given a formatter class to work with.  For this stage of the project we are now required to implement the if, for, while, and do loops in this formatter class.  I feel like I have the correct abstract idea of how to do this, however am having trouble translating this into the code required.  I am currently focusing on the IF statements, once I have completed the IF statements I will have a better understanding of completing the other statements.

The tokens that I have implemented are:
enum Token {NOT_FOUND, UPPER_CASE_IDENTIFIER, CONSTANT, COMMENT,
     COMPILER_DIRECTIVE, ASSIGNMENT_OPERATOR,
     PRE_OR_POST_UNARY_OPERATOR, STRUCTURE_OPERATOR,
     UNARY_OR_BINARY_OPERATOR,UNARY_OPERATOR, BINARY_OPERATOR,
     TERNARY_OPERATOR, COLON, LEFT_PARENTHESIS, RIGHT_PARENTHESIS,
     LEFT_BRACKET, RIGHT_BRACKET, LEFT_BRACE, RIGHT_BRACE, SEMICOLON,
     COMMA, STRING, SC_SPECIFIER, BREAK, CASE, TYPE_SPECIFIER,
     CONTINUE, DEFAULT, DO, ELSE, FOR, GOTO, IF, RETURN, SIZEOF,
     STATUS, STRUCT, SWITCH, UNION, WHILE, IDENTIFIER, FIRST, NONE,
     END_OF_FILE}

Open in new window


And the format class is as follows.  I have added nothing more than the function skeleton with comments inside trying to map out the ideas of what I am attempting to do.  As well as a few commented-out lines in the statement 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;
            // insert IF statement case
            /*case IF:
                ifStatement();
                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)
        {
            if (token == Token.CASE)
            {
                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();
            }
            else
            {
                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();
    }
    
    // if statement
    private void ifStatement()
    {
        // the next token should be a left parenthesis
        // followed by an expression
        // followed by a right parenthesis token
        // followed by a statement
        // possibly followed by an 'else' token
        // followed by a statement
    }
    
    // for statement
    private void forStatement()
    {
        // the next token should be a left parenthesis
        // followed by an expression
        // followed by a semicolon token
        // followed by an expression
        // followed by a semicolon token
        // followed by an expression
        // followed by a right parenthesis token
        // followed by a statement
    }
    
    // while statement
    private void whileStatement()
    {
        // next token is a left parenthesis
        // followed by an expression
        // followed by a right parenthesis token
        // followed by a statement
        
    }
    
    // do statement
    private void doStatement()
    {
        // next token is a statement
        // followed by a while token
        // followed by a left parenthesis token
        // followed by an expression
        // followed by a right parenthesis token
    }
    
    // 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();

    }
}

Open in new window


I am looking for help implementing the IF statement formatter.  Do I have the correct “steps” to allow the program to recognize an if statement?  I think I can get an idea of how to complete the first few steps by following the example of the switch statement class, however I am unsure after recognizing the initial logical expression where to begin making it read through the rest of the if statement.  Any help at all would be appreciated.
0
Comment
Question by:Autkast
1 Comment
 
LVL 28

Accepted Solution

by:
dpearson earned 1600 total points
ID: 39655593
Yes this structure looks correct:

    // if statement
    private void ifStatement()
    {
        // the next token should be a left parenthesis
        // followed by an expression
        // followed by a right parenthesis token
        // followed by a statement
        // possibly followed by an 'else' token
        // followed by a statement
    }

Open in new window


And the code itself will start off something like this I believe:

 
   private void ifStatement()
    {
       verifyNextToken(Token.LEFT_PARENTHESIS);
       expression(Token.RIGHT_PARENTHESIS);
       statement() ;
       ...
    }

Open in new window


I hope that helps get you started,

Doug
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

"Disruption" is the most feared word for C-level executives these days. They agonize over their industry being disturbed by another player - most likely by startups.
In this post we will learn different types of Android Layout and some basics of an Android App.
Viewers will learn about the different types of variables in Java and how to declare them. Decide the type of variable desired: Put the keyword corresponding to the type of variable in front of the variable name: Use the equal sign to assign a v…
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below. https://filedb.experts-exchange.com/incoming/2017/03_w12/1151775/Permutations.txt https://filedb.experts-exchange.com/incoming/201…
Suggested Courses

927 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question