Package dtool.parser.common

Source Code of dtool.parser.common.LexerResult

/*******************************************************************************
* Copyright (c) 2014, 2014 Bruno Medeiros and other Contributors.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
*     Bruno Medeiros - initial API and implementation
*******************************************************************************/
package dtool.parser.common;

import static melnorme.utilbox.core.Assert.AssertNamespace.assertTrue;
import static melnorme.utilbox.misc.NumberUtil.isInRange;

import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

import melnorme.utilbox.misc.IteratorUtil;
import dtool.parser.DeeLexer;
import dtool.parser.DeeTokens;


public class LexerResult {
 
  public final String source;
  public final List<LexElement> tokenList;
 
  public LexerResult(String source, List<LexElement> tokenList) {
    this.source = source;
    this.tokenList = Collections.unmodifiableList(tokenList);
   
    assertTrue(tokenList.size() > 0);
    assertTrue(tokenList.get(tokenList.size()-1).isEOF());
  }
 
  public ListIterator<LexElement> getFirstLexElementAtOffset(final int offset) {
    assertTrue(offset <= source.length());
   
    ListIterator<LexElement> iterator = tokenList.listIterator();
   
    while(true) {
      assertTrue(iterator.hasNext());
      LexElement lexElement = iterator.next();
     
      assertTrue(lexElement.getFullRangeStartPos() <= offset);
     
      if(lexElement.isEOF())
        break;
      if(offset <= lexElement.getEndPos())
        break;
    }
    return iterator;
  }
 
  public IToken findFirstTokenAtOffset(final int offset) {
    ListIterator<LexElement> iterator = getFirstLexElementAtOffset(offset);
    LexElement lexElement = IteratorUtil.getCurrentElement(iterator);
    return findTokenInLexElement(lexElement, offset);
  }
 
  public IToken findTokenInLexElement(LexElement lexElement, int offset) {
    assertTrue(isInRange(lexElement.getFullRangeStartPos(), offset, lexElement.getEndPos()));
   
    if(offset >= lexElement.getStartPos()) {
      return lexElement;
    } else {
      // Search in comments, token is in the subchannel range [FullRangeStartPos .. StartPos]
      int searchStartPos = lexElement.getFullRangeStartPos();
      // We don't store subchannel tokens, so we have to reparse to find them:
      return findFirstTokenAtOffset(source, searchStartPos, offset);
    }
  }
 
  public TokenAtOffsetResult findTokenAtOffset(int offset) {
    ListIterator<LexElement> lexElementCursor = getFirstLexElementAtOffset(offset);
    LexElement lexElement = IteratorUtil.getCurrentElement(lexElementCursor);   
   
    IToken tokenAtLeft;
    IToken tokenAtRight;
   
    if(lexElement.getFullRangeStartPos() < offset) {
      assertTrue(offset <= lexElement.getEndPos());
     
      tokenAtLeft = findTokenInLexElement(lexElement, offset);
     
      if(offset < tokenAtLeft.getEndPos()) {
        tokenAtRight = tokenAtLeft;
      } else {
        assertTrue(tokenAtLeft.getEndPos() == offset);
       
        if(offset < lexElement.getEndPos()) {
          tokenAtRight = findTokenInLexElement(lexElement, tokenAtLeft.getEndPos());
        } else
          assertTrue(tokenAtLeft.getEndPos() == offset);
         
          if(lexElementCursor.hasNext()) {
            LexElement nextLexElement = lexElementCursor.next();
            tokenAtRight = findTokenInLexElement(nextLexElement, offset);
          } else {
            tokenAtRight = null;
          }
        }
      }
     
    } else {
      tokenAtLeft = null;
      assertTrue(offset == lexElement.getFullRangeStartPos());
      tokenAtRight = findTokenInLexElement(lexElement, offset);
    }
   
    return new TokenAtOffsetResult(tokenAtLeft, tokenAtRight);
  }
 
  public static class TokenAtOffsetResult {
   
    public final IToken atLeft;
    public final IToken atRight;
   
    public TokenAtOffsetResult(IToken tokenAtOffsetLeft, IToken tokenAtOffsetRight) {
      this.atLeft = tokenAtOffsetLeft;
      this.atRight = tokenAtOffsetRight;
    }
   
    public boolean isSingleToken() {
      return atLeft == atRight;
    }
   
  }
 
  protected static Token findFirstTokenAtOffset(String source, int startPos, final int offset) {
    assertTrue(startPos <= offset);
    DeeLexer lexer = new DeeLexer(source);
    lexer.reset(startPos);
    while(true) {
      Token token = lexer.next();
      if(offset <= token.getEndPos())
        return token;
      assertTrue(token.type != DeeTokens.EOF);
    }
  }
 
}
TOP

Related Classes of dtool.parser.common.LexerResult

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');