0% found this document useful (0 votes)
51 views44 pages

Ornek Scanner Parser

This document contains code for a lexical analyzer (scanner) for a Java-like language. It defines tokens for keywords, operators, punctuation, and other language elements. It uses JLex to generate a Lexer class that implements the scanning logic through regular expressions and actions to return tokenized symbols.

Uploaded by

Safa Selim
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
51 views44 pages

Ornek Scanner Parser

This document contains code for a lexical analyzer (scanner) for a Java-like language. It defines tokens for keywords, operators, punctuation, and other language elements. It uses JLex to generate a Lexer class that implements the scanning logic through regular expressions and actions to return tokenized symbols.

Uploaded by

Safa Selim
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 44

Ornek Scanner ve Parser

//----------------------------------------------------
// The following code was generated by CUP v0.10g
// Mon Feb 15 15:20:24 CST 1999
//----------------------------------------------------

/** CUP generated class containing symbol constants. */


public class sym {
/* terminals */
static final int STATIC = 20;
static final int SEMI = 27;
static final int EOF = 0;
static final int NULL = 16;
static final int LBRACKET = 34;
static final int FINAL = 9;
static final int GT = 44;
static final int UNKNOWN = 56;
static final int EQUAL = 36;
static final int OR = 37;
static final int ELSE = 5;
static final int THIS = 23;
static final int PROTECTED = 17;
static final int CLASS = 4;
static final int STRING_literal = 55;
static final int GE = 45;
static final int error = 1;
static final int INTEGER_literal = 54;
static final int LT = 42;
static final int MINUS = 47;
static final int PUBLIC = 18;
static final int SYNCHRONIZED = 22;
static final int IMPORT_PATH = 53;
static final int TIMES = 48;
static final int COMMA = 28;
static final int TRUE = 24;
static final int LE = 43;
static final int EXTENDS = 6;
static final int EQEQ = 40;
static final int IN = 11;
static final int VOID = 25;
static final int LPAREN = 30;
static final int DOT = 29;
static final int RPAREN = 31;
static final int IF = 10;
static final int INTEGER = 13;
static final int ID = 52;
static final int NEW = 15;
static final int EXTERN = 7;
static final int WHILE = 26;
static final int ABSTRACT = 2;
static final int SUPER = 21;
static final int MOD = 50;
static final int DIV = 49;
static final int EXP = 51;
static final int PLUS = 46;
static final int AND = 38;
static final int LBRACE = 32;
static final int BOOLEAN = 3;
static final int RBRACE = 33;
static final int INSTANCEOF = 12;
static final int NE = 41;
static final int MAIN = 14;
static final int FALSE = 8;
static final int RETURN = 19;
static final int RBRACKET = 35;
static final int NOT = 39;
}
Scanner
/* juic.jlex */

/*
*
* JLex lexical specification file for JUIC ("Java at UIC" ) language.
* (Class solution)
*/
import java.io.*;
import java.lang.*;
import java_cup.runtime.*;
import sym;
%%
/***** directives to JLEX *****/
// name of generated class will be "Lexer"
%class Lexer

// name of function to call to get next token


%function nextToken

// return type for "nextToken" function


%type java_cup.runtime.Symbol

// turn on character counting (char count in yychar)


%char

// turn on line counting (line # in yyline)


%line
// generate standard token number upon EOF
%eofval{
{
if (this.comment_nesting > 0)
System.err.println("**Error: missing end of comment found at EOF!");

return allocateToken(sym.EOF, null);


}
%eofval}
/***** code that becomes part of generated lexer class *****/
%{

private int prev_EOL_yychar; // where did prev line end?


private int comment_nesting;

// call these whenever you encounter a newline character


private void newline()
{
prev_EOL_yychar = yychar; // keep track of where last line ended
}
private void newline(int correction) // when you've passed newline char
{
prev_EOL_yychar = yychar + correction;
}
// allocates a token object for us...
private java_cup.runtime.Symbol allocateToken(int number, Object value)
{
int line, column;
java_cup.runtime.Symbol s;

line = yyline + 1; // JLex starts at 0, so add one


column = yychar - prev_EOL_yychar; // compute column on *this* line
s = new java_cup.runtime.Symbol(number, line, column, value); // allocate token object

return s;
}
// called by main program to init Lexer
public void init( )
{
prev_EOL_yychar = 0;
comment_nesting = 0;
}

%}
/***** macros: equate a name with a RE *****/
anybutnl .
digit [0-9]
char [a-zA-Z]
id ([a-zA-Z][a-zA-Z0-9_]*)

