Created
February 2, 2018 12:04
-
-
Save glennismade/a09cbd6a7efe1fee791045badb18d607 to your computer and use it in GitHub Desktop.
Basic Java Compiler with Simplified Syntax
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
/** | |
* represents a type of veriable | |
*/ | |
public enum BuiltInType implements Type { | |
STRING, INTEGER, VOID, FLOAT | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.parser; | |
import glenn.compiler.gh.block.Blk; | |
import glenn.compiler.gh.block.Class; | |
import glenn.compiler.gh.lex.Tokenizer; | |
/** | |
* Created by glennhealy on 01/03/2016. | |
*/ | |
public class ClassPars extends Parser<Class> { | |
@Override | |
public boolean shouldParse(String line) { | |
return line.matches("class [a-zA-Z][a-zA-Z0-9]*"); | |
} | |
@Override | |
public Class parse(Blk superBlk, Tokenizer tokenizer) { | |
tokenizer.nextTok(); // Skip the class token. | |
String name = tokenizer.nextTok().getToken(); // Get the string value of the next token. | |
return new Class(name); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.lex; | |
/** | |
* Created by glennhealy on 28/02/2016. | |
*/ | |
public class Tok { | |
private String token; | |
private TokType type; | |
public Tok(String token, TokType type) { | |
this.token = token; | |
this.type = type; | |
} | |
public String getToken() { | |
return token; | |
} | |
public TokType getType() { | |
return type; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
/** | |
* Created by glennhealy on 02/03/2016. | |
*/ | |
public interface Type { | |
public static Type match(String str) { | |
try { | |
return BuiltInType.valueOf(str.toUpperCase()); | |
} | |
catch (Exception e) { | |
// TODO: Match str to a class. | |
return null; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
import glenn.compiler.gh.block.Blk; | |
/** | |
* Created by glennhealy on 02/03/2016. | |
*/ | |
public class Variable extends Value { | |
private Blk blk; | |
private String name; | |
public Variable(Blk blk, Type type, String name, Object value) { | |
super(type, value); | |
this.blk = blk; | |
this.name = name; | |
} | |
public Blk getBlk() { | |
return blk; | |
} | |
public String getName() { | |
return name; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.lex; | |
import java.util.regex.Pattern; | |
/** | |
* Created by glennhealy on 28/02/2016. | |
*/ | |
public class TokData { | |
private Pattern pattern; | |
private TokType type; | |
public TokData(Pattern pattern, TokType type){ | |
this.pattern = pattern; | |
this.type = type; | |
} | |
public Pattern getPattern() { | |
return pattern; | |
} | |
public TokType getType() { | |
return type; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.lex; | |
import java.util.ArrayList; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
/** | |
* Created by glennhealy on 28/02/2016. | |
*/ | |
public class Tokenizer { | |
private ArrayList<TokData> tokDatas; | |
private String str; | |
private Tok lastToken; | |
private boolean pushBack; | |
public Tokenizer(String str) { | |
this.tokDatas = new ArrayList<TokData>(); | |
this.str = str; | |
tokDatas.add(new TokData(Pattern.compile("^([a-zA-Z][a-zA-Z0-9]*)"), TokType.IDENTIFIER)); | |
tokDatas.add(new TokData(Pattern.compile("^((-)?[0-9]+)"), TokType.INTEGER_LITERAL)); | |
tokDatas.add(new TokData(Pattern.compile("^([+-]?\\d*\\.?\\d*)$"), TokType.FLOAT_LITERAL)); | |
tokDatas.add(new TokData(Pattern.compile("^(\".*\")"), TokType.STRING_LITERAL)); | |
for (String t : new String[] { "=", "\\(", "\\)", "\\.", "\\," }) { | |
tokDatas.add(new TokData(Pattern.compile("^(" + t + ")"), TokType.TOKEN)); | |
} | |
} | |
public Tok nextTok() { | |
str = str.trim(); | |
if (pushBack) { | |
pushBack = false; | |
return lastToken; | |
} | |
if (str.isEmpty()) { | |
return (lastToken = new Tok("", TokType.EMPTY)); | |
} | |
for (TokData data : tokDatas) { | |
Matcher matcher = data.getPattern().matcher(str); | |
if (matcher.find()) { | |
String token = matcher.group().trim(); | |
str = matcher.replaceFirst(""); | |
if (data.getType() == TokType.STRING_LITERAL) { | |
return (lastToken = new Tok(token.substring(1, token.length() - 1), TokType.STRING_LITERAL)); | |
} | |
else { | |
return (lastToken = new Tok(token, data.getType())); | |
} | |
} | |
} | |
throw new IllegalStateException("Could not parse " + str); | |
} | |
public boolean hasNextToken() { | |
return !str.isEmpty(); | |
} | |
public void pushBack() { | |
if (lastToken != null) { | |
this.pushBack = true; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
/** | |
* Created by glennhealy on 01/03/2016. | |
*/ | |
public class Parameter { | |
private String name; | |
private Type type; | |
public Parameter(Type type, String name){ | |
this.type = type; | |
this.name = name; | |
} | |
public String getName(){ | |
return name; | |
} | |
public Type getType(){ | |
return type; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.parser; | |
import glenn.compiler.gh.block.Blk; | |
import glenn.compiler.gh.block.Class; | |
import glenn.compiler.gh.lex.Tokenizer; | |
/** | |
* Created by glennhealy on 01/03/2016. | |
*/ | |
public class ClassPars extends Parser<Class> { | |
@Override | |
public boolean shouldParse(String line) { | |
return line.matches("class [a-zA-Z][a-zA-Z0-9]*"); | |
} | |
@Override | |
public Class parse(Blk superBlk, Tokenizer tokenizer) { | |
tokenizer.nextTok(); // Skip the class token. | |
String name = tokenizer.nextTok().getToken(); // Get the string value of the next token. | |
return new Class(name); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.parser; | |
import java.util.ArrayList; | |
import glenn.compiler.gh.BuiltInType; | |
import glenn.compiler.gh.block.Blk; | |
import glenn.compiler.gh.block.Method; | |
import glenn.compiler.gh.Parameter; | |
import glenn.compiler.gh.lex.Tok; | |
import glenn.compiler.gh.lex.Tokenizer; | |
/** | |
* Created by glennhealy on 01/03/2016. | |
*/ | |
public class MethodPars extends Parser<Method> { | |
@Override | |
public boolean shouldParse(String line) { | |
return line.matches("method [a-zA-Z][a-zA-Z0-9]* requires \\(([a-zA-Z][a-zA-Z0-9]* [a-zA-Z][a-zA-Z0-9]*)*\\) returns [a-zA-Z][a-zA-Z0-9]*"); | |
} | |
@Override | |
public Method parse(Blk superBlk, Tokenizer tokenizer) { | |
tokenizer.nextTok(); // Skip the method token. | |
String name = tokenizer.nextTok().getToken(); | |
tokenizer.nextTok(); // Skip the requires token. | |
tokenizer.nextTok(); // Skip the ( token. | |
Tok first = tokenizer.nextTok(); | |
ArrayList<Parameter> params = new ArrayList<>(); | |
if (!first.getToken().equals(")")) { | |
String[] paramData = new String[] { first.getToken(), null }; // 0 = type, 1 = value | |
while (tokenizer.hasNextToken()) { | |
Tok tok = tokenizer.nextTok(); | |
if (tok.getToken().equals(")")) { | |
break; | |
} | |
if (paramData[0] == null) { | |
paramData[0] = tok.getToken(); | |
} | |
else { | |
paramData[1] = tok.getToken(); | |
params.add(new Parameter(BuiltInType.valueOf(paramData[0].toUpperCase()), paramData[1])); | |
paramData = new String[2]; | |
} | |
} | |
} | |
tokenizer.nextTok(); // Skip the returns token. | |
String returnType = tokenizer.nextTok().getToken(); | |
return new Method(superBlk, name, returnType, params.toArray(new Parameter[params.size()])); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.parser; | |
import glenn.compiler.gh.lex.Tokenizer; | |
import glenn.compiler.gh.block.Blk; | |
/** | |
* Created by glennhealy on 29/02/2016. | |
*/ | |
public abstract class Parser<T extends Blk> { | |
/** | |
* Takes a line and checks to see if it is for this parser by using regex. | |
*/ | |
public abstract boolean shouldParse(String line); | |
/** | |
* Take the superBlock and the tokenizer for the line and return a block of this parser's type. | |
*/ | |
public abstract T parse(Blk superBlk, Tokenizer tokenizer); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.parser; | |
//import Type; | |
//import Variable; | |
import glenn.compiler.gh.block.Blk; | |
import glenn.compiler.gh.block.VariableBlk; | |
import glenn.compiler.gh.lex.Tok; | |
import glenn.compiler.gh.lex.TokType; | |
import glenn.compiler.gh.lex.Tokenizer; | |
/** | |
* Created by glennhealy on 02/03/2016. | |
*/public class VarPars extends Parser<Blk> { | |
@Override | |
public boolean shouldParse(String line) { | |
return line.matches("var [a-zA-Z]+ [a-zA-Z]+ = (\")?[a-zA-Z0-9]*(\")?"); | |
} | |
@Override | |
public Blk parse(Blk superBlk, Tokenizer tokenizer) { | |
tokenizer.nextTok(); // Skip the var token. | |
String type = tokenizer.nextTok().getToken(); | |
String name = tokenizer.nextTok().getToken(); | |
tokenizer.nextTok(); // Skip the = token. | |
Tok v = tokenizer.nextTok(); | |
Object value = null; | |
if (v.getType() == TokType.INTEGER_LITERAL) { | |
value = Integer.valueOf(v.getToken()); | |
} | |
else if (v.getType() == TokType.FLOAT_LITERAL) { | |
value = Float.valueOf(v.getToken()); //token type check float | |
} | |
else if (v.getType() == TokType.STRING_LITERAL) { | |
value = v.getToken(); | |
} | |
else /* if the token is a veriable itendifier */ { | |
value = superBlk.getVariable(v.getToken()).getValue(); | |
} | |
return new VariableBlk(superBlk, type, name, value); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
import glenn.compiler.gh.block.Blk; | |
import glenn.compiler.gh.block.Method; | |
import glenn.compiler.gh.block.Class; | |
import glenn.compiler.gh.lex.Tokenizer; | |
import glenn.compiler.gh.parser.ClassPars; | |
import glenn.compiler.gh.parser.MethodPars; | |
import glenn.compiler.gh.parser.Parser; | |
import glenn.compiler.gh.parser.VarPars; | |
import java.awt.*; | |
import java.util.ArrayList; | |
////////import me.compiler.lex.*; | |
/** | |
* Created by glennhealy on 02/03/2016. | |
*/ | |
public class Runtime { | |
private ArrayList<Class> classes; | |
public Runtime() { | |
this.classes = new ArrayList<Class>(); | |
String code = "class Variables" + "\n" + | |
"method main requires () returns void" + "\n" + | |
"var string str = \"main\"" + "\n" + | |
"method printString requires (string str) returns void"; | |
Parser<?>[] parsers = new Parser<?>[] { new ClassPars(), new MethodPars(), new VarPars() }; | |
Class main = null; | |
Blk blk = null; | |
boolean succeed = false; | |
for (String line : code.split("\n")) { | |
succeed = false; | |
line = line.trim(); | |
Tokenizer tokenizer = new Tokenizer(line); | |
for (Parser<?> parser : parsers) { | |
if (parser.shouldParse(line)) { | |
Blk newBlk = parser.parse(blk, tokenizer); | |
if (newBlk instanceof Class) { | |
classes.add((Class) newBlk); | |
} | |
else if (newBlk instanceof Method) { | |
blk.getBlockTree().get(0).addBlock(newBlk); | |
} | |
else { | |
blk.addBlock(newBlk); | |
} | |
blk = newBlk; | |
succeed = true; | |
break; | |
} | |
} | |
if (succeed != true) { | |
throw new IllegalArgumentException("Invalid arguments present at Line " + line); | |
} | |
} | |
for (Class c : classes) { | |
for (Blk b : c.getSubBlks()) { | |
if (b instanceof Method) { | |
Method method = (Method) b; | |
if (method.getName().equals("main must equal") && method.getType().equals("void") && method.getParameters().length == 0) { | |
main = c; | |
System.out.println("compiling correct" + getClass().getSimpleName()); | |
} | |
} | |
} | |
} | |
if (main == null) { | |
throw new IllegalStateException("No main method could be found. please create a main method."); | |
} | |
main.run(); | |
} | |
public static void main(String[] args) { | |
new Runtime(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
/** | |
* represents a value for a variable type. | |
*/ | |
public class Value { | |
private Type type; | |
private Object value; | |
public Value(Type type, Object value) { | |
this.type = type; | |
this.value = value; | |
} | |
public Type getType() { | |
return type; | |
} | |
public Object getValue() { | |
return value; | |
} | |
public void setValue(Object value) { | |
this.value = value; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<identifier> | |
First character is a letter, or any proceeding characters are letters or numbers. | |
<type>: | |
A primitive type: string, int, char, float, double boolean. | |
<value>: | |
Either an identifier (for a variable) or a literal (1, "Hello", true) | |
Class Declaration: | |
'class <identifier>' | |
Method Declaration: | |
'method <identifier = name> requires ([<type> <identifier = name>...]) returns <type>' | |
Variable Declaration: | |
'var <type> <identifier = name> [= <value>]' | |
Method Invocation: | |
'<identifier = name>([<value>...])' | |
Print Statement: | |
'Print <value>' | |
Return Statement: | |
'return <value>' | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class HelloWorld | |
method main requires() returns void | |
print "HelloWorld" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.parser; | |
import java.util.ArrayList; | |
import glenn.compiler.gh.BuiltInType; | |
import glenn.compiler.gh.block.Blk; | |
import glenn.compiler.gh.block.Method; | |
import glenn.compiler.gh.Parameter; | |
import glenn.compiler.gh.lex.Tok; | |
import glenn.compiler.gh.lex.Tokenizer; | |
/** | |
* Created by glennhealy on 01/03/2016. | |
*/ | |
public class MethodPars extends Parser<Method> { | |
@Override | |
public boolean shouldParse(String line) { | |
return line.matches("method [a-zA-Z][a-zA-Z0-9]* requires \\(([a-zA-Z][a-zA-Z0-9]* [a-zA-Z][a-zA-Z0-9]*)*\\) returns [a-zA-Z][a-zA-Z0-9]*"); | |
} | |
@Override | |
public Method parse(Blk superBlk, Tokenizer tokenizer) { | |
tokenizer.nextTok(); // Skip the method token. | |
String name = tokenizer.nextTok().getToken(); | |
tokenizer.nextTok(); // Skip the requires token. | |
tokenizer.nextTok(); // Skip the ( token. | |
Tok first = tokenizer.nextTok(); | |
ArrayList<Parameter> params = new ArrayList<>(); | |
if (!first.getToken().equals(")")) { | |
String[] paramData = new String[] { first.getToken(), null }; // 0 = type, 1 = value | |
while (tokenizer.hasNextToken()) { | |
Tok tok = tokenizer.nextTok(); | |
if (tok.getToken().equals(")")) { | |
break; | |
} | |
if (paramData[0] == null) { | |
paramData[0] = tok.getToken(); | |
} | |
else { | |
paramData[1] = tok.getToken(); | |
params.add(new Parameter(BuiltInType.valueOf(paramData[0].toUpperCase()), paramData[1])); | |
paramData = new String[2]; | |
} | |
} | |
} | |
tokenizer.nextTok(); // Skip the returns token. | |
String returnType = tokenizer.nextTok().getToken(); | |
return new Method(superBlk, name, returnType, params.toArray(new Parameter[params.size()])); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
/** | |
* Created by glennhealy on 01/03/2016. | |
*/ | |
public class Parameter { | |
private String name; | |
private Type type; | |
public Parameter(Type type, String name){ | |
this.type = type; | |
this.name = name; | |
} | |
public String getName(){ | |
return name; | |
} | |
public Type getType(){ | |
return type; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.parser; | |
import glenn.compiler.gh.lex.Tokenizer; | |
import glenn.compiler.gh.block.Blk; | |
/** | |
* Created by glennhealy on 29/02/2016. | |
*/ | |
public abstract class Parser<T extends Blk> { | |
/** | |
* Takes a line and checks to see if it is for this parser by using regex. | |
*/ | |
public abstract boolean shouldParse(String line); | |
/** | |
* Take the superBlock and the tokenizer for the line and return a block of this parser's type. | |
*/ | |
public abstract T parse(Blk superBlk, Tokenizer tokenizer); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
import glenn.compiler.gh.block.Blk; | |
import glenn.compiler.gh.block.Method; | |
import glenn.compiler.gh.block.Class; | |
import glenn.compiler.gh.lex.Tokenizer; | |
import glenn.compiler.gh.parser.ClassPars; | |
import glenn.compiler.gh.parser.MethodPars; | |
import glenn.compiler.gh.parser.Parser; | |
import glenn.compiler.gh.parser.VarPars; | |
import java.awt.*; | |
import java.util.ArrayList; | |
////////import me.compiler.lex.*; | |
/** | |
* Created by glennhealy on 02/03/2016. | |
*/ | |
public class Runtime { | |
private ArrayList<Class> classes; | |
public Runtime() { | |
this.classes = new ArrayList<Class>(); | |
String code = "class Variables" + "\n" + | |
"method main requires () returns void" + "\n" + | |
"var string str = \"main\"" + "\n" + | |
"method printString requires (string str) returns void"; | |
Parser<?>[] parsers = new Parser<?>[] { new ClassPars(), new MethodPars(), new VarPars() }; | |
Class main = null; | |
Blk blk = null; | |
boolean succeed = false; | |
for (String line : code.split("\n")) { | |
succeed = false; | |
line = line.trim(); | |
Tokenizer tokenizer = new Tokenizer(line); | |
for (Parser<?> parser : parsers) { | |
if (parser.shouldParse(line)) { | |
Blk newBlk = parser.parse(blk, tokenizer); | |
if (newBlk instanceof Class) { | |
classes.add((Class) newBlk); | |
} | |
else if (newBlk instanceof Method) { | |
blk.getBlockTree().get(0).addBlock(newBlk); | |
} | |
else { | |
blk.addBlock(newBlk); | |
} | |
blk = newBlk; | |
succeed = true; | |
break; | |
} | |
} | |
if (succeed != true) { | |
throw new IllegalArgumentException("Invalid arguments present at Line " + line); | |
} | |
} | |
for (Class c : classes) { | |
for (Blk b : c.getSubBlks()) { | |
if (b instanceof Method) { | |
Method method = (Method) b; | |
if (method.getName().equals("main must equal") && method.getType().equals("void") && method.getParameters().length == 0) { | |
main = c; | |
System.out.println("compiling correct" + getClass().getSimpleName()); | |
} | |
} | |
} | |
} | |
if (main == null) { | |
throw new IllegalStateException("No main method could be found. please create a main method."); | |
} | |
main.run(); | |
} | |
public static void main(String[] args) { | |
new Runtime(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.lex; | |
/** | |
* Created by glennhealy on 28/02/2016. | |
*/ | |
public class Tok { | |
private String token; | |
private TokType type; | |
public Tok(String token, TokType type) { | |
this.token = token; | |
this.type = type; | |
} | |
public String getToken() { | |
return token; | |
} | |
public TokType getType() { | |
return type; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.lex; | |
import java.util.regex.Pattern; | |
/** | |
* Created by glennhealy on 28/02/2016. | |
*/ | |
public class TokData { | |
private Pattern pattern; | |
private TokType type; | |
public TokData(Pattern pattern, TokType type){ | |
this.pattern = pattern; | |
this.type = type; | |
} | |
public Pattern getPattern() { | |
return pattern; | |
} | |
public TokType getType() { | |
return type; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.lex; | |
import java.util.ArrayList; | |
import java.util.regex.Matcher; | |
import java.util.regex.Pattern; | |
/** | |
* Created by glennhealy on 28/02/2016. | |
*/ | |
public class Tokenizer { | |
private ArrayList<TokData> tokDatas; | |
private String str; | |
private Tok lastToken; | |
private boolean pushBack; | |
public Tokenizer(String str) { | |
this.tokDatas = new ArrayList<TokData>(); | |
this.str = str; | |
tokDatas.add(new TokData(Pattern.compile("^([a-zA-Z][a-zA-Z0-9]*)"), TokType.IDENTIFIER)); | |
tokDatas.add(new TokData(Pattern.compile("^((-)?[0-9]+)"), TokType.INTEGER_LITERAL)); | |
tokDatas.add(new TokData(Pattern.compile("^([+-]?\\d*\\.?\\d*)$"), TokType.FLOAT_LITERAL)); | |
tokDatas.add(new TokData(Pattern.compile("^(\".*\")"), TokType.STRING_LITERAL)); | |
for (String t : new String[] { "=", "\\(", "\\)", "\\.", "\\," }) { | |
tokDatas.add(new TokData(Pattern.compile("^(" + t + ")"), TokType.TOKEN)); | |
} | |
} | |
public Tok nextTok() { | |
str = str.trim(); | |
if (pushBack) { | |
pushBack = false; | |
return lastToken; | |
} | |
if (str.isEmpty()) { | |
return (lastToken = new Tok("", TokType.EMPTY)); | |
} | |
for (TokData data : tokDatas) { | |
Matcher matcher = data.getPattern().matcher(str); | |
if (matcher.find()) { | |
String token = matcher.group().trim(); | |
str = matcher.replaceFirst(""); | |
if (data.getType() == TokType.STRING_LITERAL) { | |
return (lastToken = new Tok(token.substring(1, token.length() - 1), TokType.STRING_LITERAL)); | |
} | |
else { | |
return (lastToken = new Tok(token, data.getType())); | |
} | |
} | |
} | |
throw new IllegalStateException("Could not parse " + str); | |
} | |
public boolean hasNextToken() { | |
return !str.isEmpty(); | |
} | |
public void pushBack() { | |
if (lastToken != null) { | |
this.pushBack = true; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.lex; | |
/** | |
* Created by glennhealy on 28/02/2016. | |
*/ | |
public class tokenizerTest { | |
public static void main(String[] args) { | |
String code = | |
"class HelloWorld\n" + | |
"method main requires()\n" + | |
"print \"hello\"" | |
; | |
Tokenizer tokenizer = new Tokenizer(code); | |
while (tokenizer.hasNextToken()) { | |
System.out.println(tokenizer.nextTok().getToken()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.lex; | |
/** | |
* Created by glennhealy on 28/02/2016. | |
*/ | |
public enum TokType { | |
EMPTY, //this is empty, absolutly nothing. | |
TOKEN, //this repersents a token e.g. (), =, */, ", +, -" | |
IDENTIFIER, // if first character is a letter, any proceeding characters are letters or numbers | |
INTEGER_LITERAL, //a number like 0, 1,2,3,4,5 etc. | |
FLOAT_LITERAL, // a IEEE floating point number such as 0.1, 0.02 or -1, -0.1, infinity, -infinity and NaN. | |
STRING_LITERAL, // anything encloses in double quotes "" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
/** | |
* Created by glennhealy on 02/03/2016. | |
*/ | |
public interface Type { | |
public static Type match(String str) { | |
try { | |
return BuiltInType.valueOf(str.toUpperCase()); | |
} | |
catch (Exception e) { | |
// TODO: Match str to a class. | |
return null; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
/** | |
* represents a value for a variable type. | |
*/ | |
public class Value { | |
private Type type; | |
private Object value; | |
public Value(Type type, Object value) { | |
this.type = type; | |
this.value = value; | |
} | |
public Type getType() { | |
return type; | |
} | |
public Object getValue() { | |
return value; | |
} | |
public void setValue(Object value) { | |
this.value = value; | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh; | |
import glenn.compiler.gh.block.Blk; | |
/** | |
* Created by glennhealy on 02/03/2016. | |
*/ | |
public class Variable extends Value { | |
private Blk blk; | |
private String name; | |
public Variable(Blk blk, Type type, String name, Object value) { | |
super(type, value); | |
this.blk = blk; | |
this.name = name; | |
} | |
public Blk getBlk() { | |
return blk; | |
} | |
public String getName() { | |
return name; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class variables | |
method main requires() returns void | |
var string str = getString() | |
printString(str) | |
method printString requires(string str) returns void | |
print str | |
method getString requires () returns string | |
return str() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package glenn.compiler.gh.parser; | |
//import Type; | |
//import Variable; | |
import glenn.compiler.gh.block.Blk; | |
import glenn.compiler.gh.block.VariableBlk; | |
import glenn.compiler.gh.lex.Tok; | |
import glenn.compiler.gh.lex.TokType; | |
import glenn.compiler.gh.lex.Tokenizer; | |
/** | |
* Created by glennhealy on 02/03/2016. | |
*/public class VarPars extends Parser<Blk> { | |
@Override | |
public boolean shouldParse(String line) { | |
return line.matches("var [a-zA-Z]+ [a-zA-Z]+ = (\")?[a-zA-Z0-9]*(\")?"); | |
} | |
@Override | |
public Blk parse(Blk superBlk, Tokenizer tokenizer) { | |
tokenizer.nextTok(); // Skip the var token. | |
String type = tokenizer.nextTok().getToken(); | |
String name = tokenizer.nextTok().getToken(); | |
tokenizer.nextTok(); // Skip the = token. | |
Tok v = tokenizer.nextTok(); | |
Object value = null; | |
if (v.getType() == TokType.INTEGER_LITERAL) { | |
value = Integer.valueOf(v.getToken()); | |
} | |
else if (v.getType() == TokType.FLOAT_LITERAL) { | |
value = Float.valueOf(v.getToken()); //token type check float | |
} | |
else if (v.getType() == TokType.STRING_LITERAL) { | |
value = v.getToken(); | |
} | |
else /* if the token is a veriable itendifier */ { | |
value = superBlk.getVariable(v.getToken()).getValue(); | |
} | |
return new VariableBlk(superBlk, type, name, value); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment