ParsedTokenConsumer interface

Пакет: com.hypixel.hytale.server.npc.util.expression.compile

Файл: com/hypixel/hytale/server/npc/util/expression/compile/Parser.java

Методы (5)

МодификаторыВозвратСигнатура
abstract void donevoid done()
abstract void processFunctionvoid processFunction(int var1)
abstract void processOperatorvoid processOperator(Parser.ParsedToken var1)
abstract void processTuplevoid processTuple(Parser.ParsedToken var1, int var2)
abstract void pushOperandvoid pushOperand(Parser.ParsedToken var1)

Исходный код

Показать/скрыть
class="kw">package com.hypixel.hytale.server.npc.util.expression.compile;

class="kw">import java.text.ParseException;
class="kw">import java.util.ArrayDeque;
class="kw">import java.util.Deque;
class="kw">import java.util.EnumSet;
class="kw">import javax.annotation.Nonnull;
class="kw">import javax.annotation.Nullable;

class="kw">public class Parser {
   class="kw">public class="kw">static class="kw">final String MISMATCHED_CLOSING_BRACKET = "Mismatched closing bracket";
   class="kw">public class="kw">static class="kw">final String TOO_MANY_OPERANDS = "Too many operands";
   class="kw">public class="kw">static class="kw">final String NOT_ENOUGH_OPERANDS = "Not enough operands";
   class="kw">public class="kw">static class="kw">final String EXPECTED_UNARY_OPERATOR = "Expected unary operator";
   class="kw">public class="kw">static class="kw">final String EXPECTED_BINARY_OPERATOR = "Expected binary operator";
   class="kw">public class="kw">static class="kw">final String MISSING_CLOSING_BRACKET = "Missing closing bracket";
   class="kw">public class="kw">static class="kw">final String ILLEGAL_USE_OF_ARGUMENT_LIST = "Illegal use of argument list";
   class="kw">private Lexer<Token> lexer;
   class="kw">private LexerContext<Token> context;
   @Nonnull
   class="kw">private Deque<Parser.ParsedToken> operatorStack = new ArrayDeque<>();
   @Nonnull
   class="kw">private Deque<Parser.ParsedToken> bracketStack = new ArrayDeque<>();

   class="kw">public Parser(Lexer<Token> var1) {
      this.lexer = var1;
      this.context = new LexerContext<>();
   }

   @Nonnull
   class="kw">private Parser.ParsedToken nextToken() class="kw">throws ParseException {
      class="kw">return Parser.ParsedToken.fromLexer(this.lexer, this.context);
   }

   class="kw">public void parse(@Nonnull String var1, @Nonnull Parser.ParsedTokenConsumer var2) class="kw">throws ParseException {
      this.operatorStack.clear();
      this.bracketStack.clear();
      this.bracketStack.push(new Parser.ParsedToken(Token.END));
      this.context.init(var1);
      Parser.ParsedToken var3 = this.nextToken();
      Token var4 = var3.token;
      Token var5 = null;
      Parser.ParsedToken var6 = this.bracketStack.peek();

      while (!var4.isEndToken()) {
         if (var4.isOperand()) {
            var2.pushOperand(var3);
            var6.operandCount++;
         } else if (var4.isOpenBracket()) {
            if (var4 == Token.OPEN_BRACKET) {
               if (var5 == Token.IDENTIFIER) {
                  var3.isTuple = true;
                  var3.isFunctionCall = true;
               }
            } else if (var4.isOpenTuple()) {
               var3.isTuple = true;
               var3.isFunctionCall = false;
            }

            this.operatorStack.push(var3);
            this.bracketStack.push(var3);
            var6 = this.bracketStack.peek();
         } else if (var4.isCloseBracket()) {
            Token var12 = var4.getMatchingBracket();
            if (var6.token != var12) {
               throw new ParseException("Mismatched closing bracket", var3.tokenPosition);
            }

            for (Parser.ParsedToken var13 = this.operatorStack.pop(); !var13.token.isOpenBracket(); var13 = this.operatorStack.pop()) {
               var6.operandCount = this.adjustOperandCount(var13, var6.operandCount);
               var2.processOperator(var13);
            }

            this.validateOperandCount(var6);
            int var9;
            if (var6.isFunctionCall) {
               var6.tupleLength = var6.tupleLength + var6.operandCount;
               var2.processFunction(var6.tupleLength);
               var9 = 0;
            } else if (var6.isTuple) {
               var6.tupleLength = var6.tupleLength + var6.operandCount;
               var2.processTuple(var6, var6.tupleLength);
               var9 = 1;
            } else {
               var9 = 1;
            }

            this.bracketStack.pop();
            var6 = this.bracketStack.peek();
            var6.operandCount += var9;
         } else if (var4.isList()) {
            if (!var6.isTuple) {
               throw new ParseException("Illegal use of argument list", var3.tokenPosition);
            }

            for (Parser.ParsedToken var11 = this.peekOperator(); !var11.token.isOpenBracket(); var11 = this.peekOperator()) {
               var6.operandCount = this.adjustOperandCount(var11, var6.operandCount);
               var2.processOperator(var11);
               this.operatorStack.pop();
            }

            this.validateOperandCount(var6);
            var6.tupleLength++;
            var6.operandCount = 0;
         } else {
            if (!var4.isOperator()) {
               throw new RuntimeException("Internal parser error: " + var4);
            }

            boolean var7 = var5 == null || var5.containsAnyFlag(EnumSet.of(TokenFlags.OPERATOR, TokenFlags.LIST, TokenFlags.OPENING_BRACKET));
            if (var4.canBeUnary() && var7) {
               var4 = var4.getUnaryVariant();
               var3.token = var4;
            } else {
               if (var7 && !var4.isUnary()) {
                  throw new ParseException("Expected unary operator", var3.tokenPosition);
               }

               if (var4.isUnary() && !var7) {
                  throw new ParseException("Expected binary operator", var3.tokenPosition);
               }
            }

            for (Parser.ParsedToken var8 = this.peekOperator(); this.hasLowerPrecedence(var4, var8); var8 = this.peekOperator()) {
               var6.operandCount = this.adjustOperandCount(var8, var6.operandCount);
               var2.processOperator(var8);
               this.operatorStack.pop();
            }

            this.operatorStack.push(var3);
         }

         var5 = var4;
         var3 = this.nextToken();
         var4 = var3.token;
      }

