Subversion Repositories programming

Rev

Rev 232 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*******************************************************************************
 * File: jminus.y
 * 
 * Copyright (c) 2006, Ira W. Snyder (devel@irasnyder.com)
 * License: GNU General Public License v2
 *
 * This file contains a definition of the J-Minus language, and will
 * create a parser for the language when compiled using BYACC/J, which
 * is available from http://byaccj.sourceforge.net.
 ******************************************************************************/

%{
    import java.lang.*;
    import java.io.*;
    import java.util.StringTokenizer;
    import java.util.Vector;
%}

/* Token Declarations */
%token CLASS
%token ID
%token PUBLIC
%token PRIVATE
%token INT
%token FLOAT
%token VOID
%token IF
%token ELSE
%token WHILE
%token RETURN
%token ADDOP
%token MULOP
%token NUM
%token LPAREN
%token RPAREN
%token LBRACE
%token RBRACE
%token SEMI
%token ASSIGNOP

/* J-Minus Grammar */
%%

program : program_good
    | program_bad { badpath=true; };

program_good : modifier CLASS ID LBRACE method_declaration RBRACE
        { System.out.println ("program -> modifier class id { method_declaration }"); };

program_bad : modifier CLASS ID LBRACE method_declaration { v.add("Missing RBRACE in program"); }
    | modifier CLASS ID method_declaration RBRACE { v.add("Missing LBRACE in program"); }
    | modifier ID LBRACE method_declaration RBRACE { v.add("Missing CLASS in program"); }
    | modifier ID ID LBRACE method_declaration RBRACE { v.add("Mis-spelled? CLASS in program"); };

modifier : PUBLIC   { System.out.println ("modifier -> public"); }
    | PRIVATE       { System.out.println ("modifier -> private"); }
    | ID            { badpath=true; v.add("Mis-spelled? PUBLIC or PRIVATE modifier"); }
    |               { badpath=true; v.add("Missing PUBLIC or PRIVATE modifier"); };

method_declaration : method_declaration_good
    | method_declaration_bad { badpath=true; }
    
method_declaration_good : modifier type_specifier ID LPAREN param RPAREN
    LBRACE local_declaration stmt_sequence RBRACE
        { System.out.println ("method_declaration -> modifier type_specifier id (param) "
                             +"{ local_declaration stmt_sequence }"); };

method_declaration_bad : modifier type_specifier ID param RPAREN LBRACE local_declaration stmt_sequence RBRACE
        { v.add("Missing LPAREN in method_declaration"); }
    | modifier type_specifier ID LPAREN param LBRACE local_declaration stmt_sequence RBRACE
        { v.add("Missing RPAREN in method_declaration"); }
    | modifier type_specifier ID LPAREN param RPAREN local_declaration stmt_sequence RBRACE
        { v.add("Missing LBRACE in method_declaration"); }
    | modifier type_specifier ID LPAREN param RPAREN LBRACE local_declaration stmt_sequence
        { v.add("Missing RBRACE in method_declaration"); };

type_specifier : INT { System.out.println ("type_specifier -> int"); }
    | FLOAT { System.out.println ("type_specifier -> float"); }
    | VOID  { System.out.println ("type_specifier -> void"); }
    |       { badpath=true; v.add("Missing type_specifier"); }
    | ID    { badpath=true; v.add("Mis-spelled? type_specifier"); };

param : type_specifier ID { System.out.println ("param -> type_specifier id"); }
    | VOID  { System.out.println ("param -> void"); };

local_declaration : local_declaration_good
    | local_declaration_bad { badpath=true; }
    
local_declaration_good : type_specifier ID SEMI
            { System.out.println ("local_declaration -> id;"); }
    |       { System.out.println ("local_declaration -> epsilon"); };

local_declaration_bad : type_specifier ID { v.add("Missing SEMI in local_declaration"); };

stmt_sequence : stmt_sequence statement
                { System.out.println ("stmt_sequence -> stmt_sequence statement"); }
    | statement { System.out.println ("stmt_sequence -> statement"); };

statement : if_stmt { System.out.println ("statement -> if_stmt"); }
    | while_stmt    { System.out.println ("statement -> while_stmt"); }
    | assign_stmt   { System.out.println ("statement -> assign_stmt"); }
    | return_stmt   { System.out.println ("statement -> return_stmt"); }
    | expr_stmt     { System.out.println ("statement -> expr_stmt"); };