/***** Here are the RE token definitions and associated semantic actions... *****/
/***** NOTE: at this point, all tokens longer than 1 char must be prefixed with ****/
/***** the state <YYINITIAL> so as not to conflict with the COMMENT state.***/
%state COMMENT

%%
<COMMENT>"/*" { this.comment_nesting++; }
<COMMENT>"*/" {
this.comment_nesting--;
if (this.comment_nesting == 0)
yybegin(YYINITIAL);
}
<COMMENT>. { /* ignore comment char */ }
<COMMENT>\n|\r {
/* ignore, but count newlines for proper token locating */
newline();
}
"/*" {
this.comment_nesting = 1;
yybegin(COMMENT);
}
<YYINITIAL>"//"[^\n\r]* { /* one-line Java comment -- ignore everything to EOL */ }

";" { return allocateToken(sym.SEMI, null); }


"," { return allocateToken(sym.COMMA, null); }
"." { return allocateToken(sym.DOT, null); }
"(" { return allocateToken(sym.LPAREN, null); }
")" { return allocateToken(sym.RPAREN, null); }
"{" { return allocateToken(sym.LBRACE, null); }
"}" { return allocateToken(sym.RBRACE, null); }
"[" { return allocateToken(sym.LBRACKET, null); }
"]" { return allocateToken(sym.RBRACKET, null); }
"=" { return allocateToken(sym.EQUAL, null); }
<YYINITIAL>"||" { return allocateToken(sym.OR, null); }
<YYINITIAL>"&&" { return allocateToken(sym.AND, null); }
<YYINITIAL>"!" { return allocateToken(sym.NOT, null); }
<YYINITIAL>"==" { return allocateToken(sym.EQEQ, null); }
<YYINITIAL>"!=" { return allocateToken(sym.NE, null); }
"<" { return allocateToken(sym.LT, null); }
<YYINITIAL>"<=" { return allocateToken(sym.LE, null); }
">" { return allocateToken(sym.GT, null); }
<YYINITIAL>">=" { return allocateToken(sym.GE, null); }
"+" { return allocateToken(sym.PLUS, null); }
"-" { return allocateToken(sym.MINUS, null); }
"*" { return allocateToken(sym.TIMES, null); }
"/" { return allocateToken(sym.DIV, null); }
"%" { return allocateToken(sym.MOD, null); }
"^" { return allocateToken(sym.EXP, null); }
<YYINITIAL>abstract { return allocateToken(sym.ABSTRACT, null); }
<YYINITIAL>boolean { return allocateToken(sym.BOOLEAN, null); }
<YYINITIAL>class { return allocateToken(sym.CLASS, null); }
<YYINITIAL>else { return allocateToken(sym.ELSE, null); }
<YYINITIAL>extends { return allocateToken(sym.EXTENDS, null); }
<YYINITIAL>extern { return allocateToken(sym.EXTERN, null); }
<YYINITIAL>false { return allocateToken(sym.FALSE, null); }
<YYINITIAL>final { return allocateToken(sym.FINAL, null); }
<YYINITIAL>if { return allocateToken(sym.IF, null); }
<YYINITIAL>in { return allocateToken(sym.IN, null); }
<YYINITIAL>instanceof { return allocateToken(sym.INSTANCEOF, null); }
<YYINITIAL>int { return allocateToken(sym.INTEGER, null); }
<YYINITIAL>main { return allocateToken(sym.MAIN, null); }
<YYINITIAL>new { return allocateToken(sym.NEW, null); }
<YYINITIAL>null { return allocateToken(sym.NULL, null); }
<YYINITIAL>protected { return allocateToken(sym.PROTECTED, null); }
<YYINITIAL>public { return allocateToken(sym.PUBLIC, null); }
<YYINITIAL>return { return allocateToken(sym.RETURN, null); }
<YYINITIAL>static { return allocateToken(sym.STATIC, null); }
<YYINITIAL>super { return allocateToken(sym.SUPER, null); }
<YYINITIAL>synchronized { return allocateToken(sym.SYNCHRONIZED, null); }
<YYINITIAL>this { return allocateToken(sym.THIS, null); }
<YYINITIAL>true { return allocateToken(sym.TRUE, null); }
<YYINITIAL>void { return allocateToken(sym.VOID, null); }
<YYINITIAL>while { return allocateToken(sym.WHILE, null); }
<YYINITIAL>import(" "|\t)+({id}".")*("*"|{id})
{ /* import path */
String value;

value = yytext(); // get a string copy of the token

/* strip off the leading "import ", return just the path... */
value = value.substring(6); // strip off "import"
value = value.replace('\t', ' '); // convert \t -> spaces for deletion
value = value.trim(); // trim spaces from front (and back)

return allocateToken(sym.IMPORT_PATH, value);


}
<YYINITIAL>0|([1-9][0-9]*)
{ /* integer literal */
String s;
Integer value;

s = yytext(); // get a string copy of the token


value = new Integer(s); // create an Integer object from it
return allocateToken(sym.INTEGER_literal, value); // generate token
}

