Recursive Descent Parsing
Implemented tokenizer/scanner and recursive descent parser.master
commit
983f4cd852
|
@ -0,0 +1,215 @@
|
||||||
|
#################
|
||||||
|
## Eclipse
|
||||||
|
#################
|
||||||
|
|
||||||
|
*.pydevproject
|
||||||
|
.project
|
||||||
|
.metadata
|
||||||
|
bin/
|
||||||
|
tmp/
|
||||||
|
*.tmp
|
||||||
|
*.bak
|
||||||
|
*.swp
|
||||||
|
*~.nib
|
||||||
|
local.properties
|
||||||
|
.classpath
|
||||||
|
.settings/
|
||||||
|
.loadpath
|
||||||
|
|
||||||
|
# External tool builders
|
||||||
|
.externalToolBuilders/
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
|
||||||
|
# CDT-specific
|
||||||
|
.cproject
|
||||||
|
|
||||||
|
# PDT-specific
|
||||||
|
.buildpath
|
||||||
|
|
||||||
|
|
||||||
|
#################
|
||||||
|
## Visual Studio
|
||||||
|
#################
|
||||||
|
|
||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
x64/
|
||||||
|
build/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.log
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
*.ncrunch*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.Publish.xml
|
||||||
|
*.pubxml
|
||||||
|
|
||||||
|
# NuGet Packages Directory
|
||||||
|
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
|
||||||
|
#packages/
|
||||||
|
|
||||||
|
# Windows Azure Build Output
|
||||||
|
csx
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Windows Store app package directory
|
||||||
|
AppPackages/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
sql/
|
||||||
|
*.Cache
|
||||||
|
ClientBin/
|
||||||
|
[Ss]tyle[Cc]op.*
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file to a newer
|
||||||
|
# Visual Studio version. Backup files are not needed, because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
App_Data/*.mdf
|
||||||
|
App_Data/*.ldf
|
||||||
|
|
||||||
|
#############
|
||||||
|
## Windows detritus
|
||||||
|
#############
|
||||||
|
|
||||||
|
# Windows image file caches
|
||||||
|
Thumbs.db
|
||||||
|
ehthumbs.db
|
||||||
|
|
||||||
|
# Folder config file
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Recycle Bin used on file shares
|
||||||
|
$RECYCLE.BIN/
|
||||||
|
|
||||||
|
# Mac crap
|
||||||
|
.DS_Store
|
||||||
|
|
||||||
|
|
||||||
|
#############
|
||||||
|
## Python
|
||||||
|
#############
|
||||||
|
|
||||||
|
*.py[co]
|
||||||
|
|
||||||
|
# Packages
|
||||||
|
*.egg
|
||||||
|
*.egg-info
|
||||||
|
dist/
|
||||||
|
build/
|
||||||
|
eggs/
|
||||||
|
parts/
|
||||||
|
var/
|
||||||
|
sdist/
|
||||||
|
develop-eggs/
|
||||||
|
.installed.cfg
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
.coverage
|
||||||
|
.tox
|
||||||
|
|
||||||
|
#Translations
|
||||||
|
*.mo
|
||||||
|
|
||||||
|
#Mr Developer
|
||||||
|
.mr.developer.cfg
|
Binary file not shown.
|
@ -0,0 +1,35 @@
|
||||||
|
package miniJava;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import miniJava.SyntacticAnalyzer.*;
|
||||||
|
|
||||||
|
public class Compiler {
|
||||||
|
|
||||||
|
private static final int rc = 4;
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
|
||||||
|
if(args.length == 0) {
|
||||||
|
System.out.println("No file specified");
|
||||||
|
System.exit(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
try(FileReader input = new FileReader(args[0])) {
|
||||||
|
|
||||||
|
Scanner scanner = new Scanner(new BufferedReader(input));
|
||||||
|
Parser parser = new Parser(scanner);
|
||||||
|
parser.parse();
|
||||||
|
|
||||||
|
System.out.println("Works");
|
||||||
|
System.exit(0);
|
||||||
|
|
||||||
|
} catch(FileNotFoundException e) {
|
||||||
|
System.out.println("Not Found");
|
||||||
|
System.exit(rc);
|
||||||
|
} catch(IOException e) {
|
||||||
|
System.out.println("Not Works");
|
||||||
|
System.exit(rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,409 @@
|
||||||
|
package miniJava.SyntacticAnalyzer;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
public class Parser {
|
||||||
|
|
||||||
|
private Scanner scanner;
|
||||||
|
private LinkedList<Token> stream;
|
||||||
|
|
||||||
|
public Parser(Scanner scanner) {
|
||||||
|
this.scanner = scanner;
|
||||||
|
this.stream = new LinkedList<Token>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Program ::= (ClassDeclaration)* eot
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public void parse() throws IOException {
|
||||||
|
while(peek(1).type == Token.TYPE.CLASS) parseClassDeclaration();
|
||||||
|
accept(Token.TYPE.EOT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ClassDeclaration ::=
|
||||||
|
* class id {
|
||||||
|
* (Declarators id (; | MethodDeclaration))*
|
||||||
|
* }
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseClassDeclaration() throws IOException {
|
||||||
|
|
||||||
|
// Class Header
|
||||||
|
accept(Token.TYPE.CLASS);
|
||||||
|
accept(Token.TYPE.ID);
|
||||||
|
accept(Token.TYPE.LBRACKET);
|
||||||
|
|
||||||
|
// Class Body
|
||||||
|
while(peek(1).type != Token.TYPE.RBRACKET) {
|
||||||
|
parseDeclarators();
|
||||||
|
accept(Token.TYPE.ID);
|
||||||
|
if(peek(1).type == Token.TYPE.SEMICOLON) accept(Token.TYPE.SEMICOLON);
|
||||||
|
else parseMethodDeclaration();
|
||||||
|
}
|
||||||
|
|
||||||
|
accept(Token.TYPE.RBRACKET);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MethodDeclaration ::=
|
||||||
|
* (ParameterList?) {
|
||||||
|
* Statement* (return Expression ;)?
|
||||||
|
* }
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseMethodDeclaration() throws IOException {
|
||||||
|
|
||||||
|
// Method Header
|
||||||
|
accept(Token.TYPE.LPAREN);
|
||||||
|
if(peek(1).type != Token.TYPE.RPAREN) parseParameterList();
|
||||||
|
accept(Token.TYPE.RPAREN);
|
||||||
|
accept(Token.TYPE.LBRACKET);
|
||||||
|
|
||||||
|
// Method Body
|
||||||
|
while(peek(1).type != Token.TYPE.RBRACKET) {
|
||||||
|
|
||||||
|
if(peek(1).type == Token.TYPE.RETURN) {
|
||||||
|
accept(Token.TYPE.RETURN);
|
||||||
|
parseExpression();
|
||||||
|
accept(Token.TYPE.SEMICOLON);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
parseStatement();
|
||||||
|
}
|
||||||
|
|
||||||
|
accept(Token.TYPE.RBRACKET);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Declarators ::= (public | private)? static? Type
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseDeclarators() throws IOException {
|
||||||
|
|
||||||
|
if(peek(1).type == Token.TYPE.PUBLIC) accept(Token.TYPE.PUBLIC);
|
||||||
|
else if(peek(1).type == Token.TYPE.PRIVATE) accept(Token.TYPE.PRIVATE);
|
||||||
|
|
||||||
|
if(peek(1).type == Token.TYPE.STATIC) accept(Token.TYPE.STATIC);
|
||||||
|
parseType();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type ::= boolean | void | int ([])? | id ([])?
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseType() throws IOException {
|
||||||
|
|
||||||
|
Token.TYPE type = peek(1).type;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
|
||||||
|
case BOOLEAN:
|
||||||
|
case VOID:
|
||||||
|
accept(type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INT:
|
||||||
|
case ID:
|
||||||
|
accept(type);
|
||||||
|
if(peek(1).type == Token.TYPE.LSQUARE) {
|
||||||
|
accept(Token.TYPE.LSQUARE);
|
||||||
|
accept(Token.TYPE.RSQUARE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IOException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ParameterList ::= Type id (, Type id)*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseParameterList() throws IOException {
|
||||||
|
parseType();
|
||||||
|
accept(Token.TYPE.ID);
|
||||||
|
while(peek(1).type == Token.TYPE.COMMA) {
|
||||||
|
accept(Token.TYPE.COMMA);
|
||||||
|
parseType();
|
||||||
|
accept(Token.TYPE.ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ArgumentList ::= Expression (, Expression)*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseArgumentList() throws IOException {
|
||||||
|
parseExpression();
|
||||||
|
while(peek(1).type == Token.TYPE.COMMA) {
|
||||||
|
accept(Token.TYPE.COMMA);
|
||||||
|
parseExpression();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference ::= BaseRef (. BaseRef)*
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseReference() throws IOException {
|
||||||
|
parseBaseRef();
|
||||||
|
while(peek(1).type == Token.TYPE.PERIOD) {
|
||||||
|
accept(Token.TYPE.PERIOD);
|
||||||
|
accept(Token.TYPE.ID);
|
||||||
|
if(peek(1).type == Token.TYPE.LSQUARE) {
|
||||||
|
accept(Token.TYPE.LSQUARE);
|
||||||
|
parseExpression();
|
||||||
|
accept(Token.TYPE.RSQUARE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BaseRef ::= this | id ([ Expression])?
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseBaseRef() throws IOException {
|
||||||
|
|
||||||
|
switch(peek(1).type) {
|
||||||
|
|
||||||
|
// this
|
||||||
|
case THIS:
|
||||||
|
accept(Token.TYPE.THIS);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// id ([ Expression])?
|
||||||
|
default:
|
||||||
|
accept(Token.TYPE.ID);
|
||||||
|
if(peek(1).type == Token.TYPE.LSQUARE) {
|
||||||
|
accept(Token.TYPE.LSQUARE);
|
||||||
|
parseExpression();
|
||||||
|
accept(Token.TYPE.RSQUARE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Statement ::=
|
||||||
|
* {Statement*}
|
||||||
|
* | Type id = Expression;
|
||||||
|
* | Reference = Expression;
|
||||||
|
* | Reference ( ArgumentList? );
|
||||||
|
* | if (Expression) Statement (else Statement)?
|
||||||
|
* | while (Expression) Statement
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseStatement() throws IOException {
|
||||||
|
|
||||||
|
switch(peek(1).type) {
|
||||||
|
|
||||||
|
// { Statement* }
|
||||||
|
case LBRACKET:
|
||||||
|
accept(Token.TYPE.LBRACKET);
|
||||||
|
while(peek(1).type != Token.TYPE.RBRACKET) {
|
||||||
|
parseStatement();
|
||||||
|
}
|
||||||
|
accept(Token.TYPE.RBRACKET);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// if (Expression) Statement (else Statement)?
|
||||||
|
case IF:
|
||||||
|
accept(Token.TYPE.IF);
|
||||||
|
accept(Token.TYPE.LPAREN);
|
||||||
|
parseExpression();
|
||||||
|
accept(Token.TYPE.RPAREN);
|
||||||
|
parseStatement();
|
||||||
|
if(peek(1).type == Token.TYPE.ELSE) {
|
||||||
|
accept(Token.TYPE.ELSE);
|
||||||
|
parseStatement();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// while (Expression) Statement
|
||||||
|
case WHILE:
|
||||||
|
accept(Token.TYPE.WHILE);
|
||||||
|
accept(Token.TYPE.LPAREN);
|
||||||
|
parseExpression();
|
||||||
|
accept(Token.TYPE.RPAREN);
|
||||||
|
parseStatement();
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Type id = Expression ;
|
||||||
|
case BOOLEAN:
|
||||||
|
case VOID:
|
||||||
|
case INT:
|
||||||
|
case ID:
|
||||||
|
|
||||||
|
// Must be a type though there is a possibility of a reference
|
||||||
|
if(peek(1).type != Token.TYPE.ID
|
||||||
|
|| peek(2).type == Token.TYPE.ID
|
||||||
|
||(peek(2).type == Token.TYPE.LSQUARE && peek(3).type == Token.TYPE.RSQUARE)) {
|
||||||
|
parseType();
|
||||||
|
accept(Token.TYPE.ID);
|
||||||
|
accept(Token.TYPE.EQUALS);
|
||||||
|
parseExpression();
|
||||||
|
accept(Token.TYPE.SEMICOLON);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fall Through */
|
||||||
|
|
||||||
|
// Reference = Expression ; | Reference ( ArgumentList? ) ;
|
||||||
|
default:
|
||||||
|
parseReference();
|
||||||
|
|
||||||
|
if(peek(1).type == Token.TYPE.LPAREN) {
|
||||||
|
accept(Token.TYPE.LPAREN);
|
||||||
|
if(peek(1).type != Token.TYPE.RPAREN) parseArgumentList();
|
||||||
|
accept(Token.TYPE.RPAREN);
|
||||||
|
} else {
|
||||||
|
accept(Token.TYPE.EQUALS);
|
||||||
|
parseExpression();
|
||||||
|
}
|
||||||
|
|
||||||
|
accept(Token.TYPE.SEMICOLON);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expression ::=
|
||||||
|
* Reference
|
||||||
|
* | Reference ( ArgumentList? )
|
||||||
|
* | unop Expression
|
||||||
|
* | Expression binop Expression
|
||||||
|
* | ( Expression )
|
||||||
|
* | num | true | false
|
||||||
|
* | new (id() | int [ Expression ] | id [ Expression ] )
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void parseExpression() throws IOException {
|
||||||
|
|
||||||
|
switch(peek(1).type) {
|
||||||
|
|
||||||
|
// num | true | false
|
||||||
|
case NUM:
|
||||||
|
case TRUE:
|
||||||
|
case FALSE:
|
||||||
|
accept(peek(1).type);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ( Expression )
|
||||||
|
case LPAREN:
|
||||||
|
accept(Token.TYPE.LPAREN);
|
||||||
|
parseExpression();
|
||||||
|
accept(Token.TYPE.RPAREN);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// unop Expression
|
||||||
|
case UNOP:
|
||||||
|
accept(Token.TYPE.UNOP);
|
||||||
|
parseExpression();
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Must be a minus sign
|
||||||
|
case BINOP:
|
||||||
|
if(peek(1).attr.equals("-")) {
|
||||||
|
accept(Token.TYPE.BINOP);
|
||||||
|
parseExpression();
|
||||||
|
}
|
||||||
|
else throw new IOException();
|
||||||
|
break;
|
||||||
|
|
||||||
|
// new ( int [ Expression ] | id ( ) | id [ Expression ] )
|
||||||
|
case NEW:
|
||||||
|
accept(Token.TYPE.NEW);
|
||||||
|
|
||||||
|
if(peek(1).type == Token.TYPE.INT) {
|
||||||
|
accept(Token.TYPE.INT);
|
||||||
|
accept(Token.TYPE.LSQUARE);
|
||||||
|
parseExpression();
|
||||||
|
accept(Token.TYPE.RSQUARE);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
accept(Token.TYPE.ID);
|
||||||
|
|
||||||
|
if(peek(1).type == Token.TYPE.LPAREN){
|
||||||
|
accept(Token.TYPE.LPAREN);
|
||||||
|
accept(Token.TYPE.RPAREN);
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
accept(Token.TYPE.LSQUARE);
|
||||||
|
parseExpression();
|
||||||
|
accept(Token.TYPE.RSQUARE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Reference | Reference (ArgumentList?)
|
||||||
|
case THIS:
|
||||||
|
case ID:
|
||||||
|
parseReference();
|
||||||
|
if(peek(1).type == Token.TYPE.LPAREN) {
|
||||||
|
accept(Token.TYPE.LPAREN);
|
||||||
|
if(peek(1).type != Token.TYPE.RPAREN) parseArgumentList();
|
||||||
|
accept(Token.TYPE.RPAREN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Expression binop Expression
|
||||||
|
default:
|
||||||
|
accept(Token.TYPE.BINOP);
|
||||||
|
parseExpression();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Expression binop Expression
|
||||||
|
if(peek(1).type == Token.TYPE.BINOP) {
|
||||||
|
accept(Token.TYPE.BINOP);
|
||||||
|
parseExpression();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sees what the next token is, caching the result.
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private Token peek(int lookahead) throws IOException {
|
||||||
|
|
||||||
|
// Cache tokens
|
||||||
|
while(stream.size() < lookahead) {
|
||||||
|
Token next = scanner.scan();
|
||||||
|
stream.addLast(next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stream.get(lookahead - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumes token or throws exception.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void accept(Token.TYPE type) throws IOException {
|
||||||
|
Token next = peek(1);
|
||||||
|
if(next.type == type) stream.poll();
|
||||||
|
else throw new IOException();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,249 @@
|
||||||
|
package miniJava.SyntacticAnalyzer;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class Scanner {
|
||||||
|
|
||||||
|
private BufferedReader input;
|
||||||
|
|
||||||
|
public Scanner(BufferedReader input) {
|
||||||
|
this.input = input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scans in input, returning next token.
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
public Token scan() throws IOException {
|
||||||
|
|
||||||
|
String attr = "";
|
||||||
|
Token token = null;
|
||||||
|
|
||||||
|
while(token == null) {
|
||||||
|
|
||||||
|
// Check for EOF
|
||||||
|
int c = input.read();
|
||||||
|
if(c == -1) return new Token("", Token.TYPE.EOT);
|
||||||
|
|
||||||
|
// Setup
|
||||||
|
attr += (char) c;
|
||||||
|
|
||||||
|
switch(c) {
|
||||||
|
|
||||||
|
// Operators
|
||||||
|
case '+':
|
||||||
|
case '*':
|
||||||
|
case '-':
|
||||||
|
token = new Token(attr, Token.TYPE.BINOP);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Check for comment
|
||||||
|
case '/':
|
||||||
|
if(peek('*')) { input.read(); readComment(); attr = ""; }
|
||||||
|
else if(peek('/')) { readLine(); attr = ""; }
|
||||||
|
else token = new Token(attr, Token.TYPE.BINOP);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Check for c or c=
|
||||||
|
case '>':
|
||||||
|
case '<':
|
||||||
|
if(peek('=')) attr += (char) input.read();
|
||||||
|
token = new Token(attr, Token.TYPE.BINOP);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Check for ! or !=
|
||||||
|
case '!':
|
||||||
|
if(!peek('=')) token = new Token(attr, Token.TYPE.UNOP);
|
||||||
|
else {
|
||||||
|
attr += (char) input.read();
|
||||||
|
token = new Token(attr, Token.TYPE.BINOP);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Check for && or ||
|
||||||
|
case '&':
|
||||||
|
case '|':
|
||||||
|
if(!peek((char) c)) throw new IOException();
|
||||||
|
else {
|
||||||
|
attr += (char) input.read();
|
||||||
|
token = new Token(attr, Token.TYPE.BINOP);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Other Operators
|
||||||
|
case '=':
|
||||||
|
if(!peek('=')) token = new Token(attr, Token.TYPE.EQUALS);
|
||||||
|
else {
|
||||||
|
attr += (char) input.read();
|
||||||
|
token = new Token(attr, Token.TYPE.BINOP);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '.':
|
||||||
|
token = new Token(attr, Token.TYPE.PERIOD);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ',':
|
||||||
|
token = new Token(attr, Token.TYPE.COMMA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '[':
|
||||||
|
token = new Token(attr, Token.TYPE.LSQUARE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ']':
|
||||||
|
token = new Token(attr, Token.TYPE.RSQUARE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '{':
|
||||||
|
token = new Token(attr, Token.TYPE.LBRACKET);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '}':
|
||||||
|
token = new Token(attr, Token.TYPE.RBRACKET);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '(':
|
||||||
|
token = new Token(attr, Token.TYPE.LPAREN);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ')':
|
||||||
|
token = new Token(attr, Token.TYPE.RPAREN);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ';':
|
||||||
|
token = new Token(attr, Token.TYPE.SEMICOLON);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
|
||||||
|
// Identifier or Keyword
|
||||||
|
if(isAlpha((char) c)) {
|
||||||
|
for(char n = peek(); isAlpha(n) || isDigit(n) || n == '_';) {
|
||||||
|
attr += (char) input.read();
|
||||||
|
n = peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Token.keywords.containsKey(attr)) {
|
||||||
|
token = new Token(attr, Token.keywords.get(attr));
|
||||||
|
} else {
|
||||||
|
token = new Token(attr, Token.TYPE.ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number
|
||||||
|
else if(isDigit((char) c)) {
|
||||||
|
for(char n = peek(); isDigit(n);) {
|
||||||
|
attr += (char) input.read();
|
||||||
|
n = peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
token = new Token(attr, Token.TYPE.NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whitespace
|
||||||
|
else if(isWhitespace((char) c)) {
|
||||||
|
attr = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unrecognized Character
|
||||||
|
else throw new IOException();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(token.type);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Looks at next character in stream without consuming.
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private char peek() throws IOException {
|
||||||
|
input.mark(1);
|
||||||
|
int next = input.read();
|
||||||
|
input.reset();
|
||||||
|
|
||||||
|
return next == -1 ? '\0' : (char) next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether passed character is next in stream.
|
||||||
|
* @param c
|
||||||
|
* @return
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private boolean peek(char c) throws IOException {
|
||||||
|
input.mark(1);
|
||||||
|
int next = input.read();
|
||||||
|
input.reset();
|
||||||
|
|
||||||
|
return c == next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumes input until an end of comment has been reached.
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void readComment() throws IOException {
|
||||||
|
char prev = '\0', current = '\0';
|
||||||
|
while(prev != '*' || current != '/') {
|
||||||
|
|
||||||
|
prev = current;
|
||||||
|
|
||||||
|
int next = input.read();
|
||||||
|
if(next == -1) throw new IOException();
|
||||||
|
else current = (char) next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Consumes input until the end of line is reached
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
private void readLine() throws IOException {
|
||||||
|
for(int n = 0; n != '\n' && n != '\r' && n != -1; n = input.read()) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells whether character is alphabetical.
|
||||||
|
* @param c
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isAlpha(char c) {
|
||||||
|
return (c >= 'a' && c <= 'z')
|
||||||
|
|| (c >= 'A' && c <= 'Z');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells whether character is numerical.
|
||||||
|
* @param c
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isDigit(char c) {
|
||||||
|
return c >= '0' && c <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells wheter character is whitespace.
|
||||||
|
* @param c
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private boolean isWhitespace(char c) {
|
||||||
|
return c == ' '
|
||||||
|
|| c == '\n'
|
||||||
|
|| c == '\r'
|
||||||
|
|| c == '\t';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package miniJava.SyntacticAnalyzer;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
public class Token {
|
||||||
|
|
||||||
|
public enum TYPE {
|
||||||
|
|
||||||
|
// Possible Terminals
|
||||||
|
ID,
|
||||||
|
NUM,
|
||||||
|
UNOP,
|
||||||
|
BINOP,
|
||||||
|
|
||||||
|
// Keywords
|
||||||
|
IF,
|
||||||
|
ELSE,
|
||||||
|
NEW,
|
||||||
|
INT,
|
||||||
|
VOID,
|
||||||
|
THIS,
|
||||||
|
TRUE,
|
||||||
|
FALSE,
|
||||||
|
CLASS,
|
||||||
|
WHILE,
|
||||||
|
RETURN,
|
||||||
|
BOOLEAN,
|
||||||
|
|
||||||
|
// Declarators
|
||||||
|
STATIC,
|
||||||
|
PUBLIC,
|
||||||
|
PRIVATE,
|
||||||
|
|
||||||
|
// Other Terminals
|
||||||
|
EQUALS,
|
||||||
|
PERIOD,
|
||||||
|
COMMA,
|
||||||
|
LPAREN,
|
||||||
|
RPAREN,
|
||||||
|
LSQUARE,
|
||||||
|
RSQUARE,
|
||||||
|
LBRACKET,
|
||||||
|
RBRACKET,
|
||||||
|
SEMICOLON,
|
||||||
|
|
||||||
|
// End of Token Stream
|
||||||
|
EOT
|
||||||
|
};
|
||||||
|
|
||||||
|
public final static HashMap<String, TYPE> keywords;
|
||||||
|
static
|
||||||
|
{
|
||||||
|
keywords = new HashMap<String, TYPE>();
|
||||||
|
keywords.put("class", TYPE.CLASS);
|
||||||
|
keywords.put("return", TYPE.RETURN);
|
||||||
|
keywords.put("public", TYPE.PUBLIC);
|
||||||
|
keywords.put("private", TYPE.PRIVATE);
|
||||||
|
keywords.put("static", TYPE.STATIC);
|
||||||
|
keywords.put("int", TYPE.INT);
|
||||||
|
keywords.put("boolean", TYPE.BOOLEAN);
|
||||||
|
keywords.put("void", TYPE.VOID);
|
||||||
|
keywords.put("this", TYPE.THIS);
|
||||||
|
keywords.put("if", TYPE.IF);
|
||||||
|
keywords.put("else", TYPE.ELSE);
|
||||||
|
keywords.put("while", TYPE.WHILE);
|
||||||
|
keywords.put("true", TYPE.TRUE);
|
||||||
|
keywords.put("false", TYPE.FALSE);
|
||||||
|
keywords.put("new", TYPE.NEW);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final TYPE type;
|
||||||
|
public final String attr;
|
||||||
|
|
||||||
|
public Token(String attr, TYPE type) {
|
||||||
|
this.type = type;
|
||||||
|
this.attr = attr;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
Program ::= (ClassDeclaration)* eot
|
||||||
|
|
||||||
|
ClassDeclaration ::=
|
||||||
|
class id {
|
||||||
|
(Declarators id (; | MethodDeclaration))*
|
||||||
|
}
|
||||||
|
|
||||||
|
MethodDeclaration ::=
|
||||||
|
(ParameterList?) {
|
||||||
|
Statement* (return Expression ;)?
|
||||||
|
}
|
||||||
|
|
||||||
|
Declarators ::= (public | private)? static? Type
|
||||||
|
|
||||||
|
Type ::= boolean | void | int ([])? | id ([])?
|
||||||
|
|
||||||
|
ParameterList ::= Type id (, Type id)*
|
||||||
|
|
||||||
|
ArgumentList ::= Expression (, Expression)*
|
||||||
|
|
||||||
|
Reference ::= BaseRef (. id ([ Expression])?)*
|
||||||
|
|
||||||
|
BaseRef ::= this | id ([ Expression])?
|
||||||
|
|
||||||
|
Statement ::=
|
||||||
|
{Statement*}
|
||||||
|
| Type id = Expression;
|
||||||
|
| Reference = Expression;
|
||||||
|
| Reference ( ArgumentList? );
|
||||||
|
| if (Expression) Statement (else Statement)?
|
||||||
|
| while (Expression) Statement
|
||||||
|
|
||||||
|
Expression ::=
|
||||||
|
Reference
|
||||||
|
| Reference ( ArgumentList? )
|
||||||
|
| unop Expression
|
||||||
|
| Expression binop Expression
|
||||||
|
| ( Expression )
|
||||||
|
| num | true | false
|
||||||
|
| new (id() | int [ Expression ] | id [ Expression ] )
|
|
@ -0,0 +1,71 @@
|
||||||
|
package tester;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
|
/* Automated regression tester for Checkpoint 1 tests
|
||||||
|
* Created by Max Beckman-Harned
|
||||||
|
* Put your tests in "tests/pa1_tests" folder in your Eclipse workspace directory
|
||||||
|
*/
|
||||||
|
public class Checkpoint1 {
|
||||||
|
|
||||||
|
static ExecutorService threadPool = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
|
public static void main(String[] args) throws IOException, InterruptedException {
|
||||||
|
File testDir = new File(System.getProperty("java.class.path") + "/../tests/pa1_tests");
|
||||||
|
System.out.println(testDir.getAbsolutePath());
|
||||||
|
int failures = 0;
|
||||||
|
for (File x : testDir.listFiles()) {
|
||||||
|
int returnCode = runTest(x);
|
||||||
|
if (x.getName().indexOf("pass") != -1) {
|
||||||
|
if (returnCode == 0)
|
||||||
|
System.out.println(x.getName() + " passed successfully!");
|
||||||
|
else {
|
||||||
|
failures++;
|
||||||
|
System.err.println(x.getName()
|
||||||
|
+ " failed but should have passed!");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (returnCode == 4)
|
||||||
|
System.out.println(x.getName() + " failed successfully!");
|
||||||
|
else {
|
||||||
|
System.err.println(x.getName() + " did not fail properly!");
|
||||||
|
failures++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(failures + " failures in all.");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int runTest(File x) throws IOException, InterruptedException {
|
||||||
|
ProcessBuilder pb = new ProcessBuilder("java", "miniJava.Compiler", x.getPath()).directory(new File(System.getProperty("java.class.path")));
|
||||||
|
Process p = pb.start();
|
||||||
|
threadPool.execute(new ProcessOutputter(p.getInputStream(), false));
|
||||||
|
p.waitFor();
|
||||||
|
return p.exitValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ProcessOutputter implements Runnable {
|
||||||
|
private Scanner processOutput;
|
||||||
|
private boolean output;
|
||||||
|
|
||||||
|
public ProcessOutputter(InputStream _processStream, boolean _output) {
|
||||||
|
processOutput = new Scanner(_processStream);
|
||||||
|
output = _output;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while(processOutput.hasNextLine()) {
|
||||||
|
String line = processOutput.nextLine();
|
||||||
|
if (output)
|
||||||
|
System.out.println(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 parse assign fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p(int a) {
|
||||||
|
that.this = 4;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex id fail
|
||||||
|
class _id {}
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex id fail
|
||||||
|
class boolean {}
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 parse fail
|
||||||
|
class Foo {}.
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex id fail
|
||||||
|
class true {}
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex comment fail
|
||||||
|
class id {} /* unterminated
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex comment fail
|
||||||
|
class /* /* nested */ */ id {}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex ill char fail
|
||||||
|
class NonTokens{} #
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex binop fail
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
int x = 1 &| 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex binop fail
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
x = 1 + 2*3 = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex/parse binop fail
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
int x = 1 >> 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex binop fail
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
while ( 1 > = 0) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 lex trailing start char fail
|
||||||
|
class Almost {
|
||||||
|
public static void main (String [] args) {
|
||||||
|
} // nothing follows next slash
|
||||||
|
} /
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 lex comment fail
|
||||||
|
class IllegalComment {
|
||||||
|
public static void main (String [] args) {
|
||||||
|
} // nothing follows final *
|
||||||
|
}/* ****
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse field decl fail
|
||||||
|
class id {
|
||||||
|
static private Type x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse field decl fail
|
||||||
|
class id {
|
||||||
|
public private static Type x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse field decl fail
|
||||||
|
class id {
|
||||||
|
int x = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse field decl fail
|
||||||
|
class id {
|
||||||
|
void int x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse field decl fail
|
||||||
|
class id {
|
||||||
|
public [] String x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse field decl fail
|
||||||
|
class id {
|
||||||
|
public void [] x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse local decl fail
|
||||||
|
class id {
|
||||||
|
void foo() {
|
||||||
|
Nonesuch x[2] = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse local decl fail
|
||||||
|
class id {
|
||||||
|
public void f(){
|
||||||
|
Ref [] x(33);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse local decl fail
|
||||||
|
class id {
|
||||||
|
public void f(){
|
||||||
|
int x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse local decl fail
|
||||||
|
class id {
|
||||||
|
public void f(){
|
||||||
|
Foo x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse local decl fail
|
||||||
|
class idfail {
|
||||||
|
public void foo () {
|
||||||
|
int [] x[3] = null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse local decl fail
|
||||||
|
class LValueFail {
|
||||||
|
void foo () {
|
||||||
|
true = false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse expr fail
|
||||||
|
class NonTokens{
|
||||||
|
int main () {
|
||||||
|
return a++b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse expr fail
|
||||||
|
class NonTokens{
|
||||||
|
int main () {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse expr fail
|
||||||
|
class IllegalExpressions {
|
||||||
|
void main () {
|
||||||
|
z = a+!=b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse stmt fail
|
||||||
|
class IllegalStmt {
|
||||||
|
void main () {
|
||||||
|
this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse expr fail
|
||||||
|
class IllegalExpressions {
|
||||||
|
static void foo (int a) {
|
||||||
|
if (a = a) {
|
||||||
|
a = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse unop fail
|
||||||
|
class IllegalExpressions {
|
||||||
|
void foo() {
|
||||||
|
z = a!b;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
// PA1 parse ref fail
|
||||||
|
class IllegalExpressions {
|
||||||
|
void foo () {
|
||||||
|
a [b] [c] = d; // not ok
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse method fail
|
||||||
|
class IllegalExpressions {
|
||||||
|
void foo () {
|
||||||
|
if (x != 0)
|
||||||
|
return x;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse refs fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p() {
|
||||||
|
A a [17] = 23;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse decl fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p() {
|
||||||
|
boolean [] a = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse call fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p(int a, boolean b) {
|
||||||
|
int p(a,b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse decl fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p(int a) {
|
||||||
|
Test [ ] x.y = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse assign fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p(int a) {
|
||||||
|
Test [ ] = a * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse call fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p(int a) {
|
||||||
|
c.p(2,3)[3] = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse assign fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p(int a) {
|
||||||
|
that.this = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse assign fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p() {
|
||||||
|
x.y() = z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse decl fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p() {
|
||||||
|
c [] d b = new int[4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse new fail
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p() {
|
||||||
|
x = new Foo(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
class id {}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex id pass
|
||||||
|
class id {}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex id pass
|
||||||
|
class id_ {}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex id pass
|
||||||
|
class id_0_1__{}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex id pass
|
||||||
|
class Class{}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class // comment $$ followed by \r\n
|
||||||
|
id {}
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class id {} // trailing comment terminated by \r\n
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class /* comment */ id {}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class /**/ id {}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class /*/**/ id {}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class /*/$*/ id {}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 lex unop pass
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
int x = - b;
|
||||||
|
boolean y = !y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex unop pass
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
boolean x = !!!!!b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex unop pass
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
boolean x = 10 >- b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex binop pass
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
int x = 1 + 2 * 3 / 4 > 5 >= 6 < 7 <= 8 != 9 && 0 || 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex binop pass
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
boolean x = true && false || x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex unop pass
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
int y = --y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex unop pass
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
int x = b - - b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
// PA1 lex unop pass
|
||||||
|
class id {
|
||||||
|
void p(){
|
||||||
|
int x = b - - - -b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// PA1 lex whitespace including tab
|
||||||
|
class Test {
|
||||||
|
/* multiple comments between
|
||||||
|
*/
|
||||||
|
|
||||||
|
// tokens
|
||||||
|
|
||||||
|
/**//* is OK */
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class // comment followed by \n only
|
||||||
|
id {}
|
|
@ -0,0 +1,3 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class // comment followed by \r only
|
||||||
|
id {}
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class id {} // trailing comment terminated by \r
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class id {} // trailing comment terminated by \n
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class id {} // unterminated comment - no trailing \r\n
|
|
@ -0,0 +1,2 @@
|
||||||
|
// PA1 lex comment pass
|
||||||
|
class id {} /* no trailing \r\n */
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 parse field decl pass
|
||||||
|
class id {
|
||||||
|
public static Type x;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 parse field decl pass
|
||||||
|
class id {
|
||||||
|
private static Type x;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 parse field decl pass
|
||||||
|
class id {
|
||||||
|
static Type x;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 parse field decl pass
|
||||||
|
class id {
|
||||||
|
Type x;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 parse field decl pass
|
||||||
|
class id {
|
||||||
|
int x;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 parse field decl pass
|
||||||
|
class id {
|
||||||
|
int[] x;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 parse field decl pass
|
||||||
|
class id {
|
||||||
|
static void x;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 parse method decl pass
|
||||||
|
class id {
|
||||||
|
public static void main(String[] args){}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
// PA1 parse method decl pass
|
||||||
|
class id {
|
||||||
|
private int f(int x, boolean b) {return 3;}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
// PA1 parse classdecls pass
|
||||||
|
class MainClass {
|
||||||
|
public static void main (String [] args) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class OfItsOwn {
|
||||||
|
int A_01;
|
||||||
|
} // class OfItsOwn
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// PA1 parse identifiers pass
|
||||||
|
class Keywords {
|
||||||
|
|
||||||
|
// minijava keywords are lower case only
|
||||||
|
void p() {
|
||||||
|
int format = while_1;
|
||||||
|
int Int = New;
|
||||||
|
For = Class;
|
||||||
|
FOR = RETURN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int declare () {
|
||||||
|
boolean iF = true;
|
||||||
|
boolean Then = false;
|
||||||
|
boolean else1 = false;
|
||||||
|
|
||||||
|
if (true == false) { else1 = iF == Then; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse new pass
|
||||||
|
class MainClass {
|
||||||
|
public static void main (String [] args) {
|
||||||
|
SecondSubClass newobj = new SecondSubClass ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse new pass
|
||||||
|
class Foo {
|
||||||
|
void bar() {
|
||||||
|
int[] newarr = new int[20];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
// PA1 parse methods pass
|
||||||
|
class MainClass {
|
||||||
|
public static void main (String [] args) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class SuperClass
|
||||||
|
{
|
||||||
|
public void setWorth (int worth){
|
||||||
|
integer = worth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWorth (){
|
||||||
|
return this.integer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTruth (boolean truth){
|
||||||
|
bool = truth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTruth (){
|
||||||
|
return this.bool;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
// PA1 parse parse pass
|
||||||
|
class MainClass {
|
||||||
|
public static void main (String [] args) {
|
||||||
|
SecondSubClass newobj = new SecondSubClass ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class SuperClass
|
||||||
|
{
|
||||||
|
private void fillup (boolean open, int [] jar, int marble, int upto) {
|
||||||
|
|
||||||
|
int index = 0;
|
||||||
|
if (open == true) {
|
||||||
|
while ( index < upto ) {
|
||||||
|
ownjar [index] = jar [index];
|
||||||
|
jar [index] = marble;
|
||||||
|
} // while
|
||||||
|
} // if
|
||||||
|
} // fillup
|
||||||
|
|
||||||
|
} // class SuperClass
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
// PA1 parse refs pass
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p() {
|
||||||
|
a = true;
|
||||||
|
a [b] = c;
|
||||||
|
p ();
|
||||||
|
a.b[3] = d;
|
||||||
|
c.p(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
// PA1 parse decl pass
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
int [] a;
|
||||||
|
Test [] t;
|
||||||
|
|
||||||
|
void p() {
|
||||||
|
void x = this.t[3].a[4].p();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
// PA1 parse refs pass
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p() {
|
||||||
|
A a = 23;
|
||||||
|
boolean b = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse assign pass
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p() {
|
||||||
|
a = b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse call pass
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p(int a, boolean b) {
|
||||||
|
p(a,b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
// PA1 parse decl pass
|
||||||
|
class Test {
|
||||||
|
|
||||||
|
void p(int a) {
|
||||||
|
Test [ ] v = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue