Package org.antlr.analysis

Source Code of org.antlr.analysis.LL1DFA

/*
* [The "BSD license"]
*  Copyright (c) 2010 Terence Parr
*  All rights reserved.
*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*  1. Redistributions of source code must retain the above copyright
*      notice, this list of conditions and the following disclaimer.
*  2. Redistributions in binary form must reproduce the above copyright
*      notice, this list of conditions and the following disclaimer in the
*      documentation and/or other materials provided with the distribution.
*  3. The name of the author may not be used to endorse or promote products
*      derived from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
*  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
*  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
*  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
*  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
*  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
*  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.analysis;

import org.antlr.grammar.v3.ANTLRParser;
import org.antlr.misc.IntervalSet;
import org.antlr.misc.MultiMap;

import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/** A special DFA that is exactly LL(1) or LL(1) with backtracking mode
*  predicates to resolve edge set collisions.
*/
public class LL1DFA extends DFA {
  /** From list of lookahead sets (one per alt in decision), create
   *  an LL(1) DFA.  One edge per set.
   *
   *  s0-{alt1}->:o=>1
   *  | \
   *  |  -{alt2}->:o=>2
   *  |
   *  ...
   */
  @SuppressWarnings("OverridableMethodCallInConstructor")
  public LL1DFA(int decisionNumber, NFAState decisionStartState, LookaheadSet[] altLook) {
    DFAState s0 = newState();
    startState = s0;
    nfa = decisionStartState.nfa;
    nAlts = nfa.grammar.getNumberOfAltsForDecisionNFA(decisionStartState);
    this.decisionNumber = decisionNumber;
    this.decisionNFAStartState = decisionStartState;
    initAltRelatedInfo();
    unreachableAlts = null;
    for (int alt=1; alt<altLook.length; alt++) {
      DFAState acceptAltState = newState();
      acceptAltState.acceptState = true;
      setAcceptState(alt, acceptAltState);
      acceptAltState.k = 1;
      acceptAltState.cachedUniquelyPredicatedAlt = alt;
      Label e = getLabelForSet(altLook[alt].tokenTypeSet);
      s0.addTransition(acceptAltState, e);
    }
  }

  /** From a set of edgeset&rarr;list-of-alts mappings, create a DFA
   *  that uses syn preds for all |list-of-alts|&gt;1.
   */
  @SuppressWarnings("OverridableMethodCallInConstructor")
  public LL1DFA(int decisionNumber,
          NFAState decisionStartState,
          MultiMap<IntervalSet, Integer> edgeMap)
  {
    DFAState s0 = newState();
    startState = s0;
    nfa = decisionStartState.nfa;
    nAlts = nfa.grammar.getNumberOfAltsForDecisionNFA(decisionStartState);
    this.decisionNumber = decisionNumber;
    this.decisionNFAStartState = decisionStartState;
    initAltRelatedInfo();
    unreachableAlts = null;
    for (Map.Entry<IntervalSet, List<Integer>> entry : edgeMap.entrySet()) {
      IntervalSet edge = entry.getKey();
      List<Integer> alts = entry.getValue();
      Collections.sort(alts); // make sure alts are attempted in order
      //System.out.println(edge+" -> "+alts);
      DFAState s = newState();
      s.k = 1;
      Label e = getLabelForSet(edge);
      s0.addTransition(s, e);
      if ( alts.size()==1 ) {
        s.acceptState = true;
        int alt = alts.get(0);
        setAcceptState(alt, s);
        s.cachedUniquelyPredicatedAlt = alt;
      }
      else {
        // resolve with syntactic predicates.  Add edges from
        // state s that test predicates.
        s.resolvedWithPredicates = true;
        for (int i = 0; i < alts.size(); i++) {
          int alt = (int)alts.get(i);
          s.cachedUniquelyPredicatedAlt =  NFA.INVALID_ALT_NUMBER;
          DFAState predDFATarget = getAcceptState(alt);
          if ( predDFATarget==null ) {
            predDFATarget = newState(); // create if not there.
            predDFATarget.acceptState = true;
            predDFATarget.cachedUniquelyPredicatedAlt =  alt;
            setAcceptState(alt, predDFATarget);
          }
          // add a transition to pred target from d
          /*
          int walkAlt =
            decisionStartState.translateDisplayAltToWalkAlt(alt);
          NFAState altLeftEdge = nfa.grammar.getNFAStateForAltOfDecision(decisionStartState, walkAlt);
          NFAState altStartState = (NFAState)altLeftEdge.transition[0].target;
          SemanticContext ctx = nfa.grammar.ll1Analyzer.getPredicates(altStartState);
          System.out.println("sem ctx = "+ctx);
          if ( ctx == null ) {
            ctx = new SemanticContext.TruePredicate();
          }
          s.addTransition(predDFATarget, new Label(ctx));
          */
          SemanticContext.Predicate synpred =
            getSynPredForAlt(decisionStartState, alt);
          if ( synpred == null ) {
            synpred = new SemanticContext.TruePredicate();
          }
          s.addTransition(predDFATarget, new PredicateLabel(synpred));
        }
      }
    }
    //System.out.println("dfa for preds=\n"+this);
  }

  protected Label getLabelForSet(IntervalSet edgeSet) {
    Label e;
    int atom = edgeSet.getSingleElement();
    if ( atom != Label.INVALID ) {
      e = new Label(atom);
    }
    else {
      e = new Label(edgeSet);
    }
    return e;
  }

  protected SemanticContext.Predicate getSynPredForAlt(NFAState decisionStartState,
                             int alt)
  {
    int walkAlt =
      decisionStartState.translateDisplayAltToWalkAlt(alt);
    NFAState altLeftEdge =
      nfa.grammar.getNFAStateForAltOfDecision(decisionStartState, walkAlt);
    NFAState altStartState = (NFAState)altLeftEdge.transition[0].target;
    //System.out.println("alt "+alt+" start state = "+altStartState.stateNumber);
    if ( altStartState.transition[0].isSemanticPredicate() ) {
      SemanticContext ctx = altStartState.transition[0].label.getSemanticContext();
      if ( ctx.isSyntacticPredicate() ) {
        SemanticContext.Predicate p = (SemanticContext.Predicate)ctx;
        if ( p.predicateAST.getType() == ANTLRParser.BACKTRACK_SEMPRED ) {
          /*
          System.out.println("syn pred for alt "+walkAlt+" "+
                     ((SemanticContext.Predicate)altStartState.transition[0].label.getSemanticContext()).predicateAST);
          */
          if ( ctx.isSyntacticPredicate() ) {
            nfa.grammar.synPredUsedInDFA(this, ctx);
          }
          return (SemanticContext.Predicate)altStartState.transition[0].label.getSemanticContext();
        }
      }
    }
    return null;
  }
}
TOP

Related Classes of org.antlr.analysis.LL1DFA

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.