<YYINITIAL>{id} { /* identifier */
String value;

value = yytext(); // get a string copy of the token


return allocateToken(sym.ID, value);
}
<YYINITIAL>\"([^\n\r\"]|\\\")*\"
{ /* string literal "..." (which cannot be broken across lines) */
String value;
int loc;

value = yytext(); // get a string copy of the token

/* strip off the leading and trailing "...*/


value = value.substring(1);
value = value.substring(0, value.length() - 1);

// replace escaped quotes with just quotes...


loc = 0;
while (loc > -1) { // look for embedded quote
loc = value.indexOf("\\\"", loc);
if (loc == 0) // found one at start of string...
value = value.substring(1);
else if (loc > 0) // found in the middle...
value = value.substring(0, loc) +
value.substring(loc+1);
}//while

return allocateToken(sym.STRING_literal, value);


}
"" { /* ignore whitespace */ }
\t { /* ignore whitespace */ }
\n|\r { /* ignore whitespace */
newline(); // but keep track of when lines end...
}

{anybutnl} { /* this must be last in the list of REs */


String value;

value = yytext(); // get a string copy of the token


return allocateToken(sym.UNKNOWN, value);
}
Parser kismi
/* juic.cup */
/*
* Name: Joe Hummel
* SS# (last 4 digits): professor
*
* EECS 473: Compiler Design
* U. of Illinois, Chicago
* Spring 1999
*
* Java CUP parser specification file for JUIC ("Java at UIC") language.
* (Class solution)
*/
import java.io.*;
import java.lang.*;
import java_cup.runtime.*;
import Juic;
import Lexer;
/*
* utility code to include along with the actions
*/
action code {:

:};

/*
* code to include in the generated Parser
*/
parser code {:

private Lexer lexer;

// custom constructor
public Parser(Lexer lexer)
{
this(); // apply default Parser constructor

this.lexer = lexer;
}
// override default syntax error reporting method
public void syntax_error(java_cup.runtime.Symbol token)
{
System.err.print("**Syntax error at line " + token.left
+ ", column " + token.right + ": ");
System.err.print("token #" + token.sym);
if (token.value != null)
System.err.print(" (value='" + token.value + "').");
System.err.println();
System.err.println();
System.err.println("Halting...");
}

public void unrecovered_syntax_error(java_cup.runtime.Symbol token)


{
Juic.syntax_error = true;
}

:};
/*
* connect generated parser with our Lexer
*/