if_stmt : if_stmt_good
    | if_stmt_bad { badpath=true; };

if_stmt_good : IF LPAREN exp RPAREN statement ELSE statement
        { System.out.println ("if_stmt -> if (exp) statement else statement"); };

if_stmt_bad : IF exp RPAREN statement ELSE statement { v.add("Missing LPAREN in if_stmt"); }
    | IF LPAREN exp statment ELSE statement { v.add("Missing RPAREN in if_stmt"); }
    | IF LPAREN exp RPAREN statement { v.add("Missing ELSE part in if_stmt"); };

while_stmt : while_stmt_good
    | while_stmt_bad { badpath=true; };

while_stmt_good : WHILE LPAREN exp RPAREN statement
        { System.out.println ("while_stmt -> (exp) statement"); };

while_stmt_bad : WHILE exp RPAREN statement { v.add("Missing LPAREN in while_stmt"); }
    | WHILE LPAREN exp statement { v.add("Missing RPAREN in while_stmt"); };

assign_stmt : assign_stmt_good
    | assign_stmt_bad { badpath=true; };

assign_stmt_good : ID ASSIGNOP exp SEMI
        { System.out.println ("assign_stmt -> id = exp;"); };

assign_stmt_bad : ID ASSIGNOP exp { v.add("Missing SEMI in assign_stmt"); };

return_stmt : return_stmt_good
    | return_stmt_bad { badpath=true; };

return_stmt_good : RETURN exp SEMI   { System.out.println ("return_stmt -> return exp;"); }
    | RETURN SEMI               { System.out.println ("return_stmt -> return;"); };

return_stmt_bad : RETURN exp { v.add("Missing SEMI in return_stmt"); }
    | RETURN { v.add("Missing SEMI in return_stmt"); };

expr_stmt : expr_stmt_good
    | expr_stmt_bad { badpath=true; };

expr_stmt_good : exp SEMI            { System.out.println ("expr_stmt -> exp;"); };

expr_stmt_bad : exp { v.add("Missing SEMI in expr_stmt"); }

exp : exp ADDOP term            { System.out.println ("exp -> exp + term"); }
    | term                      { System.out.println ("exp -> term"); };

term : term MULOP factor        { System.out.println ("term -> term * factor"); }
    | factor                    { System.out.println ("term -> factor"); };

factor : LPAREN exp RPAREN      { System.out.println ("factor -> (exp)"); }
    | ADDOP factor              { System.out.println ("factor -> + factor"); }
    | NUM                       { System.out.println ("factor -> NUM"); }
    | ID                        { System.out.println ("factor -> ID"); }
    | exp RPAREN                { badpath=true; v.add("Missing LPAREN in factor"); }
    | LPAREN exp                { badpath=true; v.add("Missing RPAREN in factor"); };

%%

/**
 * Special Stuff
 */

static boolean badpath = false;
static Vector v = new Vector();

/**
 * END
 */

private Yylex lexer;

public void yyerror (String error)
{
    System.out.println ("Parse Error: " + error);
}

int yylex ()
{
    int lex_return = -1;

    try
    {
        lex_return = lexer.yylex();
    }
    catch (IOException e)
    {
        System.out.println ("IO Error: " + e);
    }

    return lex_return;
}

public Parser (Reader r)
{
    lexer = new Yylex (r, this);
}

public static void main (String[] args) throws Exception
{
    System.out.println ("Grammar Productions - Rightmost Derivation in Reverse Order");
    System.out.println ("===============================================================");
    
    try
    {
        Parser yyparser = new Parser (new FileReader (args[0]));
        yyparser.yyparse();
    }
    catch (Exception e)
    {
        badpath=true;
    }

    if (badpath)
    {
        int i;
        String s;
        
        System.out.println ("\n\nError Report:");
        System.out.println ("============================================");
        
        for (i=0; i<v.size(); i++)
        {
            s = (String)v.get(i);
            System.out.println (s);
        }
        
        System.out.println ("\nPARSING FAILED");
        
    }
    else
    {
        System.out.println ("\nPARSING SUCCESSFUL");
    }
}