      if (var6.token != Token.END) {
         throw new ParseException("Missing closing bracket", var6.tokenPosition);
      }

      while (!this.operatorStack.isEmpty()) {
         var3 = this.operatorStack.pop();
         var6.operandCount = this.adjustOperandCount(var3, var6.operandCount);
         var2.processOperator(var3);
      }

      this.validateOperandCount(var6);
      var2.done();
   }

   @Nullable
   class="kw">public Parser.ParsedToken peekOperator() {
      class="kw">return this.operatorStack.isEmpty() ? null : this.operatorStack.peek();
   }

   class="kw">private void validateOperandCount(@Nonnull Parser.ParsedToken var1) class="kw">throws ParseException {
      if (!var1.isTuple || var1.tupleLength != 0 || var1.operandCount != 0) {
         if (var1.operandCount <= 0) {
            throw new ParseException("Not enough operands", 0);
         }

         if (var1.operandCount > 1) {
            throw new ParseException("Too many operands", 0);
         }
      }
   }

   class="kw">private int adjustOperandCount(@Nonnull Parser.ParsedToken var1, int var2) class="kw">throws ParseException {
      int var3 = this.arity(var1.token);
      if (var2 < var3) {
         throw new ParseException("Not enough operands", var1.tokenPosition);
      } else {
         class="kw">return var2 - var3 + 1;
      }
   }

   class="kw">private boolean hasLowerPrecedence(@Nonnull Token var1, @Nullable Parser.ParsedToken var2) {
      if (var2 != null && !var2.token.isList() && !var2.token.isOpenBracket()) {
         int var3 = var1.getPrecedence();
         int var4 = var2.token.getPrecedence();
         class="kw">return var3 == var4 ? !var1.isRightToLeft() : var3 < var4;
      } else {
         class="kw">return false;
      }
   }

   class="kw">private int arity(@Nonnull Token var1) {
      if (!var1.isOperator()) {
         throw new RuntimeException("Arity only possible with operators");
      } else {
         class="kw">return var1.isUnary() ? 1 : 2;
      }
   }

   class="kw">public class="kw">static class ParsedToken {
      @Nullable
      class="kw">public Token token;
      @Nullable
      class="kw">public String tokenString;
      class="kw">public double tokenNumber;
      class="kw">public int tokenPosition;
      class="kw">public int operandCount;
      class="kw">public boolean isTuple;
      class="kw">public boolean isFunctionCall;
      class="kw">public int tupleLength;

      class="kw">public ParsedToken(@Nonnull LexerContext<Token> var1) {
         this(var1.getToken());
         this.tokenString = var1.getTokenString();
         this.tokenNumber = var1.getTokenNumber();
         this.tokenPosition = var1.getTokenPosition();
      }

      class="kw">public ParsedToken(Token var1) {
         this.token = var1;
         this.tokenString = null;
         this.tokenNumber = 0.0;
         this.tokenPosition = 0;
         this.operandCount = 0;
         this.isTuple = false;
         this.isFunctionCall = false;
         this.tupleLength = 0;
      }

      @Nonnull
      class="kw">static Parser.ParsedToken fromLexer(@Nonnull Lexer<Token> var0, @Nonnull LexerContext<Token> var1) class="kw">throws ParseException {
         var0.nextToken(var1);
         class="kw">return new Parser.ParsedToken(var1);
      }
   }

   class="kw">public class="kw">interface ParsedTokenConsumer {
      void pushOperand(Parser.ParsedToken var1);

      void processOperator(Parser.ParsedToken var1) class="kw">throws ParseException;

      void processFunction(int var1) class="kw">throws ParseException;

      void processTuple(Parser.ParsedToken var1, int var2);

      void done();
   }
}