Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
      Copyright (c) 2012 zuendorf 
   
      Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
      and associated documentation files (the "Software"), to deal in the Software without restriction, 
      including without limitation the rights to use, copy, modify, merge, publish, distribute, 
      sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
      furnished to do so, subject to the following conditions: 
   
     The above copyright notice and this permission notice shall be included in all copies or 
     substantial portions of the Software. 
  
     The Software shall be used for Good, not Evil. 
  
     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
     BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
     DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 
   */
  
  package org.sdmlib.codegen;
  
  import java.util.Arrays;
  import java.util.HashMap;
  import java.util.Set;
  
  
  
  public class Parser
  {
  
     public static final char EOF = .;
  
     public static final String VOID = "void";
  
     public static final String CLASS = "class";
  
     public static final String INTERFACE = "interface";
  
     public static final String ENUM = "enum";
  
     public static final char COMMENT_START = 'c';
  
     public static final String PACKAGE = "package";
  
     public static final char LONG_COMMENT_END = 'd';
  
     public static final String CONSTRUCTOR = "constructor";
     
     public static final String ATTRIBUTE = "attribute";
     
     public static final String ENUMVALUE = "enumvalue";
  
     public static final String METHOD = "method";
  
     public static final String IMPORT = "import";
  
     public static final String CLASS_BODY = "classBody";
  
     public static final String CLASS_END = "classEnd";
  
     public static final String NAME_TOKEN = "nameToken";
  
     public static final String METHOD_END = "methodEnd";
  
     public static final String LAST_RETURN_POS = "lastReturnPos";
  
     public static final String IMPLEMENTS = "implements";
  
     public static final String QUALIFIED_NAME = "qualifiedName";
  
     public static final String EXTENDS = "extends";
  
     public static char NEW_LINE = '\n';
  
     private StringBuilder fileBody = null;
     
     private boolean fileBodyHasChanged = false;
     
     public boolean isFileBodyChanged()
     {
        return ;
     }
     
     private Token lookAheadToken = null;
  
     private Token currentToken;
  
     private char currentChar;
  
     private int index;
  
  
    {
       return ;
    }
 
 
 
    private StatementEntry currentStatement = null
 
    {
       return ;
    }
 
    {
       return ;
    }
 
    {
       return ;
    }
    
    {
       return ;
    }
 
    private boolean verbose = false;
 
    public void setVerbose(boolean verbose)
    {
       this. = verbose;
    }
 
    public boolean isVerbose()
    {
       return ;
    }
 
    private int endPos;
 
    private char lookAheadChar;
 
    private int lookAheadIndex;
 
    private String searchString;
 
    private int methodBodyStartPos;
 
    private int endOfAttributeInitialization;
 
    private int endOfImplementsClause;
 
    private int endOfClassName;
 
    private int endOfExtendsClause;
 
    private int endOfImports;  
 
    public int getEndOfImports()
    {
       return ;
    }
 
    public int getEndOfExtendsClause()
    {
       return ;
    }
 
    public int getEndOfClassName()
    {
       return ;
    }
 
    public int getEndOfImplementsClause()
    {
       return ;
    }
 
    public int getEndOfAttributeInitialization()
    {
       return ;
    }
 
    public int getMethodBodyStartPos()
    {
       return ;
    }
 
    public int insert(int offsetString text)
    {
       this..insert(offsettext);
       this. = true;
       return offsettext.length();
    }
    
    public int search(String searchTextint pos)
    {
       return this..indexOf(searchTextpos);
    }
    
    public int search(String searchText)
    {
       return this..indexOf(searchText);
    }
    
    public String getClassName()
    {
       return ;
    }
    
    
    {
       private static final long serialVersionUID = 1L; 
    }
 
    public Parser withFileBody(StringBuilder fileBody)
    {
       this. = fileBody;
       return this;
    }
 
    private Parser withInit(int startPosint endPos
    {
       if ( == null)
       {
           = new SimpleKeyValueList<StringSymTabEntry>();
       }
       else
       {
          .clear();
       }
 
       if ( == null)
       {
           = new LinkedHashMap<StringLocalVarTableEntry>();
       }
       else
       {
          .clear();
       }
       
       if ( == null)
       {
           = new HashMap<>();
       }
       else
       {
          .clear();
       }
 
        = new StatementEntry();
 
 
 
        = 0;
 
        = startPos-1;
        = startPos-1;
 
       this. = endPos;
 
       nextChar(); 
       nextChar();
 
        = new Token ();
        = new Token ();
        = new Token ();
 
       nextToken();
       nextToken();
 
        = new Token();
        = new Token();
        = new Token();
 
       nextRealToken();
       nextRealToken();
 
       return this;
    }
 
    public int indexOf(String searchString)
    {
        = -1;
 
       withInit(0, .length());
 
       this. = searchString;
 
       try
       {
          parseFile();
       }
       catch (SearchStringFoundException e)
       {
          // found it, return indexOfResult
       }
       catch (Exception e
       {
          // problem with parsing. Return not found
          e.printStackTrace();
       }
 
       return ;
    }
    
    public Parser parse(){
       indexOf();
       return this;
    }
 
    private void parseFile()
    {
       // [packagestat] importlist classlist
       if (currentRealTokenEquals())
       {
          parsePackageDecl();
       }
 
       int startPos = .;
 
       while (currentRealTokenEquals())
       {
          parseImport();
       }
 
 
       checkSearchStringFound(startPos);
 
       parseClassDecl();
    }
 
    private void parseClassDecl()
    {
       // modifiers class name classbody
       parseModifiers();
 
       // skip keyword
       //      skip ("class");
 
       //class or interface or enum
       parseClassType();
 
        = currentRealWord();
 
       // skip name
       nextRealToken();
 
       parseGenericTypeSpec();
 
       // extends 
       if ("extends".equals(currentRealWord()))
       {
          int startPos = .;
 
          skip ("extends");
 
          .put( + ":" + currentRealWord(), 
             new SymTabEntry().withBodyStartPos(.)
             .withKind()
             .withMemberName(currentRealWord())
             .withEndPos(.));
 
          // skip superclass name
          parseTypeRef(); 
 
 
          checkSearchStringFound(startPos);
       }
 
       // implements 
       if ("implements".equals(currentRealWord()))
       {
          int startPos = .;
 
          skip ("implements");
 
          while ( ! currentRealKindEquals() && ! currentRealKindEquals('{'))
          {
             .put( + ":" + currentRealWord(), 
                new SymTabEntry().withBodyStartPos(.)
                .withKind()
                .withMemberName(currentRealWord())
                .withEndPos(.));
 
             // skip interface name
             nextRealToken(); 
 
             if (currentRealKindEquals(','))
             {
                nextRealToken();
             }
          }
 
 
          checkSearchStringFound(startPos);
       }
 
       parseClassBody();     
    }
 
    private void parseGenericTypeSpec()
    {
       // genTypeSpec < T , T, ...>
       if (currentRealKindEquals('<'))
       {
          skipTo('>');
 
          nextRealToken();
       }
    }
 
    private String parseClassType()
    {
 
       if ("class".equals(currentRealWord()) ) {
          skip("class");
           = "class";
       }
 
       else if ("interface".equals(currentRealWord()) ) {
          skip("interface");
           = "interface";
       }
       
       else if ("enum".equals(currentRealWord()) ) {
     	  skip("enum");
     	   = "enum";
       }
 
       return ;
    }
 
    private void parseClassBody()
    {
       // { classBodyDecl* }
       skip("{");
       while ( ! currentRealKindEquals() && ! currentRealKindEquals('}'))
       {
          parseMemberDecl();
       }
 
       if (currentRealKindEquals('}'))
       {
       }
       
       if (!currentRealKindEquals()) {
     	  skip("}"); 
       }
       else {
       }
    }
 
    private void parseMemberDecl()
    {
       // annotations modifiers (genericsDecl) ( typeRef name [= expression ] | typeRef name '(' params ')' | classdecl ) ; 
 
       // TODO: annotations
 	   String annotations = parseAnnotations();
 
       int startPos = .;
 
       String modifiers = parseModifiers();
 
       if (currentRealTokenEquals("<"))
       {
          // generic type decl
          skip("<");
          while  (!currentRealTokenEquals(">"))
          {
             nextRealToken();
          }
          skip(">");
       }
 
       if (currentRealTokenEquals())
       {
          // parse nested class
          // throw new RuntimeException("class "  + className + " has nested class. " + " Can't parse it.");
          // System.err.println("class "  + fileName + " has nested class in line " + getLineIndexOf(currentRealToken.startPos) + "  Can't parse it. Skip it.");
          while (!currentRealTokenEquals("{")) {
             nextRealToken();
          }
          skipBody();
          if (currentRealTokenEquals("}")) 
          {
             return;
          }
          modifiers = parseModifiers();
       }
       else if (currentRealTokenEquals())
       {
          // skip enum name { entry, ... }
          skip();
          nextRealToken(); // name
          skipBody();
          if (currentRealTokenEquals("}")) 
          {
             return;
          }
          modifiers = parseModifiers();
       }
 
       if (currentRealTokenEquals() && . == '(')
       {
          // constructor 
          skip();
          String params = parseFormalParamList();
          parseBlock();
          
          String constructorSignature = . + ":" +  + params;
          .put(constructorSignature
             new SymTabEntry()
          .withMemberName(constructorSignature)
          .withKind()
          .withType(constructorSignature + ":" + )
          .withStartPos(startPos)
          .withModifiers(modifiers)
           );
 
          checkSearchStringFound(constructorSignaturestartPos);
          
       }
       else
       {
          String type = parseTypeRef();
 
          String memberName = currentRealWord();
          verbose("parsing member: " + memberName);
 
          nextRealToken();
 
          if (currentRealKindEquals('='))
          {
             // field declaration with initialisation
             skip("=");
 
             parseExpression();
 
 
             skip(";");
        
             .put(+":"+memberName
                new SymTabEntry()
             .withMemberName(memberName)
             .withKind()
             .withType(type)
             .withStartPos(startPos)
             .withEndPos(.)
             .withModifiers(modifiers)
                   );
 
             checkSearchStringFound(+":"+memberNamestartPos);
          }
          else if (currentRealKindEquals(';') && !",".equals(memberName))
          {
             // field declaration
             checkSearchStringFound( + ":" + startPos);
             skip(";");
 
             .put(+":"+memberName
                new SymTabEntry()
             .withMemberName(memberName)
             .withKind()
             .withType(type)
             .withStartPos(startPos)
             .withEndPos(.)
             .withModifiers(modifiers)
                   );
 
             checkSearchStringFound(+":"+memberNamestartPos);
          }
          else if (currentRealKindEquals('('))
          {
 
             String params = parseFormalParamList();
 
             // FIXME : skip annotations 
             if(type.startsWith("@")) {
             	return;
             }
 
             // skip throws
             if (currentRealTokenEquals("throws")) 
             {
                skipTo('{');
             }
 
              = .;
 
             if (currentRealKindEquals('{'))
             {
                parseBlock();
             }
 
             else if (currentRealKindEquals(';'))
                skip(';');
 
             String methodSignature = . + ":" + memberName + params;
             .put(methodSignature
                new SymTabEntry()
             .withMemberName(methodSignature)
             .withKind()
             .withType(methodSignature + ":" + type)
             .withStartPos(startPos)
             .withEndPos(.)
             .withBodyStartPos()
             .withAnnotations(annotations)
             .withModifiers(modifiers)
                   );
 
             checkSearchStringFound(methodSignaturestartPos);
             //System.out.println(className + " :  " +  methodSignature);
          }
          else if (.equals()) {
 
         	 if (  ",".equalsIgnoreCase(memberName) || ";".equalsIgnoreCase(memberName) || !";".equals(type) && currentRealKindEquals()) {
         		 
         		 String enumSignature = . + ":" + type;
                  .put(enumSignature
                     new SymTabEntry()
                  .withMemberName(type)
                  .withKind()
                  .withType(enumSignature + ":" + )
                  .withStartPos(startPos)
                  .withEndPos(.)
                  .withBodyStartPos()
                  .withModifiers(modifiers)
                        );
         		 
         	 }
          }
       }
    }
 
 	private String parseAnnotations() {
 		String result = "";
 
 		while ("@".equals(currentRealWord())) {
 			result += currentRealWord();
 			result += currentRealWord();
 
 			if("(".equals(currentRealWord())) {
 				result += currentRealWord();
 				
 				while (!")".equals(currentRealWord())) {
 					result += currentRealWord();
 				}
 				result += currentRealWord();
 			}
 		}
 		
 //		if (!result.isEmpty()) System.out.println(result);
 		return result;
 	}
 
 	private void skipTo(char c) {
       while (!currentRealKindEquals(c) && ! currentRealKindEquals()) {
          nextRealToken();
       }
    }
 
    private void skipBody() {
       int index = 1;
       nextRealToken();
       while (index > 0 && ! currentRealKindEquals()) {
          nextRealToken();
          if (currentRealTokenEquals("{"))
             index++;
          else if (currentRealTokenEquals("}"))
             index--;
       }   
       nextRealToken();
    }
 
    private void verbose(String string)
    {
       if ()
       {
          ..println(string);
       }
    }
 
    private void parseExpression()
    {
       // ... { ;;; } ;
       while ( ! currentRealKindEquals() && ! currentRealKindEquals(';'))
       {
          if (currentRealKindEquals('{'))
          {
             parseBlock();
          }
          else
          {
             nextRealToken();
          }
       }
    }
 
    private void parseBlock()
    {
       // { stat ... }
       skip("{");
 
       while ( ! currentRealKindEquals() && ! currentRealKindEquals('}'))
       {
          if (currentRealKindEquals('{'))
          {
             parseBlock();
          }
          else
          {
             nextRealToken();
          }
       }
 
       skip("}");      
    }
 
    private String parseTypeRef()
    {
       StringBuilder typeString = new StringBuilder();
 
       // (void | qualifiedName) <T1, T2> [] ...  
       String typeName = ;
       if (currentRealTokenEquals())
       {
          // skip void
          nextRealToken();
       }
       else
       {
          typeName = parseQualifiedName();
       }
 
       typeString.append(typeName);
 
       if (currentRealKindEquals('<'))
       {
          parseGenericTypeDefPart(typeString);
       }
 
       if (currentRealKindEquals('['))
       {
          typeString.append("[]");
          skip("[");
          while (! "]".equals(currentRealWord()) && ! currentRealKindEquals())
          {
             nextRealToken();
          }
          skip("]");
       }
 
       if (currentRealKindEquals('.'))
       {
          typeString.append("...");
          skip(".");
          skip(".");
          skip(".");
       }
 
       if ("extends".equals(..toString()) )
       {
          typeString.append(.);
          nextRealToken();
          typeString.append(.);
          nextRealToken();
          typeString.append(.);
          nextRealToken();
          typeString.append(.);
 
       }
       if("@".equals(typeString.toString())) {
     	  typeString.append(.);
       }
       // phew
       return typeString.toString();
    }
 
    private void parseGenericTypeDefPart(StringBuilder typeString)
    {
       // <T, T, ...>
       skip("<"); typeString.append('<');
 
       while (! currentRealKindEquals('>') && ! currentRealKindEquals())
       {
          if (currentRealKindEquals('<'))
          {
             parseGenericTypeDefPart(typeString);
          }
          else
          {
             typeString.append(currentRealWord());
             nextRealToken();
          }
       }
 
       // should be a < now
       typeString.append(">");
       skip(">");
    }
 
    private String parseFormalParamList()
    {
       StringBuilder paramList = new StringBuilder().append('(');
 
       // '(' (type name[,] )* ') [throws type , (type,)*] 
       skip("(");
 
       while ( ! currentRealKindEquals() && ! currentRealKindEquals(')'))
       {
          int typeStartPos = .;
 
          parseTypeRef();
 
          int typeEndPos = .-1;
 
          paramList.append(.substring(typeStartPostypeEndPos));
 
          // parameter ends
          if (currentRealKindEquals(')'))
             break;
 
          // skip param name
          nextRealToken();
 
          if (currentRealKindEquals(','))
          {
             skip(",");
             paramList.append(',');
          }
       }
 
       skip(")");
 
       paramList.append(')');
 
       return paramList.toString();
    }
 
    private boolean currentRealKindEquals(char c)
    {
       return . == c;
    }
 
    private String currentRealWord()
    {
       return ..toString();
    }
 
    private boolean currentRealTokenEquals(String word)
    {
       return StrUtil.stringEquals(currentRealWord(), word);
    }
 
    private String parseModifiers()
    {
       // names != class
       String result = "";
       String modifiers = " public protected private static abstract final native synchronized transient volatile strictfp ";
       while (modifiers.indexOf(" " + currentRealWord() + " ") >= 0)
       {
          result += currentRealWord() + " ";
          nextRealToken();
       }
 
       return result;
    }
 
    private void parseImport()
    {
       // import qualifiedName [. *];
       int startPos = .;
       nextRealToken();
 
       String modifier = parseModifiers();
 
       // if (!modifier.isEmpty())
       //  System.out.println("static import");
 
       String importName = parseQualifiedName();
 
       if (. == '*')
       {
          skip("*");
       }
 //      if (currentRealToken.kind == '$'){
 //         nextRealToken();
 //         importName += "$"+currentRealWord();
 //         nextRealToken();
 //      }
 
       .put( + ":" + importName
          new SymTabEntry().withMemberName(importName)
          .withModifiers(modifier)
          .withStartPos(startPos)
          .withEndPos(.));
 
       skip(";");
    }
 
    private void parsePackageDecl()
    {
       int startPos = .;
       nextRealToken();
       parseQualifiedName();
       skip(";");
       checkSearchStringFound(startPos);
    }
 
    private void checkSearchStringFound(String foundElemint startPos)
    {
       if (StrUtil.stringEquals(foundElem))
       {
           = startPos;
          throw new SearchStringFoundException();
       }
    }
 
    private String parseQualifiedName()
    {
       // return dotted name
       int startPos = .;
       int endPos = .;
 
       nextRealToken();
 
       while (currentRealKindEquals('.') && ! (. == '.') && ! currentRealKindEquals())
       {
          skip(".");
 
          // read next name
          endPos = .;
          nextRealToken();
       }
 
       return .substring(startPosendPos + 1);
    }
 
    private void skip(char c)
    {
       if (currentRealKindEquals(c))
       {
          nextRealToken();
       }
       else
       { 
          ..println"Parser Problem: \'" + . + "\' :"  
                +  " but \'" + c + "\' expected in " +  + ".java  at line " 
                + getLineIndexOf(.)
                + "\n"+getLineForPos(.));
 //         throw new RuntimeException("parse error");
       }
    }
 
    private void skip(String string)
    {
       if (currentRealTokenEquals(string))
       {
          nextRealToken();
       }
       else
       {
 
          ..println("Parser Error: expected token " + string + " found " + currentRealWord() 
             + " at pos " + . + " at line " + getLineIndexOf(.)
             + " in file \n" + );
 
          throw new RuntimeException("parse error");
       }
    }
 
    private long getLineIndexOf(int startPosStringBuilder fileBody)
    {
       long count = 1;
       String substring = fileBody.substring(0, startPos);
      for (int index = 0; index < substring.length() - 1; ++index)
      {
         final char firstChar = substring.charAt(index);
         if (firstChar == )
            count++;
      }
      return count;
   }
   public long getLineIndexOf(int startPos)
   {
      if(startPos < 0)
         return -1;
      long count = 1;
      String substring = .substring(0, startPos);
      for (int index = 0; index < substring.length() - 1; ++index)
      {
         final char firstChar = substring.charAt(index);
         if (firstChar == )
            count++;
      }
      return count;
   }
   public Token currentRealToken
   public int indexOfResult;
   private Token previousToken;
   private String className;
   private String classType;
   public String getClassType()
   {
      return ;
   }
   public int lastIfStart;
   public int lastIfEnd;
   private int lastReturnStart;
   private HashMap<StatementEntryIntegerreturnStatements = new HashMap<>();
      return ;
   }
      return .keySet();
   }
   public int getLastReturnStart()
   {
      return ;
   }
   private void nextRealToken()
   {
      Token tmp = ;
       = tmp;
      // parse comments and skip new lines
      while (. ==  || . == )
      {
         if (..indexOf("/*") == 0 )
         {
            parseLongComment();
         }
         else if (..indexOf("//") == 0)
         {
            parseLineComment();
         }
         else
         {
            nextToken();
         }
      }
      // parse string constants as one real token
      if (. == '"')
      {
         int constStartPos = .;
         parseStringConstant();
         . = '"';
         . = constStartPos;
      }
      else if (. == '\'')
      {
         int constStartPos = .;
         parseCharConstant();
         . = '\'';
         . = constStartPos;
      }
      else
      {
         nextToken();
      }
   }
   private void parseCharConstant()
   {
      // " 'c' or '\c' "
      skipBasicToken('\'');
      // skip \ 
      if (. == '\\')
      {
         nextToken();
      }
      // skip c
      nextToken();
      skipBasicToken('\'');
   }
   private void parseLineComment()
   {
      // '//' ... \n
      // skip //
      nextToken();
      while (. !=  && . != '\n')
      {
         nextToken();
      }
      // skip \n 
      nextToken();
   }
   private void parseStringConstant()
   {
      // " ... \" ... "
      skipBasicToken('"');
      // read until next "
      while (. !=  && . != '"')
      {
         if (. == '\\')
         {
            // escape next char
            nextToken();
         }