diff options
| author | dibyendumajumdar <mobile@majumdar.org.uk> | 2023-08-26 15:39:13 +0100 |
|---|---|---|
| committer | dibyendumajumdar <mobile@majumdar.org.uk> | 2023-08-26 15:39:13 +0100 |
| commit | 867405ea40d3c8acd93e5e0e6030e8ad96eb2470 (patch) | |
| tree | ada2570ba653c8c4557713949232f466266ce7f7 /chapter01/src/main/java | |
| parent | 3b07be6d2c30f7539c5e71964c7a1e4c6790f91f (diff) | |
| download | Simple-867405ea40d3c8acd93e5e0e6030e8ad96eb2470.tar.gz Simple-867405ea40d3c8acd93e5e0e6030e8ad96eb2470.zip | |
Avoid using Node as a type as the IR will need this
So just extends the top level Ast class in all the subtypes.
Also avoid holding reference to lexer in parser.
Diffstat (limited to 'chapter01/src/main/java')
| -rw-r--r-- | chapter01/src/main/java/com/seaofnodes/simple/parser/Ast.java | 10 | ||||
| -rw-r--r-- | chapter01/src/main/java/com/seaofnodes/simple/parser/Parser.java | 239 |
2 files changed, 124 insertions, 125 deletions
diff --git a/chapter01/src/main/java/com/seaofnodes/simple/parser/Ast.java b/chapter01/src/main/java/com/seaofnodes/simple/parser/Ast.java index b11d1ddb..51c7b7ac 100644 --- a/chapter01/src/main/java/com/seaofnodes/simple/parser/Ast.java +++ b/chapter01/src/main/java/com/seaofnodes/simple/parser/Ast.java @@ -27,13 +27,11 @@ import java.util.stream.Collectors; */ public class Ast { - private Ast() { + protected Ast() { } - public interface Node { - } - public abstract static class Expr implements Node { + public abstract static class Expr extends Ast { public final Token op; protected Expr(Token op) { @@ -116,7 +114,7 @@ public class Ast { } } - public abstract static class Statement implements Node { + public abstract static class Statement extends Ast { } public static class IfElse extends Statement { @@ -175,7 +173,7 @@ public class Ast { } } - public static class Type implements Node { + public static class Type extends Ast { public final Token.Id typeId; public Type(Token.Id typeId) { diff --git a/chapter01/src/main/java/com/seaofnodes/simple/parser/Parser.java b/chapter01/src/main/java/com/seaofnodes/simple/parser/Parser.java index 263d0b41..fe224105 100644 --- a/chapter01/src/main/java/com/seaofnodes/simple/parser/Parser.java +++ b/chapter01/src/main/java/com/seaofnodes/simple/parser/Parser.java @@ -22,53 +22,54 @@ import com.seaofnodes.simple.lexer.ecstasy.Token; import com.seaofnodes.simple.lexer.ecstasy.Severity; public class Parser { - final Lexer lexer; - Token look; + private Token currentToken; - public Parser(Lexer lexer) { - this.lexer = lexer; + /** + * Parse and return a top level Ast + * At present this is an Ast.Block + * @see Ast.Block + */ + public Ast parse(Lexer lexer) { + nextToken(lexer); + return parseProgram(lexer); } - private Token nextOrEof() { + private Token nextOrEof(Lexer lexer) { if (lexer.hasNext()) return lexer.next(); - return new Token(look.getStartPosition(), look.getEndPosition(), Token.Id.EOF); + return new Token(currentToken.getStartPosition(), currentToken.getEndPosition(), Token.Id.EOF); } - private void nextToken() { - look = nextOrEof(); + private void nextToken(Lexer lexer) { + currentToken = nextOrEof(lexer); // skip comments - while (look.isComment()) { - look = nextOrEof(); + while (currentToken.isComment()) { + currentToken = nextOrEof(lexer); } - if (look.isContextSensitive() && - look.getId() == Token.Id.IDENTIFIER) { - look = look.convertToKeyword(); + if (currentToken.isContextSensitive() && + currentToken.getId() == Token.Id.IDENTIFIER) { + currentToken = currentToken.convertToKeyword(); } } - private void error(Token t, String errorMessage) { + private void error(Lexer lexer, Token t, String errorMessage) { lexer.log(Severity.ERROR, errorMessage, t.getStartPosition(), t.getEndPosition()); throw new CompilerException(errorMessage + ": " + t.toDebugString()); } - private void match(Token.Id tag) { - if (look.getId() == tag) { - nextToken(); + private void match(Lexer lexer, Token.Id tag) { + if (currentToken.getId() == tag) { + nextToken(lexer); } else { - error(look, "syntax error, expected " + tag); + error(lexer, currentToken, "syntax error, expected " + tag); } } - public Ast.Node parse() { - nextToken(); - return parseProgram(); - } - private Ast.Statement parseProgram() { + private Ast.Statement parseProgram(Lexer lexer) { var block = new Ast.Block(); - parseDeclarations(block); - parseStatements(block); + parseDeclarations(lexer, block); + parseStatements(lexer, block); return block; } @@ -79,172 +80,172 @@ public class Parser { }; } - private void parseDeclarations(Ast.Block block) { - while (isTypeName(look)) { - var type = new Ast.Type(look.getId()); - nextToken(); - var tok = look; - match(Token.Id.IDENTIFIER); - match(Token.Id.SEMICOLON); + private void parseDeclarations(Lexer lexer, Ast.Block block) { + while (isTypeName(currentToken)) { + var type = new Ast.Type(currentToken.getId()); + nextToken(lexer); + var tok = currentToken; + match(lexer, Token.Id.IDENTIFIER); + match(lexer, Token.Id.SEMICOLON); var identifier = new Ast.Identifier(tok); block.stmtList.add(new Ast.Declare(type, identifier)); } } - private void parseStatements(Ast.Block block) { - while (look.getId() != Token.Id.EOF && - look.getId() != Token.Id.R_CURLY) { - block.stmtList.add(parseStatement()); + private void parseStatements(Lexer lexer, Ast.Block block) { + while (currentToken.getId() != Token.Id.EOF && + currentToken.getId() != Token.Id.R_CURLY) { + block.stmtList.add(parseStatement(lexer)); } } - private Ast.Statement parseStatement() { + private Ast.Statement parseStatement(Lexer lexer) { Ast.Expr x; Ast.Statement s1; Ast.Statement s2; - switch (look.getId()) { + switch (currentToken.getId()) { case IF -> { - match(Token.Id.IF); - match(Token.Id.L_PAREN); - x = parseBool(); - match(Token.Id.R_PAREN); - s1 = parseStatement(); - if (look.getId() != Token.Id.ELSE) { + match(lexer, Token.Id.IF); + match(lexer, Token.Id.L_PAREN); + x = parseBool(lexer); + match(lexer, Token.Id.R_PAREN); + s1 = parseStatement(lexer); + if (currentToken.getId() != Token.Id.ELSE) { return new Ast.IfElse(x, s1, null); } - s2 = parseStatement(); + s2 = parseStatement(lexer); return new Ast.IfElse(x, s1, s2); } case WHILE -> { - match(Token.Id.WHILE); - match(Token.Id.L_PAREN); - x = parseBool(); - match(Token.Id.R_PAREN); - s1 = parseStatement(); + match(lexer, Token.Id.WHILE); + match(lexer, Token.Id.L_PAREN); + x = parseBool(lexer); + match(lexer, Token.Id.R_PAREN); + s1 = parseStatement(lexer); return new Ast.While(x, s1); } case BREAK -> { - match(Token.Id.BREAK); - match(Token.Id.SEMICOLON); + match(lexer, Token.Id.BREAK); + match(lexer, Token.Id.SEMICOLON); return new Ast.Break(); } case L_CURLY -> { - return parseBlock(); + return parseBlock(lexer); } default -> { - return parseAssign(); + return parseAssign(lexer); } } } - private Ast.Statement parseBlock() { - match(Token.Id.L_CURLY); + private Ast.Statement parseBlock(Lexer lexer) { + match(lexer, Token.Id.L_CURLY); var block = new Ast.Block(); - parseDeclarations(block); - parseStatements(block); - match(Token.Id.R_CURLY); + parseDeclarations(lexer, block); + parseStatements(lexer, block); + match(lexer, Token.Id.R_CURLY); return block; } - private Ast.Statement parseAssign() { - Token tok = look; - match(Token.Id.IDENTIFIER); + private Ast.Statement parseAssign(Lexer lexer) { + Token tok = currentToken; + match(lexer, Token.Id.IDENTIFIER); Ast.Identifier identifier = new Ast.Identifier(tok); - match(Token.Id.ASN); - var s = new Ast.Assign(identifier, parseBool()); - match(Token.Id.SEMICOLON); + match(lexer, Token.Id.ASN); + var s = new Ast.Assign(identifier, parseBool(lexer)); + match(lexer, Token.Id.SEMICOLON); return s; } - private Ast.Expr parseBool() { - var x = parseAnd(); - while (look.getId() == Token.Id.COND_OR) { - var tok = look; - nextToken(); - x = new Ast.Binary(tok, x, parseAnd()); + private Ast.Expr parseBool(Lexer lexer) { + var x = parseAnd(lexer); + while (currentToken.getId() == Token.Id.COND_OR) { + var tok = currentToken; + nextToken(lexer); + x = new Ast.Binary(tok, x, parseAnd(lexer)); } return x; } - private Ast.Expr parseAnd() { - var x = parseRelational(); - while (look.getId() == Token.Id.COND_AND) { - var tok = look; - nextToken(); - x = new Ast.Binary(tok, x, parseRelational()); + private Ast.Expr parseAnd(Lexer lexer) { + var x = parseRelational(lexer); + while (currentToken.getId() == Token.Id.COND_AND) { + var tok = currentToken; + nextToken(lexer); + x = new Ast.Binary(tok, x, parseRelational(lexer)); } return x; } - private Ast.Expr parseRelational() { - var x = parseAddition(); - while (look.getId() == Token.Id.COMP_EQ || - look.getId() == Token.Id.COMP_NEQ || - look.getId() == Token.Id.COMP_LT || - look.getId() == Token.Id.COMP_GT || - look.getId() == Token.Id.COMP_GTEQ || - look.getId() == Token.Id.COMP_LTEQ) { - var tok = look; - nextToken(); - x = new Ast.Binary(tok, x, parseAddition()); + private Ast.Expr parseRelational(Lexer lexer) { + var x = parseAddition(lexer); + while (currentToken.getId() == Token.Id.COMP_EQ || + currentToken.getId() == Token.Id.COMP_NEQ || + currentToken.getId() == Token.Id.COMP_LT || + currentToken.getId() == Token.Id.COMP_GT || + currentToken.getId() == Token.Id.COMP_GTEQ || + currentToken.getId() == Token.Id.COMP_LTEQ) { + var tok = currentToken; + nextToken(lexer); + x = new Ast.Binary(tok, x, parseAddition(lexer)); } return x; } - private Ast.Expr parseAddition() { - var x = parseMultiplication(); - while (look.getId() == Token.Id.ADD || - look.getId() == Token.Id.SUB) { - var tok = look; - nextToken(); - x = new Ast.Binary(tok, x, parseMultiplication()); + private Ast.Expr parseAddition(Lexer lexer) { + var x = parseMultiplication(lexer); + while (currentToken.getId() == Token.Id.ADD || + currentToken.getId() == Token.Id.SUB) { + var tok = currentToken; + nextToken(lexer); + x = new Ast.Binary(tok, x, parseMultiplication(lexer)); } return x; } - private Ast.Expr parseMultiplication() { - var x = parseUnary(); - while (look.getId() == Token.Id.MUL || - look.getId() == Token.Id.DIV) { - var tok = look; - nextToken(); - x = new Ast.Binary(tok, x, parseUnary()); + private Ast.Expr parseMultiplication(Lexer lexer) { + var x = parseUnary(lexer); + while (currentToken.getId() == Token.Id.MUL || + currentToken.getId() == Token.Id.DIV) { + var tok = currentToken; + nextToken(lexer); + x = new Ast.Binary(tok, x, parseUnary(lexer)); } return x; } - private Ast.Expr parseUnary() { - if (look.getId() == Token.Id.SUB || - look.getId() == Token.Id.NOT) { - var tok = look; - nextToken(); - return new Ast.Unary(tok, parseUnary()); + private Ast.Expr parseUnary(Lexer lexer) { + if (currentToken.getId() == Token.Id.SUB || + currentToken.getId() == Token.Id.NOT) { + var tok = currentToken; + nextToken(lexer); + return new Ast.Unary(tok, parseUnary(lexer)); } else { - return parsePrimary(); + return parsePrimary(lexer); } } - private Ast.Expr parsePrimary() { - switch (look.getId()) { + private Ast.Expr parsePrimary(Lexer lexer) { + switch (currentToken.getId()) { case L_PAREN -> { - nextToken(); - var x = parseBool(); - match(Token.Id.R_PAREN); + nextToken(lexer); + var x = parseBool(lexer); + match(lexer, Token.Id.R_PAREN); return x; } case LIT_INT -> { - var x = new Ast.Constant(look); - nextToken(); + var x = new Ast.Constant(currentToken); + nextToken(lexer); return x; } case IDENTIFIER -> { - var x = new Ast.Symbol(look); - nextToken(); + var x = new Ast.Symbol(currentToken); + nextToken(lexer); return x; } default -> { - error(look, "syntax error, expected nested expr, integer value or variable"); + error(lexer, currentToken, "syntax error, expected nested expr, integer value or variable"); return null; } } |