init with {: lexer.init(); :};


scan with {: return lexer.nextToken(); :}

/*
* terminal symbols returned by Lexer...
*/

/* keywords */
terminal ABSTRACT, BOOLEAN, CLASS, ELSE, EXTENDS, EXTERN, FALSE, FINAL, IF, IN;
terminal INSTANCEOF, INTEGER, MAIN, NEW, NULL, PROTECTED, PUBLIC, RETURN, STATIC;
terminal SUPER, SYNCHRONIZED, THIS, TRUE, VOID, WHILE;

/* punctuation */
terminal SEMI, COMMA, DOT, LPAREN, RPAREN, LBRACE, RBRACE, LBRACKET, RBRACKET;
terminal EQUAL, OR, AND, NOT, EQEQ, NE, LT, LE, GT, GE, PLUS, MINUS, TIMES, DIV, MOD, EXP;

/* terminals with types: identifiers, literals, etc. */


terminal String ID;
terminal String IMPORT_PATH;
terminal Integer INTEGER_literal;
terminal String STRING_literal;
terminal String UNKNOWN;
/*
* non-terminals in the grammar...
*/

non terminal classfile, imports, import_stmt, class, externclasses, externclass;


non terminal extension, type, fields, field_list, field, id_list, constructor;
non terminal super_call, externconstructor, formals, formal_list, formal;
non terminal methods, method_list, method, mainargv, externmethods;
non terminal externmethods_list, externmethod, returntype, stmts;
non terminal stmt_list, statement, declaration, simplestatement;
non terminal ifthenstatement, ifthenelsestatement, statementnoshortif;
non terminal ifthenelsestatementnoshortif, whilestatement;
non terminal whilestatementnoshortif, expressionstatement, statementexpression;
non terminal returnstatement, returnexpression, assignment, expression;
non terminal binaryexpr, and_binexpr, eq_binexpr, rel_binexpr, add_binexpr;
non terminal mult_binexpr, exp_binexpr, unaryexpr, unaryexprnotminus, castexpression;
non terminal postfixexpression, primaryexpression, classinstancecreation;
non terminal methodinvocation, receiver, arguments, arg_list, literal;
/*
* grammar for Juic...
*/

start with classfile ;

classfile ::= imports class


| externclasses
;

imports ::= import_stmt imports


| /* empty */
;

import_stmt ::= IMPORT_PATH SEMI


;

class ::= PUBLIC CLASS ID extension LBRACE fields constructor methods RBRACE
| PUBLIC FINAL CLASS ID extension LBRACE fields constructor methods RBRACE
| PUBLIC ABSTRACT CLASS ID extension LBRACE fields constructor methods RBRACE
;

externclasses ::= externclass


| externclass externclasses
;
externclass ::= EXTERN PUBLIC CLASS ID extension IN STRING_literal LBRACE externconstructor externmethods RBRACE
| EXTERN PUBLIC FINAL CLASS ID extension IN STRING_literal LBRACE externconstructor externmethods RBRACE
| EXTERN PUBLIC ABSTRACT CLASS ID extension IN STRING_literal LBRACE externconstructor externmethods RBRACE
;

extension ::= EXTENDS ID


| /* empty */
;

type ::= ID
| BOOLEAN
| INTEGER
;

fields ::= field_list


| /* empty */
;

field_list ::= field


| field field_list
;

field ::= PROTECTED type id_list SEMI


;

id_list ::= ID
| ID COMMA id_list
;
constructor ::= PUBLIC ID LPAREN formals RPAREN LBRACE super_call stmts RBRACE
;

super_call ::= SUPER LPAREN arguments RPAREN SEMI


;

externconstructor ::= PUBLIC ID LPAREN formals RPAREN SEMI


;

formals ::= formal_list


| /* empty */
;

formal_list ::= formal


| formal COMMA formal_list
;

formal ::= type ID


;

methods ::= method_list


| /* empty */
;

