public TokenRangeElement(Grammar g, Token t1, Token t2, int autoGenType) {
   super(g, t1, autoGenType);
   begin = grammar.tokenManager.getTokenSymbol(t1.getText()).getTokenType();
   beginText = t1.getText();
   end = grammar.tokenManager.getTokenSymbol(t2.getText()).getTokenType();
   endText = t2.getText();
   line = t1.getLine();
 }
예제 #2
0
파일: ECLParser.java 프로젝트: mhcxp/isgi
  // $ANTLR start arrayIdSet
  // ECL.g:41:1: arrayIdSet returns [java.util.Set<Long> idSet] : (id1= DIGIT ) ( ',' id2= DIGIT )*
  // ;
  public final java.util.Set<Long> arrayIdSet() throws RecognitionException {
    java.util.Set<Long> idSet = null;

    Token id1 = null;
    Token id2 = null;

    idSet = new java.util.HashSet<Long>();

    try {
      // ECL.g:45:2: ( (id1= DIGIT ) ( ',' id2= DIGIT )* )
      // ECL.g:45:4: (id1= DIGIT ) ( ',' id2= DIGIT )*
      {
        // ECL.g:45:4: (id1= DIGIT )
        // ECL.g:45:5: id1= DIGIT
        {
          id1 = (Token) input.LT(1);
          match(input, DIGIT, FOLLOW_DIGIT_in_arrayIdSet154);

          idSet.add(new Long(id1.getText()));
        }

        // ECL.g:47:5: ( ',' id2= DIGIT )*
        loop7:
        do {
          int alt7 = 2;
          int LA7_0 = input.LA(1);

          if ((LA7_0 == 14)) {
            alt7 = 1;
          }

          switch (alt7) {
            case 1:
              // ECL.g:47:6: ',' id2= DIGIT
              {
                match(input, 14, FOLLOW_14_in_arrayIdSet158);
                id2 = (Token) input.LT(1);
                match(input, DIGIT, FOLLOW_DIGIT_in_arrayIdSet162);

                idSet.add(new Long(id2.getText()));
              }
              break;

            default:
              break loop7;
          }
        } while (true);
      }

    } catch (RecognitionException re) {
      reportError(re);
      recover(input, re);
    } finally {
    }
    return idSet;
  }
예제 #3
0
 /** Make name and alias for target. Replace any previous def of name */
 public CompiledST defineTemplateAlias(Token aliasT, Token targetT) {
   String alias = aliasT.getText();
   String target = targetT.getText();
   CompiledST targetCode = rawGetTemplate(target);
   if (targetCode == null) {
     errMgr.compileTimeError(ErrorType.ALIAS_TARGET_UNDEFINED, null, aliasT, alias, target);
     return null;
   }
   templates.put(alias, targetCode);
   return targetCode;
 }
예제 #4
0
 /** Create singleton template for use with dictionary values */
 public ST createSingleton(Token templateToken) {
   String template;
   if (templateToken.getType() == GroupParser.BIGSTRING) {
     template = Misc.strip(templateToken.getText(), 2);
   } else {
     template = Misc.strip(templateToken.getText(), 1);
   }
   CompiledST impl = compile(getFileName(), null, null, template, templateToken);
   ST st = createStringTemplateInternally(impl);
   st.groupThatCreatedThisInstance = this;
   st.impl.hasFormalArgs = false;
   st.impl.name = ST.UNKNOWN_NAME;
   st.impl.defineImplicitlyDefinedTemplates(this);
   return st;
 }
예제 #5
0
  private SymTabEntry parseRoutineName(Token token, String dummyName) throws Exception {
    SymTabEntry routineId = null;

    // Parse the routine name identifier.
    if (token.getType() == IDENTIFIER) {
      String routineName = token.getText().toLowerCase();
      routineId = symTabStack.lookupLocal(routineName);

      // Not already defined locally: Enter into the local symbol table.
      if (routineId == null) {
        routineId = symTabStack.enterLocal(routineName);
        routineId.appendLineNumber(token.getLineNumber());
      }

      // If already defined, it should be a forward definition.
      else {
        routineId = null;
        errorHandler.flag(token, IDENTIFIER_REDEFINED, this);
      }

      token = nextToken(); // consume routine name identifier

    } else {
      errorHandler.flag(token, MISSING_IDENTIFIER, this);
    }

    // If necessary, create a dummy routine name symbol table entry.
    if (routineId == null) {
      routineId = symTabStack.enterLocal(dummyName);
    }

    return routineId;
  }
