Class BaseParser

java.lang.Object
io.karatelabs.parser.BaseParser
Direct Known Subclasses:
JsParser

public abstract class BaseParser extends Object
  • Field Details

    • resource

      protected final Resource resource
    • tokens

      protected final List<Token> tokens
    • errorRecoveryEnabled

      protected final boolean errorRecoveryEnabled
  • Constructor Details

    • BaseParser

      protected BaseParser(Resource resource, List<Token> tokens, boolean errorRecovery)
  • Method Details

    • markerNode

      protected Node markerNode()
    • isCallerType

      protected boolean isCallerType(NodeType type)
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • error

      protected void error(String message)
    • error

      protected void error(NodeType... expected)
    • error

      protected void error(TokenType... expected)
    • getErrors

      public List<SyntaxError> getErrors()
      Returns:
      list of syntax errors collected during parsing
    • hasErrors

      public boolean hasErrors()
      Returns:
      true if any syntax errors were recorded
    • recoverTo

      protected boolean recoverTo(TokenType... recoveryTokens)
      Skip tokens until we find a recovery point. Includes infinite loop detection - if called from the same position twice, forces skip of at least one token to guarantee progress.
      Parameters:
      recoveryTokens - tokens that indicate a safe recovery point
      Returns:
      true if a recovery token was found, false if EOF reached
    • consumeSoft

      protected boolean consumeSoft(TokenType token)
      Consume token if present, or record error if in recovery mode.
      Parameters:
      token - the expected token type
      Returns:
      true if consumed successfully or in recovery mode
    • exitSoft

      protected boolean exitSoft()
      Exit that tolerates incomplete nodes. Even if the node is incomplete, it is added to the parent.
    • enter

      protected void enter(NodeType type)
    • enter

      protected boolean enter(NodeType type, TokenType token)
    • enter

      protected boolean enter(NodeType type, TokenType[] tokens)
    • enterIf

      protected boolean enterIf(NodeType type, TokenType[] tokens)
    • enter

      protected boolean enter(NodeType type, EnumSet<TokenType> tokens)
    • enterIf

      protected boolean enterIf(NodeType type, EnumSet<TokenType> tokens)
    • exit

      protected boolean exit()
    • exit

      protected boolean exit(boolean result, boolean mandatory)
    • exit

      protected void exit(BaseParser.Shift shift)
    • peek

      protected TokenType peek()
    • peekToken

      protected Token peekToken()
    • consume

      protected void consume(TokenType token)
    • anyOf

      protected boolean anyOf(TokenType[] tokens)
    • anyOf

      protected boolean anyOf(EnumSet<TokenType> tokens)
    • consumeIf

      protected boolean consumeIf(TokenType token)
    • peekIf

      protected boolean peekIf(TokenType token)
    • peekAnyOf

      protected boolean peekAnyOf(TokenType[] tokens)
    • peekAnyOf

      protected boolean peekAnyOf(EnumSet<TokenType> tokens)
    • lastConsumed

      protected TokenType lastConsumed()
    • lastConsumedText

      protected String lastConsumedText()
    • noLineTerminatorBefore

      protected boolean noLineTerminatorBefore()
      Is there no LineTerminator between the token just consumed and the next one?

      What the ECMAScript grammar's restricted productions need: in a handful of places a LineTerminator is not whitespace, it ends the statement. Without the check, return followed by a newline and a call swallows the call as its argument — which parses fine and means something else.

      Which productions actually consult this today: return, throw, and break/continue before a label. The grammar also restricts yield before its operand and a postfix ++/-- after its operand; neither is enforced here — the postfix case is a separate, unfixed gap. Do not read this javadoc as a claim that they are covered.

      Reusing it needs one caution. It measures the gap after the last token of the current node, so a caller whose preceding element is an expression rather than a keyword — the postfix case — gets the right token only because Node.getLastToken() recurses to it. And the scan start is clamped: Token.length is a short, so a token longer than 32767 characters reports a negative length (a limitation this engine already has in Token.getText()). The clamp makes that fail toward terminating the statement, which is the safe direction — the unsafe one is silently swallowing the next expression.

    • getPosition

      protected int getPosition()
    • consumeNext

      protected void consumeNext()
    • next

      protected Token next()