diff options
| author | bculkin2442 <bjculkin@mix.wvu.edu> | 2017-02-13 02:56:51 -0500 |
|---|---|---|
| committer | bculkin2442 <bjculkin@mix.wvu.edu> | 2017-02-13 02:56:51 -0500 |
| commit | c8bec56ce8bd384b31ab6025ba7d31c3dfb1b874 (patch) | |
| tree | 3d8e0e80e8bddce01bb4656a036df2b9eb71f3d1 /dice-lang/src/bjc/dicelang/v2/Shunter.java | |
| parent | 517b89b4aa936be1457bb26290b23369cbe4a9f1 (diff) | |
Lexer/shunter work
Diffstat (limited to 'dice-lang/src/bjc/dicelang/v2/Shunter.java')
| -rw-r--r-- | dice-lang/src/bjc/dicelang/v2/Shunter.java | 111 |
1 files changed, 108 insertions, 3 deletions
diff --git a/dice-lang/src/bjc/dicelang/v2/Shunter.java b/dice-lang/src/bjc/dicelang/v2/Shunter.java index bca08eb..3edceeb 100644 --- a/dice-lang/src/bjc/dicelang/v2/Shunter.java +++ b/dice-lang/src/bjc/dicelang/v2/Shunter.java @@ -5,7 +5,9 @@ import bjc.utils.funcdata.FunctionalMap; import bjc.utils.funcdata.IList; import bjc.utils.funcdata.IMap; +import java.util.Deque; import java.util.HashSet; +import java.util.LinkedList; import java.util.Set; import static bjc.dicelang.v2.Token.Type.*; @@ -42,18 +44,121 @@ public class Shunter { ops.put(DICEGROUP, 0 + DICE_PREC); ops.put(DICECONCAT, 1 + DICE_PREC); + ops.put(DICELIST, 2 + DICE_PREC); ops.put(LET, 0 + EXPR_PREC); ops.put(BIND, 1 + EXPR_PREC); } - public IList<Token> shuntTokens(IList<Token> tks) { - IList<Token> returned = new FunctionalList<>(); + public boolean shuntTokens(IList<Token> tks, IList<Token> returned) { + Deque<Token> opStack = new LinkedList<>(); + + boolean unaryMode = false; + Deque<Token> unaryOps = new LinkedList<>(); for(Token tk : tks.toIterable()) { + if(unaryMode) { + // @TODO finish unary mode + if(unaryAdjectives.contains(tk.type) || unaryAdverbs.contains(tk.type)) { + unaryOps.push(tk); + continue; + } + + Token currOperator = unaryOps.peek(); + + if(unaryAdjectives.contains(currOperator.type)) { + boolean isOp = ops.containsKey(tk.type) + || unaryAdverbs.contains(tk.type) + || unaryAdjectives.contains(tk.type); + + if(isOp) { + System.out.printf("\tError: Unary operator %s is an" + + " adjective, not an adverb (can't be applied" + + " to operator %s)\n", currOperator, tk ); + + return false; + } + + returned.add(tk); + returned.add(unaryOps.pop()); + } else if (unaryAdverbs.contains(currOperator.type)) { + if(opStack.size() < 1) { + System.out.printf("\tError: Unary operators %s is an adverb," + + " but there is no operator to apply it to\n"); + } + + Token currOperand = opStack.peek(); + + boolean isOp = ops.containsKey(currOperand.type) + || unaryAdverbs.contains(currOperand.type) + || unaryAdjectives.contains(currOperand.type); + + if(!isOp) { + System.out.printf("\tError: Unary operator %s is an adverb," + + " not an adjective (can't be applied to operand %s)\n", + currOperator, tk); + + return false; + } + + returned.add(tk); + returned.add(unaryOps.pop()); + } + + if(unaryOps.isEmpty()) unaryMode = false; + } else { + if(unaryAdjectives.contains(tk.type) || unaryAdverbs.contains(tk.type)) { + unaryMode = true; + + unaryOps.add(tk); + continue; + } else if(ops.containsKey(tk.type)) { + while(!opStack.isEmpty() + && isHigherPrec(tk.type, opStack.peek().type)) { + returned.add(opStack.pop()); + } + + opStack.push(tk); + } else if(tk.type == OPAREN) { + opStack.push(tk); + } else if(tk.type == CPAREN) { + Token currTk = opStack.peek(); + + while(currTk.type != OPAREN && currTk.intValue != tk.intValue) { + if(opStack.isEmpty()) { + System.out.printf("\tError: Could not find matching parenthesis" + + " with matching level %d", tk.intValue); + + return false; + } + + returned.add(opStack.pop()); + } + } else { + returned.add(tk); + } + } + } + + // Flush leftover operators + while(!opStack.isEmpty()) { + returned.add(opStack.pop()); + } + return true; + } + + private boolean isHigherPrec(Token.Type left, Token.Type right) { + boolean exists = ops.containsKey(right); + + // If it doesn't, the left is higher precedence. + if (!exists) { + return false; } - return returned; + int rightPrecedence = ops.get(right); + int leftPrecedence = ops.get(left); + + return rightPrecedence >= leftPrecedence; } } |