예제 #6
0
  // $ANTLR start "color"
  // D:\\Pamela\\Quinto semestre\\Computación  Gráfica\\RayTracer\\RayTracer.g:112:1: color :
  // TYPE_COLOR ;
  public final RayTracerParser.color_return color() throws RecognitionException {
    RayTracerParser.color_return retval = new RayTracerParser.color_return();
    retval.start = input.LT(1);

    Token TYPE_COLOR5 = null;

    try {
      // D:\\Pamela\\Quinto semestre\\Computación  Gráfica\\RayTracer\\RayTracer.g:112:7: (
      // TYPE_COLOR )
      // D:\\Pamela\\Quinto semestre\\Computación  Gráfica\\RayTracer\\RayTracer.g:112:9: TYPE_COLOR
      {
        TYPE_COLOR5 = (Token) match(input, TYPE_COLOR, FOLLOW_TYPE_COLOR_in_color265);
        color += (TYPE_COLOR5 != null ? TYPE_COLOR5.getText() : null);
        double[] color1 = new double[3];
        if (color.equals("Yellow")) {
          color1[0] = 1.0;
          color1[1] = 1.0;
          color1[2] = 0.0;
        } else if (color.equals("Blue")) {
          color1[0] = 0.0;
          color1[1] = 0.0;
          color1[2] = 1.0;
        } else if (color.equals("Red")) {
          color1[0] = 1.0;
          color1[1] = 0.0;
          color1[2] = 0.0;
        } else if (color.equals("Green")) {
          color1[0] = 0.0;
          color1[1] = 1.0;
          color1[2] = 0.0;
        } else if (color.equals("White")) {
          color1[0] = 1.0;
          color1[1] = 1.0;
          color1[2] = 1.0;
        }
        color = "";
        switch (typeObject) {
          case 4:
            ligths.add(color1);
            break;
          case 5:
            for (int i = 0; i < 3; i++) {
              ambientLight[i] = color1[i];
            }
            break;
          default:
            break;
        }
      }

      retval.stop = input.LT(-1);

    } catch (RecognitionException re) {
      reportError(re);
      recover(input, re);
    } finally {
    }
    return retval;
  }
예제 #7
0
 /**
  * Get an integer option. Given the name of the option find its associated integer value. If the
  * associated value is not an integer or is not in the table, then throw an exception of type
  * NumberFormatException.
  *
  * @param key The name of the option
  * @return The value associated with the key.
  */
 public int getIntegerOption(String key) throws NumberFormatException {
   Token t = (Token) options.get(key);
   if (t == null || t.getType() != ANTLRTokenTypes.INT) {
     throw new NumberFormatException();
   } else {
     return Integer.parseInt(t.getText());
   }
 }
예제 #8
0
 public static void main(String[] args) throws Exception {
   ANTLRFileStream input = new ANTLRFileStream(args[0]);
   WigLexer lexer = new WigLexer(input);
   Token token;
   while ((token = lexer.nextToken()) != Token.EOF_TOKEN) {
     System.out.println("Token: " + token.getText() + "(" + token.getType() + ")");
   }
 }
예제 #9
0
 @Override
 protected final void logLoadError(Token ident) {
   logLoadErrorImpl(
       ident.getLineNo(),
       ident.getColumnNo(),
       MSG_CLASS_INFO,
       JavadocTagInfo.THROWS.getText(),
       ident.getText());
 }
예제 #10
0
 protected VarNode varNode() throws JmoException {
   Token t = buf.findValid();
   checkType(t, null);
   String name = t.getText();
   if (validMethodName(name)) {
     buf.takeToken();
     return new VarNode(t.getPosition(), name);
   }
   throw new ParseException("invalid varNode " + t, t.getPosition());
 }
예제 #11
0
파일: ECLParser.java 프로젝트: mhcxp/isgi
  // $ANTLR start rangeIdSet
  // ECL.g:51:1: rangeIdSet returns [java.util.Set<Long> idSet] : id1= DIGIT '.' '.' id2= DIGIT ;
  public final java.util.Set<Long> rangeIdSet() throws RecognitionException {
    java.util.Set<Long> idSet = null;

    Token id1 = null;
    Token id2 = null;

    idSet = new java.util.HashSet<Long>();
    Long start = 0L;
    Long end = 0L;

    try {
      // ECL.g:56:3: (id1= DIGIT '.' '.' id2= DIGIT )
      // ECL.g:56:6: id1= DIGIT '.' '.' id2= DIGIT
      {
        id1 = (Token) input.LT(1);
        match(input, DIGIT, FOLLOW_DIGIT_in_rangeIdSet184);

        start = new Long(id1.getText());

        match(input, 15, FOLLOW_15_in_rangeIdSet187);
        match(input, 15, FOLLOW_15_in_rangeIdSet189);
        id2 = (Token) input.LT(1);
        match(input, DIGIT, FOLLOW_DIGIT_in_rangeIdSet193);

        end = new Long(id2.getText());

        if (end < start) {
          Long temp = end;
          end = start;
          start = temp;
        }
        for (Long id = start; id <= end; id++) {
          idSet.add(id);
        }
      }

    } catch (RecognitionException re) {
      reportError(re);
      recover(input, re);
    } finally {
    }
    return idSet;
  }
