Rev 231 | Go to most recent revision | 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
{
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");
}
}