Синтаксис языков программирования. Нисходящий синтаксический анализ, процедурная и автоматная реализации, страница 8

  return true;

  }

  if((curWordIndex>=0)&&SelSet[45].get(curWordIndex)){

   curWordIndex=getWordIndex();

  return true;

  }

  if((curWordIndex>=0)&&SelSet[46].get(curWordIndex)){

   curWordIndex=getWordIndex();

  return true;

  }

  if((curWordIndex>=0)&&SelSet[47].get(curWordIndex)){

   curWordIndex=getWordIndex();

  return true;

  }

  return false;

 }

 public String getStatistic(int i){

  if(i==0)

   return " "+cCnt+" ";

  else

   return"";

 }

}

//end of Part_5

//Part_7: обработка HTTP-запроса, создание экземпляра синтаксического акцептора/анализатора

//start:

decoderEscaped dE=new decoderEscaped();

String qs="";

if((qs=request.getParameter("inputText"))==null)

 if(request.getQueryString()!=null)qs=new String(request.getQueryString());

if((qs!=null)&&(qs.length()>0))

  qs=dE.decode(qs).toString();

else qs="";

textReader str=new textReader(qs);

parser p=new parser(qs);

Программная реализация рекурсивного спуска:


public boolean parse(){

  int i,j,k,ss=0; //целые локальные переменные

  Vector r;       //для хранения текущего правила

  boolean back=false; //флажок необходимости отката

  stkItem si,ri; //элементы стека разбора

//весь входной поток складывается в список input

  while(true){

   curWordIndex=getWordIndex();

   if(curWordIndex==0) break;          //обнаружен конец входного потока

   if(curWordIndex<0) return false;   //если обнаружена лексическая ошибка - уходим, разбирать нечего

   input.add(new Integer(curWordIndex));

  }

  inputPos=0;  //установим указатель на первое слово

  si=new stkItem();si.sIndex=-1;si.rIndex=-1;si.pIndex=0;  //создаем элемент стека

//пишем в него индекс начального нетерминала, информацию о том, что никакое правило не применялось, и текущую входную позицию

  treeLevel.add(si);     //и заносим этот элемент в стек разбора

  while(true){  //организуем основной цикл

//ищем в стеке самый левый нетерминал, который можно чем-нибудь заменить, на случай неудачи поиска устанавливаем флаг отката

   for(back=true,i=0;i<treeLevel.size();i++){

    if((si=(stkItem)treeLevel.get(i)).sIndex<0){

     for(ss=si.sIndex,j=si.rIndex+1;j<rules.size();j++)          //ищем первое правило для этого нетерминала, которое еще не применялось в этой позиции стека разбора

      if(ss==((Integer)((Vector)rules.get(j)).get(0)).intValue())break;

     if(j<rules.size()){  //если нашли такое правило

      if(freeItems.size()>0)ri=(stkItem)freeItems.pop();        //если есть свободный элемент стека - возьмем его

      else ri=new stkItem();      //иначе создадим новый

      ri.sIndex=si.sIndex;ri.rIndex=j;ri.pIndex=i;backUp.push(ri);   //заполним элемент индексами слова, правила и позиции в стеке разбора и вставим его вместо элемента с нетерминалом в список откатов

      if((k=(r=(Vector)rules.get(j)).size())==1)          //если найденное правило имеет пустую правую часть

       {treeLevel.remove(i);freeItems.push(si);}        //удаляем элемент с нетерминалом из стека разбора

      else{         //иначе (правая часть правила не пуста)

       si.sIndex=((Integer)r.get(1)).intValue();si.rIndex=-1;si.pIndex=inputPos;      //вместо нетерминала из левой части пишем данные первого символа правой части

       for(j=2;j<k;j++){            //и для всех оставшихся символов правой части

        if(freeItems.size()>0)si=(stkItem)freeItems.pop();else si=new stkItem();     //берем свободный или создаем новый элемент стека

        si.sIndex=((Integer)r.get(j)).intValue();si.rIndex=-1;si.pIndex=inputPos;     //формируем его поля