예제 #12
0
  /**
   * Checks a set of tags for matching throws.
   *
   * @param tags the tags to check
   * @param throwsList the throws to check
   * @param reportExpectedTags whether we should report if do not find expected tag
   */
  private void checkThrowsTags(
      List<JavadocTag> tags, List<ExceptionInfo> throwsList, boolean reportExpectedTags) {
    // Loop over the tags, checking to see they exist in the throws.
    // The foundThrows used for performance only
    final Set<String> foundThrows = Sets.newHashSet();
    final ListIterator<JavadocTag> tagIt = tags.listIterator();
    while (tagIt.hasNext()) {
      final JavadocTag tag = tagIt.next();

      if (!tag.isThrowsTag()) {
        continue;
      }
      tagIt.remove();

      // Loop looking for matching throw
      final String documentedEx = tag.getFirstArg();
      final Token token = new Token(tag.getFirstArg(), tag.getLineNo(), tag.getColumnNo());
      final AbstractClassInfo documentedCI = createClassInfo(token, getCurrentClassName());
      final boolean found =
          foundThrows.contains(documentedEx) || isInThrows(throwsList, documentedCI, foundThrows);

      // Handle extra JavadocTag.
      if (!found) {
        boolean reqd = true;
        if (allowUndeclaredRTE) {
          reqd = !isUnchecked(documentedCI.getClazz());
        }

        if (reqd && validateThrows) {
          log(
              tag.getLineNo(),
              tag.getColumnNo(),
              MSG_UNUSED_TAG,
              JavadocTagInfo.THROWS.getText(),
              tag.getFirstArg());
        }
      }
    }
    // Now dump out all throws without tags :- unless
    // the user has chosen to suppress these problems
    if (!allowMissingThrowsTags && reportExpectedTags) {
      for (ExceptionInfo ei : throwsList) {
        if (!ei.isFound()) {
          final Token fi = ei.getName();
          log(
              fi.getLineNo(),
              fi.getColumnNo(),
              MSG_EXCPECTED_TAG,
              JavadocTagInfo.THROWS.getText(),
              fi.getText());
        }
      }
    }
  }
예제 #13
0
  private String collectToEnd() {
    StringBuilder sb = new StringBuilder();
    buf.findValid();
    do {
      Token t = buf.getToken(0);
      if (t == null) break;
      sb.append(t.getText());

    } while (buf.takeToken() != null);
    return sb.toString();
  }
예제 #14
0
 public String toString(int start, int stop) {
   if (start < 0 || stop < 0) return null;
   if (p == -1) setup();
   if (stop >= tokens.size()) stop = tokens.size() - 1;
   StringBuffer buf = new StringBuffer();
   for (int i = start; i <= stop; i++) {
     Token t = tokens.get(i);
     if (t.getType() == Token.EOF) break;
     buf.append(t.getText());
   }
   return buf.toString();
 }
예제 #15
0
 /**
  * Gets the text without the comments. For example for the string <code>{ // it's a comment</code>
  * this method will return "{ ".
  *
  * @param aStart start of the text.
  * @param anEnd end of the text.
  * @return String for the line without comments (if exists).
  */
 public synchronized String getUncommentedText(int aStart, int anEnd) {
   readLock();
   StringBuilder result = new StringBuilder();
   Iterator<Token> iter = getTokens(aStart, anEnd);
   while (iter.hasNext()) {
     Token t = iter.next();
     if (!TokenType.isComment(t)) {
       result.append(t.getText(this));
     }
   }
   readUnlock();
   return result.toString();
 }
예제 #16
0
 /**
  * How should a token be displayed in an error message? The default is to display just the text,
  * but during development you might want to have a lot of information spit out. Override in that
  * case to use t.toString() (which, for CommonToken, dumps everything about the token). This is
  * better than forcing you to override a method in your token objects because you don't have to go
  * modify your lexer so that it creates a new Java type.
  */
 public String getTokenErrorDisplay(Token t) {
   String s = t.getText();
   if (s == null) {
     if (t.getType() == Token.EOF) {
       s = "<EOF>";
     } else {
       s = "<" + t.getType() + ">";
     }
   }
   s = s.replaceAll("\n", "\\\\n");
   s = s.replaceAll("\r", "\\\\r");
   s = s.replaceAll("\t", "\\\\t");
   return "'" + s + "'";
 }
