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

org.snapscript.parse.MatchFirstGrammar Maven / Gradle / Ivy

There is a newer version: 1.4.6
Show newest version
package org.snapscript.parse;

import java.util.ArrayList;
import java.util.List;

import org.snapscript.common.BitSet;
import org.snapscript.common.SparseArray;

public class MatchFirstGrammar implements Grammar {
   
   private final List grammars;
   private final String name;
   private final int index;
   
   public MatchFirstGrammar(List grammars, String name, int index) {
      this.grammars = grammars;
      this.index = index;
      this.name = name;
   }       

   @Override
   public GrammarMatcher create(GrammarCache cache, int length) {
      List matchers = new ArrayList();
      
      for(Grammar grammar : grammars) {
         GrammarMatcher matcher = grammar.create(cache, length);
         matchers.add(matcher);
      }
      return new MatchFirstMatcher(matchers, name, index, length);
   } 
   
   private static class MatchFirstMatcher implements GrammarMatcher {
      
      private final SparseArray cache;
      private final List matchers;
      private final BitSet failure;
      private final String name;
      private final int index;
      
      public MatchFirstMatcher(List matchers, String name, int index, int length) {
         this.cache = new SparseArray(length);
         this.failure = new BitSet(length);
         this.matchers = matchers;
         this.index = index;
         this.name = name;
      }    
   
      @Override
      public boolean check(SyntaxChecker checker, int depth) {
         int position = checker.position();
         
         if(!failure.get(position)) {
            GrammarMatcher best = cache.get(position);
            
            if(best == null) {
               int mark = checker.mark(index);
                  
               for(GrammarMatcher matcher : matchers) {
                  if(matcher.check(checker, depth + 1)) {
                     cache.set(position, matcher);
                     return true;
                  }               
               }                  
               failure.set(position);  
               checker.reset(mark, index);
            }  
            if(best != null) {            
               if(!best.check(checker, 0)) {
                  throw new ParseException("Could not read node in " + name);  
               }     
               return true;
            } 
         }
         return false;
      }
      
      @Override
      public boolean build(SyntaxBuilder builder, int depth) {
         int position = builder.position();
         
         if(!failure.get(position)) {
            GrammarMatcher best = cache.get(position);
            
            if(best == null) {
               for(GrammarMatcher matcher : matchers) {
                  if(matcher.build(builder, depth + 1)) {
                     cache.set(position, matcher);
                     return true;
                  }               
               }                  
               failure.set(position);            
            }
            if(best != null) {            
               if(!best.build(builder, 0)) {
                  throw new ParseException("Could not read node in " + name);  
               }     
               return true;
            }      
         }
         return false;
      }
      
      @Override
      public String toString() {
         return String.format("{%s}", matchers);
      }    
   }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy