1
Fork 0

Recursive Descent Parsing

Implemented tokenizer/scanner and recursive descent parser.
master
Joshua Potter 2014-02-15 21:00:29 -05:00
commit 983f4cd852
108 changed files with 1802 additions and 0 deletions

215
.gitignore vendored Normal file
View File

@ -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

BIN
docs/PA1.pdf Normal file

Binary file not shown.

View File

@ -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);
}
}
}

View File

@ -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();
}
}

View File

@ -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';
}
}

View File

@ -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;
}
}

View File

@ -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 ] )

View File

@ -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);
}
}
}
}

7
miniJava/test.java Normal file
View File

@ -0,0 +1,7 @@
// PA1 parse assign fail
class Test {
void p(int a) {
that.this = 4;
}
}

View File

@ -0,0 +1,2 @@
// PA1 lex id fail
class _id {}

View File

@ -0,0 +1,2 @@
// PA1 lex id fail
class boolean {}

View File

@ -0,0 +1,2 @@
// PA1 parse fail
class Foo {}.

View File

@ -0,0 +1,2 @@
// PA1 lex id fail
class true {}

View File

@ -0,0 +1,2 @@
// PA1 lex comment fail
class id {} /* unterminated

View File

@ -0,0 +1,3 @@
// PA1 lex comment fail
class /* /* nested */ */ id {}

View File

@ -0,0 +1,2 @@
// PA1 lex ill char fail
class NonTokens{} #

View File

@ -0,0 +1,7 @@
// PA1 lex binop fail
class id {
void p(){
int x = 1 &| 0;
}
}

View File

@ -0,0 +1,7 @@
// PA1 lex binop fail
class id {
void p(){
x = 1 + 2*3 = 4;
}
}

View File

@ -0,0 +1,7 @@
// PA1 lex/parse binop fail
class id {
void p(){
int x = 1 >> 0;
}
}

View File

@ -0,0 +1,7 @@
// PA1 lex binop fail
class id {
void p(){
while ( 1 > = 0) {}
}
}

View File

@ -0,0 +1,5 @@
// PA1 lex trailing start char fail
class Almost {
public static void main (String [] args) {
} // nothing follows next slash
} /

View File

@ -0,0 +1,5 @@
// PA1 lex comment fail
class IllegalComment {
public static void main (String [] args) {
} // nothing follows final *
}/* ****

View File

@ -0,0 +1,6 @@
// PA1 parse field decl fail
class id {
static private Type x;
}

View File

@ -0,0 +1,6 @@
// PA1 parse field decl fail
class id {
public private static Type x;
}

View File

@ -0,0 +1,6 @@
// PA1 parse field decl fail
class id {
int x = 3;
}

View File

@ -0,0 +1,6 @@
// PA1 parse field decl fail
class id {
void int x;
}

View File

@ -0,0 +1,6 @@
// PA1 parse field decl fail
class id {
public [] String x;
}

View File

@ -0,0 +1,6 @@
// PA1 parse field decl fail
class id {
public void [] x;
}

View File

@ -0,0 +1,8 @@
// PA1 parse local decl fail
class id {
void foo() {
Nonesuch x[2] = 3;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse local decl fail
class id {
public void f(){
Ref [] x(33);
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse local decl fail
class id {
public void f(){
int x;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse local decl fail
class id {
public void f(){
Foo x;
}
}

View File

@ -0,0 +1,6 @@
// PA1 parse local decl fail
class idfail {
public void foo () {
int [] x[3] = null;
}
}

View File

@ -0,0 +1,6 @@
// PA1 parse local decl fail
class LValueFail {
void foo () {
true = false;
}
}

View File

@ -0,0 +1,6 @@
// PA1 parse expr fail
class NonTokens{
int main () {
return a++b;
}
}

View File

@ -0,0 +1,6 @@
// PA1 parse expr fail
class NonTokens{
int main () {
return;
}
}

View File

@ -0,0 +1,6 @@
// PA1 parse expr fail
class IllegalExpressions {
void main () {
z = a+!=b;
}
}

View File

@ -0,0 +1,6 @@
// PA1 parse stmt fail
class IllegalStmt {
void main () {
this;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse expr fail
class IllegalExpressions {
static void foo (int a) {
if (a = a) {
a = a;
}
}
}

View File

@ -0,0 +1,6 @@
// PA1 parse unop fail
class IllegalExpressions {
void foo() {
z = a!b;
}
}

View File

@ -0,0 +1,6 @@
// PA1 parse ref fail
class IllegalExpressions {
void foo () {
a [b] [c] = d; // not ok
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse method fail
class IllegalExpressions {
void foo () {
if (x != 0)
return x;
return y;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse refs fail
class Test {
void p() {
A a [17] = 23;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse decl fail
class Test {
void p() {
boolean [] a = b;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse call fail
class Test {
void p(int a, boolean b) {
int p(a,b);
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse decl fail
class Test {
void p(int a) {
Test [ ] x.y = a;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse assign fail
class Test {
void p(int a) {
Test [ ] = a * 3;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse call fail
class Test {
void p(int a) {
c.p(2,3)[3] = 4;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse assign fail
class Test {
void p(int a) {
that.this = 4;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse assign fail
class Test {
void p() {
x.y() = z;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse decl fail
class Test {
void p() {
c [] d b = new int[4];
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse new fail
class Test {
void p() {
x = new Foo(10);
}
}

View File

@ -0,0 +1,2 @@
class id {}

View File

@ -0,0 +1,3 @@
// PA1 lex id pass
class id {}

View File

@ -0,0 +1,3 @@
// PA1 lex id pass
class id_ {}

View File

@ -0,0 +1,3 @@
// PA1 lex id pass
class id_0_1__{}

View File

@ -0,0 +1,3 @@
// PA1 lex id pass
class Class{}

View File

@ -0,0 +1,3 @@
// PA1 lex comment pass
class // comment $$ followed by \r\n
id {}

View File

@ -0,0 +1,2 @@
// PA1 lex comment pass
class id {} // trailing comment terminated by \r\n

View File

@ -0,0 +1,3 @@
// PA1 lex comment pass
class /* comment */ id {}

View File

@ -0,0 +1,3 @@
// PA1 lex comment pass
class /**/ id {}

View File

@ -0,0 +1,3 @@
// PA1 lex comment pass
class /*/**/ id {}

View File

@ -0,0 +1,3 @@
// PA1 lex comment pass
class /*/$*/ id {}

View File

@ -0,0 +1,8 @@
// PA1 lex unop pass
class id {
void p(){
int x = - b;
boolean y = !y;
}
}

View File

@ -0,0 +1,7 @@
// PA1 lex unop pass
class id {
void p(){
boolean x = !!!!!b;
}
}

View File

@ -0,0 +1,7 @@
// PA1 lex unop pass
class id {
void p(){
boolean x = 10 >- b;
}
}

View File

@ -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;
}
}

View File

@ -0,0 +1,7 @@
// PA1 lex binop pass
class id {
void p(){
boolean x = true && false || x;
}
}

View File

@ -0,0 +1,7 @@
// PA1 lex unop pass
class id {
void p(){
int y = --y;
}
}

View File

@ -0,0 +1,7 @@
// PA1 lex unop pass
class id {
void p(){
int x = b - - b;
}
}

View File

@ -0,0 +1,7 @@
// PA1 lex unop pass
class id {
void p(){
int x = b - - - -b;
}
}

View File

View File

@ -0,0 +1,12 @@
// PA1 lex whitespace including tab
class Test {
/* multiple comments between
*/
// tokens
/**//* is OK */
}

View File

@ -0,0 +1,3 @@
// PA1 lex comment pass
class // comment followed by \n only
id {}

View File

@ -0,0 +1,3 @@
// PA1 lex comment pass
class // comment followed by \r only
id {}

View File

@ -0,0 +1,2 @@
// PA1 lex comment pass
class id {} // trailing comment terminated by \r

View File

@ -0,0 +1,2 @@
// PA1 lex comment pass
class id {} // trailing comment terminated by \n

View File

@ -0,0 +1,2 @@
// PA1 lex comment pass
class id {} // unterminated comment - no trailing \r\n

View File

@ -0,0 +1,2 @@
// PA1 lex comment pass
class id {} /* no trailing \r\n */

View File

@ -0,0 +1,5 @@
// PA1 parse field decl pass
class id {
public static Type x;
}

View File

@ -0,0 +1,5 @@
// PA1 parse field decl pass
class id {
private static Type x;
}

View File

@ -0,0 +1,5 @@
// PA1 parse field decl pass
class id {
static Type x;
}

View File

@ -0,0 +1,5 @@
// PA1 parse field decl pass
class id {
Type x;
}

View File

@ -0,0 +1,5 @@
// PA1 parse field decl pass
class id {
int x;
}

View File

@ -0,0 +1,5 @@
// PA1 parse field decl pass
class id {
int[] x;
}

View File

@ -0,0 +1,5 @@
// PA1 parse field decl pass
class id {
static void x;
}

View File

@ -0,0 +1,5 @@
// PA1 parse method decl pass
class id {
public static void main(String[] args){}
}

View File

@ -0,0 +1,5 @@
// PA1 parse method decl pass
class id {
private int f(int x, boolean b) {return 3;}
}

View File

@ -0,0 +1,9 @@
// PA1 parse classdecls pass
class MainClass {
public static void main (String [] args) {}
}
class OfItsOwn {
int A_01;
} // class OfItsOwn

View File

@ -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; }
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse new pass
class MainClass {
public static void main (String [] args) {
SecondSubClass newobj = new SecondSubClass ();
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse new pass
class Foo {
void bar() {
int[] newarr = new int[20];
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -0,0 +1,11 @@
// PA1 parse decl pass
class Test {
int [] a;
Test [] t;
void p() {
void x = this.t[3].a[4].p();
}
}

View File

@ -0,0 +1,9 @@
// PA1 parse refs pass
class Test {
void p() {
A a = 23;
boolean b = c;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse assign pass
class Test {
void p() {
a = b;
}
}

View File

@ -0,0 +1,8 @@
// PA1 parse call pass
class Test {
void p(int a, boolean b) {
p(a,b);
}
}

View File

@ -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