예제 #17
0
 public Instance pipe(Instance carrier) {
   TokenSequence ts = (TokenSequence) carrier.getData();
   for (int i = 0; i < ts.size(); i++) {
     Token t = ts.get(i);
     String s = t.getText();
     if (distinguishBorders) s = startBorderChar + s + endBorderChar;
     int slen = s.length();
     for (int j = 0; j < gramSizes.length; j++) {
       int size = gramSizes[j];
       for (int k = 0; k < (slen - size) + 1; k++)
         t.setFeatureValue((prefix + s.substring(k, k + size)).intern(), 1.0);
     }
   }
   return carrier;
 }
예제 #18
0
 /**
  * Checks the validity of the logic behind the tokens and then creates a valid ADS by calling
  * createADS on the valid tokens list.
  *
  * @param theTokens A valid and mathematically correct array of tokens.
  * @return Expression that abstracts the initial, mathematically correct input.
  */
 public Expression createADS(Token[] theTokens) {
   // operations stack
   Stack<Token> operations = new Stack<Token>();
   // operands stack
   Stack<Expression> operand = new Stack<Expression>();
   for (int i = 0; i < theTokens.length; i++) {
     if (theTokens[i].getType() == Token.Type.PLUS
         || theTokens[i].getType() == Token.Type.MULTIPLY
         || theTokens[i].getType() == Token.Type.OPEN_PAREN)
       // push operations and open paren on operations stack
       operations.push(theTokens[i]);
     else if (theTokens[i].getType() == Token.Type.NUMBER)
       // push number on operands stack
       operand.push(new Number(theTokens[i].getText()));
     else if (theTokens[i].getType() == Token.Type.VARIABLE) {
       Variable k = new Variable(theTokens[i].getText());
       // push variable on operands stack
       operand.push(k);
       System.out.println("In Parser: " + k.value);
     }
     // whenever a closed paren is seen, pop the elements between this paren and the previous open
     // one
     if (theTokens[i].getText() == ")") {
       // if the previous one is open, there is nothing in between
       if (i > 0 && operations.peek().getText() == "(") {
         operations.pop();
       }
       // if the previous element pushed is a number or variable, it is the case for  (3) or (x)
       else if (i > 1
           && operations.peek().getText() == "("
           && (theTokens[i - 1].getType() == Token.Type.NUMBER
               || theTokens[i - 1].getType() == Token.Type.VARIABLE)) {
         operations.pop();
       }
       // This is the case for a complete expression such as (4*x) or (4+x)
       else {
         Expression right = operand.pop();
         Expression left = operand.pop();
         Token op = operations.pop();
         operations.pop();
         if (op.getText() == "+") operand.push(new Add(left, right));
         else operand.push(new Multiply(left, right));
       }
     }
   }
   // returns the complete expression
   return operand.pop();
 }
예제 #19
0
  public void syntaxError(
      Recognizer<?, ?> recognizer,
      Object offendingSymbol,
      int line,
      int charPositionInLine,
      String msg,
      RecognitionException e) {
    CommonTokenStream tokens = (CommonTokenStream) recognizer.getInputStream();
    String input = tokens.getTokenSource().getInputStream().toString();
    Token token = (Token) offendingSymbol;
    String[] lines = StringUtils.splitPreserveAllTokens(input, '\n');
    String errorLine = lines[line - 1];

    String simpleMessage = "syntax error at or near \"" + token.getText() + "\"";
    throw new LangParserException(token, line, charPositionInLine, simpleMessage, errorLine);
  }
예제 #20
0
 public Instance pipe(Instance carrier) {
   TokenSequence ts = (TokenSequence) carrier.getData();
   for (int i = 0; i < ts.size(); i++) {
     Token t = ts.get(i);
     String s = t.getText();
     if (distinguishBorders) s = startBorderChar + s + endBorderChar;
     int slen = s.length();
     for (int j = 0; j < gramSizes.length; j++) {
       int size = gramSizes[j];
       for (int k = 0; k < slen - size; k++)
         t.setFeatureValue(
             s.substring(k, k + size), 1.0); // original was substring(k, size), changed by Fuchun
     }
   }
   return carrier;
 }
예제 #21
0
  public String toString(String programName, int start, int end) {
    List rewrites = (List) programs.get(programName);

    // ensure start/end are in range
    if (end > tokens.size() - 1) end = tokens.size() - 1;
    if (start < 0) start = 0;

    if (rewrites == null || rewrites.size() == 0) {
      return toOriginalString(start, end); // no instructions to execute
    }
    StringBuffer buf = new StringBuffer();

    // First, optimize instruction stream
    Map indexToOp = reduceToSingleOperationPerIndex(rewrites);

    // Walk buffer, executing instructions and emitting tokens
    int i = start;
    while (i <= end && i < tokens.size()) {
      RewriteOperation op = (RewriteOperation) indexToOp.get(new Integer(i));
      indexToOp.remove(new Integer(i)); // remove so any left have index size-1
      Token t = (Token) tokens.get(i);
      if (op == null) {
        // no operation at that index, just dump token
        if (t.getType() != Token.EOF) buf.append(t.getText());
        i++; // move to next token
      } else {
        i = op.execute(buf); // execute operation and skip
      }
    }

    // include stuff after end if it's last index in buffer
    // So, if they did an insertAfter(lastValidIndex, "foo"), include
    // foo if end==lastValidIndex.
    if (end == tokens.size() - 1) {
      // Scan any remaining operations after last token
      // should be included (they will be inserts).
      Iterator it = indexToOp.values().iterator();
      while (it.hasNext()) {
        RewriteOperation op = (RewriteOperation) it.next();
        if (op.index >= tokens.size() - 1) buf.append(op.text);
      }
    }
    return buf.toString();
  }
 @NotNull
 @Override
 public Pair<Token<T>, State> parse(@NotNull List<Token<T>> tokens, @NotNull State state)
     throws ParserException {
   final int pos = state.getPos();
   if (pos >= tokens.size()) {
     throw new ParserException("No tokens left", state);
   }
   final Token<T> token = tokens.get(pos);
   if (token.getType().equals(myType) && (myText == null || token.getText().equals(myText))) {
     final int newPos = pos + 1;
     final State newState = new State(state, newPos, Math.max(newPos, state.getMax()));
     return Pair.create(token, newState);
   }
   final String expected =
       myText != null
           ? String.format("Token(<%s>, \"%s\")", myType, myText)
           : String.format("Token(<%s>)", myType);
   throw new ParserException(String.format("Expected %s, found %s", expected, token), state);
 }
예제 #23
0
 private String readUntil(TokenType... stopTypes) {
   StringBuilder sb = new StringBuilder();
   while (true) {
     Token t = buf.getToken(0);
     if (t == null) {
       break;
     }
     boolean shouldStop = false;
     for (TokenType type : stopTypes) {
       if (t.getType() == type) {
         shouldStop = true;
       }
     }
     if (shouldStop) {
       break;
     }
     buf.takeToken();
     sb.append(t.getText());
   }
   return sb.toString();
 }
  // $ANTLR start "lengthScheme"
  // C:\\data\\eclipse_workspace\\clea\\grammars\\pointertarget\\URIFragmentIdentifierPlainText.g:185:1: lengthScheme returns [Integer length] : 'length=' INT ;
  public final Integer lengthScheme() throws RecognitionException {
    Integer length = null;

    Token INT11 = null;

    try {
      // C:\\data\\eclipse_workspace\\clea\\grammars\\pointertarget\\URIFragmentIdentifierPlainText.g:186:2: ( 'length=' INT )
      // C:\\data\\eclipse_workspace\\clea\\grammars\\pointertarget\\URIFragmentIdentifierPlainText.g:186:4: 'length=' INT
      {
        match(input, 15, FOLLOW_15_in_lengthScheme369);

        INT11 = (Token) match(input, INT, FOLLOW_INT_in_lengthScheme371);

        length = Integer.valueOf((INT11 != null ? INT11.getText() : null));
      }

    } catch (RecognitionException e) {
      throw e;
    } finally {
      // do for sure before leaving
    }
    return length;
  }
  // $ANTLR start "md5Scheme"
  // C:\\data\\eclipse_workspace\\clea\\grammars\\pointertarget\\URIFragmentIdentifierPlainText.g:193:1: md5Scheme returns [String md5] : 'md5=' MD5VALUE ;
  public final String md5Scheme() throws RecognitionException {
    String md5 = null;

    Token MD5VALUE12 = null;

    try {
      // C:\\data\\eclipse_workspace\\clea\\grammars\\pointertarget\\URIFragmentIdentifierPlainText.g:194:2: ( 'md5=' MD5VALUE )
      // C:\\data\\eclipse_workspace\\clea\\grammars\\pointertarget\\URIFragmentIdentifierPlainText.g:194:4: 'md5=' MD5VALUE
      {
        match(input, 16, FOLLOW_16_in_md5Scheme397);

        MD5VALUE12 = (Token) match(input, MD5VALUE, FOLLOW_MD5VALUE_in_md5Scheme399);

        md5 = (MD5VALUE12 != null ? MD5VALUE12.getText() : null);
      }

    } catch (RecognitionException e) {
      throw e;
    } finally {
      // do for sure before leaving
    }
    return md5;
  }
예제 #26
0
  /**
   * 解析标识符
   *
   * @param token
   * @return 对应符号表项
   * @throws Exception
   */
  private SymTabEntry parseIdentifier(Token token) throws Exception {
    SymTabEntry id = null;

    if (token.getType() == IDENTIFIER) {
      String name = token.getText().toLowerCase();
      id = symTabStack.lookupLocal(name);

      // 申明必须得没有,否则重定义了
      if (id == null) {
        id = symTabStack.enterLocal(name);
        id.setDefinition(definition);
        id.appendLineNumber(token.getLineNumber());
      } else {
        errorHandler.flag(token, IDENTIFIER_REDEFINED, this);
      }

      token = nextToken();
    } else {
      errorHandler.flag(token, MISSING_IDENTIFIER, this);
    }

    return id;
  }
예제 #27
0
  public CompiledST defineRegion(
      String enclosingTemplateName, Token regionT, String template, Token templateToken) {
    String name = regionT.getText();
    template = Misc.trimOneStartingNewline(template);
    template = Misc.trimOneTrailingNewline(template);
    CompiledST code = compile(getFileName(), enclosingTemplateName, null, template, templateToken);
    String mangled = getMangledRegionName(enclosingTemplateName, name);

    if (lookupTemplate(mangled) == null) {
      errMgr.compileTimeError(
          ErrorType.NO_SUCH_REGION, templateToken, regionT, enclosingTemplateName, name);
      return new CompiledST();
    }
    code.name = mangled;
    code.isRegion = true;
    code.regionDefType = ST.RegionType.EXPLICIT;
    code.templateDefStartToken = regionT;

    rawDefineTemplate(mangled, code, regionT);
    code.defineArgDefaultValueTemplates(this);
    code.defineImplicitlyDefinedTemplates(this);

    return code;
  }
예제 #28
0
 private static String location(Token t) {
   if (t == Token.EOF) return "the last line";
   else return "\"" + t.getText() + "\" at line " + t.getLineNumber();
 }
예제 #29
0
  /**
   * Parse a Triangle SingleDeclarationParser.
   *
   * <p>Single-Declaration ::= const Identifier ~ Expression | var Identifier : Type-Denoter | proc
   * Identifier (Formal-Parameter-Sequence) ~ Single-Command | func Identifier
   * (Formal-Parameter-Sequence) : Type-Denoter ~ Expression | Type Identifier ~ Type-Denoter
   *
   * <p>To be overridden by the specialized command parse subclasses.
   *
   * @param token the initial token.
   * @return the root node of the generated parse tree.
   * @throws Exception if an error occurred.
   */
  public void parse(Token token) throws Exception {
    SingleCommandParser singleCommand = null;
    ExpressionParser expression = null;
    FormalParameterSequenceParser formalParameterSequence = null;
    TypeDenoterParser typeDenoter = null;
    EnumSet<TriangleTokenType> syncSet = null;
    TypeSpec identifierType = TrianglePredefined.undefinedType;
    Token identifierToken = null;
    ICode routineICode = null;

    token = currentToken();

    switch ((TriangleTokenType) token.getType()) {
      case CONST:
        identifierToken = nextToken();
        syncSet = EnumSet.of(TILDE);
        syncSet.addAll(ExpressionParser.FIRST_FOLLOW_SET);
        synchronize(IDENTIFIER, MISSING_IDENTIFIER, syncSet);
        syncSet.remove(TILDE);
        token = synchronize(TILDE, MISSING_TILDE, syncSet);
        expression = new ExpressionParser(this);
        ICodeNode expressionNode = expression.parse(token);

        SymTabEntry constantId = symTabStack.lookupLocal(identifierToken.getText().toLowerCase());
        // Enter the new identifier into the symbol table
        // but don't set how it's defined yet.
        if (constantId == null) {
          constantId = symTabStack.enterLocal(identifierToken.getText().toLowerCase());
          constantId.setDefinition(DefinitionImpl.CONSTANT);
          constantId.setAttribute(CONSTANT_VALUE, expressionNode);
          constantId.appendLineNumber(identifierToken.getLineNumber());
          constantId.setTypeSpec(expressionNode.getTypeSpec());
        } else {
          errorHandler.flag(identifierToken, IDENTIFIER_REDEFINED, this);
        }
        break;
      case VAR:
        identifierToken = nextToken();
        syncSet = EnumSet.of(COLON);
        syncSet.addAll(TypeDenoterParser.FIRST_FOLLOW_SET);
        synchronize(IDENTIFIER, MISSING_IDENTIFIER, syncSet);

        syncSet.remove(COLON);
        token = synchronize(COLON, MISSING_COLON, syncSet);

        typeDenoter = new TypeDenoterParser(this);
        identifierType = typeDenoter.parse(token);

        SymTabEntry variableId = symTabStack.lookupLocal(identifierToken.getText().toLowerCase());
        // Enter the new identifier into the symbol table
        // but don't set how it's defined yet.
        if (variableId == null) {
          variableId = symTabStack.enterLocal(identifierToken.getText().toLowerCase());
          variableId.setDefinition(DefinitionImpl.VARIABLE);
          variableId.appendLineNumber(identifierToken.getLineNumber());
          variableId.setTypeSpec(identifierType);
        } else {
          errorHandler.flag(identifierToken, IDENTIFIER_REDEFINED, this);
        }
        break;
      case PROC:
        identifierToken = nextToken();
        routineICode = ICodeFactory.createICode();
        syncSet = EnumSet.of(LEFT_PAREN);
        syncSet.addAll(FormalParameterSequenceParser.FIRST_FOLLOW_SET);
        token = synchronize(IDENTIFIER, MISSING_IDENTIFIER, syncSet);
        syncSet.remove(LEFT_PAREN);
        token = synchronize(LEFT_PAREN, MISSING_LEFT_PAREN, syncSet);
        SymTabEntry procId = symTabStack.lookupLocal(identifierToken.getText().toLowerCase());
        // Enter the new identifier into the symbol table
        // but don't set how it's defined yet.
        if (procId == null) {
          procId = symTabStack.enterLocal(identifierToken.getText().toLowerCase());
          procId.setTypeSpec(TrianglePredefined.undefinedType);
          procId.setDefinition(DefinitionImpl.PROCEDURE);
          procId.appendLineNumber(identifierToken.getLineNumber());
          procId.setAttribute(ROUTINE_SYMTAB, symTabStack.push());
          procId.setAttribute(ROUTINE_ICODE, routineICode);
        } else {
          errorHandler.flag(identifierToken, IDENTIFIER_REDEFINED, this);
          procId = null;
        }

        formalParameterSequence = new FormalParameterSequenceParser(this);
        ArrayList<SymTabEntry> procParamList = formalParameterSequence.parse(token);
        syncSet = EnumSet.of(TILDE);
        syncSet.addAll(SingleCommandParser.FIRST_FOLLOW_SET);
        token = synchronize(RIGHT_PAREN, MISSING_RIGHT_PAREN, syncSet);
        syncSet.remove(TILDE);
        token = synchronize(TILDE, MISSING_TILDE, syncSet);
        singleCommand = new SingleCommandParser(this);
        routineICode.setRoot(singleCommand.parse(token));
        if (procId != null) {
          procId.setAttribute(ROUTINE_PARMS, procParamList);
        }
        symTabStack.pop();
        break;
      case FUNC:
        identifierToken = nextToken();
        routineICode = ICodeFactory.createICode();
        SymTabEntry funcId = symTabStack.lookupLocal(identifierToken.getText().toLowerCase());
        // Enter the new identifier into the symbol table
        // but don't set how it's defined yet.
        if (funcId == null) {
          funcId = symTabStack.enterLocal(identifierToken.getText().toLowerCase());
          funcId.setDefinition(DefinitionImpl.FUNCTION);
          funcId.appendLineNumber(identifierToken.getLineNumber());
          funcId.setTypeSpec(TrianglePredefined.undefinedType);
          funcId.setAttribute(ROUTINE_SYMTAB, symTabStack.push());
          funcId.setAttribute(ROUTINE_ICODE, routineICode);
        } else {
          errorHandler.flag(identifierToken, IDENTIFIER_REDEFINED, this);
          funcId = null;
        }
        syncSet = EnumSet.of(LEFT_PAREN);
        syncSet.addAll(FormalParameterSequenceParser.FIRST_FOLLOW_SET);
        token = synchronize(IDENTIFIER, MISSING_IDENTIFIER, syncSet);
        syncSet.remove(LEFT_PAREN);
        token = synchronize(LEFT_PAREN, MISSING_LEFT_PAREN, syncSet);
        formalParameterSequence = new FormalParameterSequenceParser(this);
        ArrayList<SymTabEntry> funcParamList = formalParameterSequence.parse(token);
        syncSet = EnumSet.of(COLON);
        syncSet.addAll(TypeDenoterParser.FIRST_FOLLOW_SET);
        synchronize(RIGHT_PAREN, MISSING_RIGHT_PAREN, syncSet);
        syncSet.remove(COLON);
        token = synchronize(COLON, MISSING_COLON, syncSet);
        Token typeToken = currentToken();
        typeDenoter = new TypeDenoterParser(this);
        TypeSpec funcType = typeDenoter.parse(token);
        syncSet = ExpressionParser.FIRST_FOLLOW_SET.clone();
        token = synchronize(TILDE, MISSING_TILDE, syncSet);
        expression = new ExpressionParser(this);
        routineICode.setRoot(expression.parse(token));
        if (funcId != null) {
          funcId.setTypeSpec(funcType);
          funcId.setAttribute(ROUTINE_PARMS, funcParamList);
          if (!routineICode.getRoot().getTypeSpec().equals(funcType)) {
            errorHandler.flag(typeToken, RETURN_TYPE_MISMATCH, this);
          }
        }
        symTabStack.pop();
        break;
      case TYPE:
        identifierToken = nextToken();
        syncSet = EnumSet.of(TILDE);
        syncSet.addAll(TypeDenoterParser.FIRST_FOLLOW_SET);
        synchronize(IDENTIFIER, MISSING_IDENTIFIER, syncSet);
        syncSet.remove(TILDE);
        token = synchronize(TILDE, MISSING_TILDE, syncSet);
        typeDenoter = new TypeDenoterParser(this);
        TypeSpec typeType = typeDenoter.parse(token);
        SymTabEntry typeId = symTabStack.lookupLocal(identifierToken.getText().toLowerCase());
        // Enter the new identifier into the symbol table
        // but don't set how it's defined yet.
        if (typeId == null) {
          typeId = symTabStack.enterLocal(identifierToken.getText().toLowerCase());
          typeId.setDefinition(DefinitionImpl.TYPE);
          typeId.appendLineNumber(identifierToken.getLineNumber());
          typeId.setTypeSpec(typeType);
        } else {
          errorHandler.flag(token, IDENTIFIER_REDEFINED, this);
        }
        break;
      default:
        errorHandler.flag(token, MISSING_DECLARATION, this);
        break;
    }
  }
  /**
   * Parse a factor.
   *
   * @param token the initial token.
   * @return the root of the generated parse subtree.
   * @throws Exception if an error occurred.
   */
  private ICodeNode parseFactor(Token token) throws Exception {
    TokenType tokenType = token.getType();
    ICodeNode rootNode = null;

    switch ((PascalTokenType) tokenType) {
      case IDENTIFIER:
        {
          // Look up the identifier in the symbol table stack.
          // Flag the identifier as undefined if it's not found.
          String name = token.getText().toLowerCase();
          SymTabEntry id = symTabStack.lookup(name);
          if (id == null) {
            errorHandler.flag(token, IDENTIFIER_UNDEFINED, this);
            id = symTabStack.enterLocal(name);
          }

          rootNode = ICodeFactory.createICodeNode(VARIABLE);
          rootNode.setAttribute(ID, id);
          id.appendLineNumber(token.getLineNumber());

          token = nextToken(); // consume the identifier
          break;
        }

      case INTEGER:
        {
          // Create an INTEGER_CONSTANT node as the root node.
          rootNode = ICodeFactory.createICodeNode(INTEGER_CONSTANT);
          rootNode.setAttribute(VALUE, token.getValue());

          token = nextToken(); // consume the number
          break;
        }

      case REAL:
        {
          // Create an REAL_CONSTANT node as the root node.
          rootNode = ICodeFactory.createICodeNode(REAL_CONSTANT);
          rootNode.setAttribute(VALUE, token.getValue());

          token = nextToken(); // consume the number
          break;
        }

      case STRING:
        {
          String value = (String) token.getValue();

          // Create a STRING_CONSTANT node as the root node.
          rootNode = ICodeFactory.createICodeNode(STRING_CONSTANT);
          rootNode.setAttribute(VALUE, value);

          token = nextToken(); // consume the string
          break;
        }

      case NOT:
        {
          token = nextToken(); // consume the NOT

          // Create a NOT node as the root node.
          rootNode = ICodeFactory.createICodeNode(ICodeNodeTypeImpl.NOT);

          // Parse the factor.  The NOT node adopts the
          // factor node as its child.
          rootNode.addChild(parseFactor(token));

          break;
        }

      case LEFT_PAREN:
        {
          token = nextToken(); // consume the (

          // Parse an expression and make its node the root node.
          rootNode = parseExpression(token);

          // Look for the matching ) token.
          token = currentToken();
          if (token.getType() == RIGHT_PAREN) {
            token = nextToken(); // consume the )
          } else {
            errorHandler.flag(token, MISSING_RIGHT_PAREN, this);
          }

          break;
        }
      case LEFT_BRACKET:
        {
          rootNode = parseSet(token);

          break;
        }

      default:
        {
          errorHandler.flag(token, UNEXPECTED_TOKEN, this);
          break;
        }
    }

    return rootNode;
  }