method_list ::= method


| method method_list
;
method ::= PUBLIC returntype ID LPAREN formals RPAREN LBRACE stmts RBRACE
| PUBLIC FINAL returntype ID LPAREN formals RPAREN LBRACE stmts RBRACE
| PUBLIC SYNCHRONIZED returntype ID LPAREN formals RPAREN LBRACE stmts RBRACE
| PUBLIC STATIC VOID MAIN LPAREN mainargv RPAREN LBRACE stmts RBRACE
| PUBLIC ABSTRACT returntype ID LPAREN formals RPAREN SEMI
;

mainargv ::= ID ID LBRACKET RBRACKET


| ID LBRACKET RBRACKET ID
;

externmethods ::= externmethods_list


| /* empty */
;

externmethods_list ::= externmethod


| externmethod externmethods_list
;

externmethod ::= PUBLIC returntype ID LPAREN formals RPAREN SEMI


| PUBLIC FINAL returntype ID LPAREN formals RPAREN SEMI
| PUBLIC ABSTRACT returntype ID LPAREN formals RPAREN SEMI
| PUBLIC SYNCHRONIZED returntype ID LPAREN formals RPAREN SEMI
;

returntype ::= VOID


| type
;
stmts ::= stmt_list
| /* empty */
;
stmt_list ::= statement
| statement stmt_list
;

statement ::= simplestatement


| declaration
| ifthenstatement
| ifthenelsestatement
| whilestatement
;

declaration ::= type id_list SEMI


;

simplestatement ::= SEMI


| LBRACE stmts RBRACE
| expressionstatement
| returnstatement
;

ifthenstatement ::= IF LPAREN expression RPAREN statement


;
ifthenelsestatement ::= IF LPAREN expression RPAREN statementnoshortif ELSE statement
;
statementnoshortif ::= simplestatement
| ifthenelsestatementnoshortif
| whilestatementnoshortif
;

ifthenelsestatementnoshortif ::= IF LPAREN expression RPAREN statementnoshortif


ELSE statementnoshortif
;

whilestatement ::= WHILE LPAREN expression RPAREN statement


;

whilestatementnoshortif ::= WHILE LPAREN expression RPAREN statementnoshortif


;

expressionstatement ::= statementexpression SEMI


;

statementexpression ::= assignment


| methodinvocation
| classinstancecreation
;
returnstatement ::= RETURN returnexpression SEMI
;

returnexpression ::= expression


| /* empty */
;

assignment ::= ID EQUAL expression


;

expression ::= assignment


| binaryexpr
;

binaryexpr ::= binaryexpr OR and_binexpr


| and_binexpr
;

and_binexpr ::= and_binexpr AND eq_binexpr


| eq_binexpr
;

eq_binexpr ::= eq_binexpr EQEQ rel_binexpr


| eq_binexpr NE rel_binexpr
| rel_binexpr
;
rel_binexpr ::= rel_binexpr LT add_binexpr
| rel_binexpr LE add_binexpr
| rel_binexpr GT add_binexpr
| rel_binexpr GE add_binexpr
| rel_binexpr INSTANCEOF ID
| add_binexpr
;

add_binexpr ::= add_binexpr PLUS mult_binexpr


| add_binexpr MINUS mult_binexpr
| mult_binexpr
;

mult_binexpr ::= mult_binexpr TIMES exp_binexpr


| mult_binexpr DIV exp_binexpr
| mult_binexpr MOD exp_binexpr
| exp_binexpr
;

exp_binexpr ::= unaryexpr EXP exp_binexpr


| unaryexpr
;

unaryexpr ::= unaryexprnotminus


| MINUS unaryexpr
;
unaryexprnotminus ::= postfixexpression
| NOT unaryexpr
| castexpression
;

castexpression ::= LPAREN expression RPAREN unaryexprnotminus


| LPAREN INTEGER RPAREN unaryexprnotminus
| LPAREN BOOLEAN RPAREN unaryexprnotminus
;

postfixexpression ::= ID
| primaryexpression
;

primaryexpression ::= literal


| THIS
| LPAREN expression RPAREN
| classinstancecreation
| methodinvocation
;

classinstancecreation ::= NEW ID LPAREN arguments RPAREN


;
methodinvocation ::= receiver DOT ID LPAREN arguments RPAREN
;

receiver ::= ID
| primaryexpression
| SUPER
;

arguments ::= arg_list


| /* empty */
;

arg_list ::= expression


| expression COMMA arg_list
;

literal ::= INTEGER_literal


| TRUE
| FALSE
| STRING_literal
| NULL
;
Driver program
/* Juic.java */

/*
* Name: Joe Hummel
* SS# (last 4 digits): Professor
*
* EECS 473, Compiler Design
* U. of Illinois, Chicago
* Spring 1999
*
* Main program for JUIC ("Java at UIC") compiler.
*
* To run: java Juic file1.juic [file2.juic file3.juic ...]
*/
import java.io.*;
import java.lang.*;
import Lexer;
import Parser;

public class Juic {

// Note: use of "static" below enables access from other classes via the
// use of the class name, e.g. Juic.filename (this is necessary since
// other objects won't necessarily have a reference to the actual Juic
// object created at startup).

public static String filename; // .juic file being compiled


public static InputStream in; // ref to current input file
public static PrintStream out; // ref to current output file
public static boolean syntax_error; // "true" if syntax error occured
// main program
public static void main(String argv[])
{
int i;
Lexer lexer;
Parser parser;

/*
* Make sure user supplied at least one file to compile
*/

if (argv.length == 0) {
System.err.println("**Error: usage is 'java Juic file1.juic [file2.juic ...]'.");
System.err.println();
System.err.println("Halting...");
return;
}//then
/*
* For each file, parse...
*/

syntax_error = false;

for (i = 0; i < argv.length; i++) {

/***** open input file *****/


filename = argv[i];
in = openInputFile(filename);
if (in == null) return;

/***** parse file... *****/


System.out.println("Parsing " + filename + "...");

lexer = new Lexer(in);


parser = new Parser(lexer);
try {
parser.parse();
}
catch (Exception e) {
System.err.println("**Parser error: " + e.getMessage());
syntax_error = true; // force .html file to be emptied
}//try-catch

/***** stop on first syntax error *****/


if (syntax_error)
break;

/***** else close input file and repeat... *****/


try {
in.close();
}
catch (IOException e) { /* ignore */ }

}//for
/*
* Done parsing --- if a syntax error occurred, exit now...
*/

if (syntax_error) {
try {
in.close(); // close that last file...
}
catch (IOException e) { /* ignore */ }

return;
}//then

/*
* That's it, we're done!
*/

System.out.println();
System.out.println("done.");
}
public static InputStream openInputFile(String filename)
{
InputStream in;

try { // try to open input file so we can input data...


in = new FileInputStream(filename);
}
catch (FileNotFoundException e) {
System.err.println("**Error: unable to open input file '" + filename + "'.");
System.err.println();
System.err.println("Halting...");
in = null;
}//try-catch

return in;
}
public static PrintStream openOutputFile(String filename)
{
PrintStream out;
int loc;
String outname;

try { // try to open output file as well...


loc = filename.lastIndexOf(".juic");
outname = filename.substring(0, loc);
outname = outname.concat(".jasm");
out = new PrintStream(new FileOutputStream(outname));
}
catch (FileNotFoundException e) {
System.err.println("**Error: unable to open output file '" + filename + "'.");
System.err.println();
System.err.println("Halting...");
out = null;
}//try-catch
catch (SecurityException e) {
System.err.println("**Error: no permission to write output file '" + filename + "'.");
System.err.println();
System.err.println("Halting...");
out = null;
}//try-catch
catch (IOException e) {
System.err.println("**Error: unknown error opening output file '" + filename + "'.");
System.err.println();
System.err.println("Halting...");
out = null;
}//try-catch

return out;
}

You might also like