All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.antlr.parser.antlr4.LexerAdaptor Maven / Gradle / Ivy

package org.antlr.parser.antlr4;

import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.misc.Interval;

public abstract class LexerAdaptor extends Lexer {
   /**
    * Track whether we are inside of a rule and whether it is lexical parser. currentRuleType==Token.INVALID_TYPE means that we are outside of a rule. At the first sign of a rule name reference and
    * currentRuleType==invalid, we can assume that we are starting a parser rule. Similarly, seeing a token reference when not already in rule means starting a token rule. The terminating ';' of a
    * rule, flips this back to invalid type. This is not perfect logic but works. For example, "grammar T;" means that we start and stop a lexical rule for the "T;". Dangerous but works. The whole
    * point of this state information is to distinguish between [..arg actions..] and [charsets]. Char sets can only occur in lexical rules and arg actions cannot occur.
    */
   private int currentRuleType = Token.INVALID_TYPE;

   public LexerAdaptor(CharStream input) {
      super(input);
   }

   @Override
   public Token emit() {
      if (_type == ANTLRv4Lexer.ID) {
         final String firstChar = _input.getText(Interval.of(_tokenStartCharIndex, _tokenStartCharIndex));
         if (Character.isUpperCase(firstChar.charAt(0))) {
            _type = ANTLRv4Lexer.TOKEN_REF;
         } else {
            _type = ANTLRv4Lexer.RULE_REF;
         }
         if (currentRuleType == Token.INVALID_TYPE) { // if outside of rule def
            currentRuleType = _type; // set to inside lexer or parser rule
         }
      } else if (_type == ANTLRv4Lexer.SEMI) { // exit rule def
         currentRuleType = Token.INVALID_TYPE;
      }
      return super.emit();
   }

   public int getCurrentRuleType() {
      return currentRuleType;
   }

   protected void handleBeginArgument() {
      if (inLexerRule()) {
         pushMode(ANTLRv4Lexer.LexerCharSet);
         more();
      } else {
         pushMode(ANTLRv4Lexer.Argument);
      }
   }

   protected void handleEndAction() {
      popMode();
      if (_modeStack.size() > 0) {
         setType(ANTLRv4Lexer.ACTION_CONTENT);
      }
   }

   protected void handleEndArgument() {
      popMode();
      if (_modeStack.size() > 0) {
         setType(ANTLRv4Lexer.ARGUMENT_CONTENT);
      }
   }

   private boolean inLexerRule() {
      return currentRuleType == ANTLRv4Lexer.TOKEN_REF;
   }

   public void setCurrentRuleType(int ruleType) {
      currentRuleType = ruleType;
   }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy