Skip to content

Commit

Permalink
Using typed tokens for knife grammar.
Browse files Browse the repository at this point in the history
Fixed missing production code NPE bug.
  • Loading branch information
ZeroBone committed Mar 28, 2020
1 parent 6dd6c83 commit e318cac
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 165 deletions.
131 changes: 73 additions & 58 deletions bootstrap/ParseNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
import net.zerobone.knife.ast.entities.ProductionStatementBody;
import net.zerobone.knife.ast.statements.ProductionStatementNode;
import net.zerobone.knife.ast.statements.StatementNode;
import net.zerobone.knife.ast.statements.TypeStatementNode;
import net.zerobone.knife.lexer.tokens.CodeToken;
import net.zerobone.knife.lexer.tokens.IdToken;
import net.zerobone.knife.utils.StringUtils;

import java.lang.Object;
import java.util.ArrayList;

final class ParseNode {
Expand All @@ -27,77 +30,89 @@ void reduce() {
Object v;
switch (actionId - 1) {
case 0:
{
v = new TranslationUnitNode();
}
break;
{
v = new TranslationUnitNode();
}
break;
case 1:
{
StatementNode s = (StatementNode) ((ParseNode)children.get(1)).payload;
TranslationUnitNode t = (TranslationUnitNode) ((ParseNode)children.get(0)).payload;
t.addStatement(s); v = t;
}
break;
{
StatementNode s = (StatementNode)((ParseNode)children.get(1)).payload;
TranslationUnitNode t = (TranslationUnitNode)((ParseNode)children.get(0)).payload;
t.addStatement(s); v = t;
}
break;
case 2:
{
Object s = ((ParseNode)children.get(0)).payload;
v = s;
}
break;
{
IdToken nonTerminal = (IdToken)((ParseNode)children.get(2)).payload;
ProductionStatementBody body = (ProductionStatementBody)((ParseNode)children.get(0)).payload;
v = new ProductionStatementNode(nonTerminal.id, body.getProduction(), body.getCode());
}
break;
case 3:
{
IdToken nonTerminal = (IdToken) ((ParseNode)children.get(2)).payload;
ProductionStatementBody body = (ProductionStatementBody) ((ParseNode)children.get(0)).payload;
v = new ProductionStatementNode(nonTerminal.identifier, body.getProduction(), body.getCode());
}
break;
{
IdToken symbol = (IdToken)((ParseNode)children.get(1)).payload;
IdToken type = (IdToken)((ParseNode)children.get(0)).payload;
v = new TypeStatementNode(symbol.id, type.id);
}
break;
case 4:
{
CodeToken code = (CodeToken) ((ParseNode)children.get(0)).payload;
v = new ProductionStatementBody(code.code);
}
break;
{
CodeToken code = (CodeToken)((ParseNode)children.get(0)).payload;
v = new ProductionStatementBody(code == null ? null : code.code);
}
break;
case 5:
{
IdToken s = (IdToken) ((ParseNode)children.get(2)).payload;
IdToken arg = (IdToken) ((ParseNode)children.get(1)).payload;
ProductionStatementBody b = (ProductionStatementBody) ((ParseNode)children.get(0)).payload;
char firstChar = s.identifier.charAt(0);
if (Character.isUpperCase(firstChar))
if (arg == null) b.addTerminal(s.identifier);
else b.addTerminal(s.identifier, arg.identifier);
else
if (arg == null) b.addNonTerminal(s.identifier);
else b.addNonTerminal(s.identifier, arg.identifier);
v = b;
{
IdToken s = (IdToken)((ParseNode)children.get(2)).payload;
IdToken arg = (IdToken)((ParseNode)children.get(1)).payload;
ProductionStatementBody b = (ProductionStatementBody)((ParseNode)children.get(0)).payload;

if (StringUtils.isTerminal(s.id)) {
if (arg == null) {
b.addTerminal(s.id);
}
else {
b.addTerminal(s.id, arg.id);
}
}
break;
case 6:
{
v = null;
else {
if (arg == null) {
b.addNonTerminal(s.id);
}
else {
b.addNonTerminal(s.id, arg.id);
}
}
break;
v = b;

}
break;
case 6:
{
v = null;
}
break;
case 7:
{
Object c = ((ParseNode)children.get(0)).payload;
v = c;
}
break;
{
Object c = (Object)((ParseNode)children.get(0)).payload;
v = c;
}
break;
case 8:
{
v = null;
}
break;
{
v = null;
}
break;
case 9:
{
Object arg = ((ParseNode)children.get(1)).payload;
v = arg;
}
break;
{
IdToken arg = (IdToken)((ParseNode)children.get(1)).payload;
v = arg;
}
break;
default:
throw new IllegalStateException();
}
payload = v;
children = null;
}
}
}
28 changes: 15 additions & 13 deletions bootstrap/Parser.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package net.zerobone.knife.parser;

import java.lang.Object;
import java.util.Stack;

public final class Parser {
Expand All @@ -17,27 +18,28 @@ public final class Parser {

public static final int T_LEFT_PAREN = 5;

private static final int terminalCount = 7;
public static final int T_TYPE = 7;

private static final int nonTerminalCount = 6;
private static final int terminalCount = 8;

private static final int nonTerminalCount = 5;

private static final int startSymbol = -1;

private static final int[] table = {
1,2,0,0,0,0,0,
0,3,0,0,0,0,0,
0,4,0,0,0,0,0,
0,6,0,5,0,0,0,
7,7,0,0,8,0,0,
0,9,0,9,0,10,0};
1,2,0,0,0,0,0,2,
0,3,0,0,0,0,0,4,
0,6,0,5,0,0,0,0,
7,7,0,0,8,0,0,7,
0,9,0,9,0,10,0,0};

private static final int[][] actionTable = {
{},
{-2,-1},
{-3},
{1,2,-4},
{3,-5},
{1,-6,-4},
{1,2,-3},
{7,1,1},
{3,-4},
{1,-5,-3},
{},
{4},
{},
Expand Down Expand Up @@ -78,7 +80,7 @@ public void parse(int tokenId, Object token) {
}
int actionId = table[(-prevRoot.symbolId - 1) * terminalCount + tokenId];
if (actionId == 0) {
throw new RuntimeException("Syntax error. Non-terminal: " + (-prevRoot.symbolId - 1) + " Token: " + token);
throw new RuntimeException("Syntax error. Token: " + token);
}
int[] action = actionTable[actionId - 1];
prevRoot.actionId = actionId;
Expand Down
8 changes: 4 additions & 4 deletions run/ParseNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,20 @@ void reduce() {
{
IdToken nonTerminal = (IdToken)((ParseNode)children.get(2)).payload;
ProductionStatementBody body = (ProductionStatementBody)((ParseNode)children.get(0)).payload;
v = new ProductionStatementNode(nonTerminal, body.getProduction(), body.getCode());
v = new ProductionStatementNode(nonTerminal.id, body.getProduction(), body.getCode());
}
break;
case 3:
{
IdToken symbol = (IdToken)((ParseNode)children.get(1)).payload;
IdToken type = (IdToken)((ParseNode)children.get(0)).payload;
v = new TypeStatementNode(symbol, type);
v = new TypeStatementNode(symbol.id, type.id);
}
break;
case 4:
{
IdToken code = (IdToken)((ParseNode)children.get(0)).payload;
v = new ProductionStatementBody(code);
CodeToken code = (CodeToken)((ParseNode)children.get(0)).payload;
v = new ProductionStatementBody(code == null ? null : code.code);
}
break;
case 5:
Expand Down
8 changes: 4 additions & 4 deletions run/knife.kn
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ translationUnit = statement(s) translationUnit(t); { t.addStatement(s); v = t; }
%type statement StatementNode

// production statement
statement = ID(nonTerminal) ASSIGN productionStatementBody(body); { v = new ProductionStatementNode(nonTerminal, body.getProduction(), body.getCode()); }
statement = ID(nonTerminal) ASSIGN productionStatementBody(body); { v = new ProductionStatementNode(nonTerminal.id, body.getProduction(), body.getCode()); }

%type productionStatementBody ProductionStatementBody
productionStatementBody = SEMICOLON productionStatementCode(code); { v = new ProductionStatementBody(code); }
productionStatementBody = SEMICOLON productionStatementCode(code); { v = new ProductionStatementBody(code == null ? null : code.code); }
productionStatementBody = ID(s) productionStatementArgument(arg) productionStatementBody(b); {
if (StringUtils.isTerminal(s.id)) {
if (arg == null) {
Expand All @@ -35,7 +35,7 @@ productionStatementBody = ID(s) productionStatementArgument(arg) productionState
v = b;
}

%type productionStatementCode IdToken
%type productionStatementCode CodeToken
productionStatementCode = ; { v = null; }
productionStatementCode = CODE(c); { v = c; }

Expand All @@ -44,4 +44,4 @@ productionStatementArgument = ; { v = null; }
productionStatementArgument = LEFT_PAREN ID(arg) RIGHT_PAREN; { v = arg; }

// type statement
statement = TYPE ID(symbol) ID(type); { v = new TypeStatementNode(symbol, type); }
statement = TYPE ID(symbol) ID(type); { v = new TypeStatementNode(symbol.id, type.id); }
Loading

0 comments on commit e318cac

Please sign in to comment.