清華大學電腦系列教材
編譯原理第二版
張素琴,呂映芝等編著
P56 5.6 典型例題及解答 例題一為例,進行預測性分析
tip:預測性分析法和迴歸分析法都是自頂向下的方法,預測性分析法只能分析滿足LL1的文法
簡單樣本,為清楚原理
//課本P96 例1</p><p>#include "stdafx.h"<br />#include <stdio.h><br />#include <iostream><br />#define MAXLEN 100 //棧的最大容量<br />using namespace std;</p><p>int analysisStack[MAXLEN]={0,30};//分析棧</p><p>//略過詞法分析階段<br />//int shuru[MAXLEN]={1,1,1,2,3,0};//匹配<br />//int shuru[MAXLEN]={1,1,2,3,0};//不匹配<br />int shuru[MAXLEN]={1,3,0};//匹配</p><p>int inputLength=0; //輸入串的長度<br />int leftString[MAXLEN]={};//剩餘輸入串</p><p>//定義產生式,根據題意,7條BNF,共7個產生式。每條最大長度不超過10<br />//右邊的第一個符號為終結符<br />int product[10][10]={<br />{30,1,31,0},<br />{31,1,32,3,0},<br />{31,3,0},<br />{32,1,32,2,0},<br />{32,4,0},<br />{32,0},<br />{33,1,32,0},<br />{33,4,0},<br />};</p><p>void setLeftString()//設定剩餘輸入串,即要分析的字串,詞法分析的結果<br />{<br />while (shuru[inputLength]!=0)<br />{<br />inputLength++;<br />}<br />int j=0;//指向分析串的指標,暫時的<br />for (j=0;j<=inputLength;j++)<br />{<br />leftString[j]=shuru[inputLength-j];<br />}<br />}<br />void outputAnalysis()//輸出分析棧的內容<br />{<br />printf("/n分析棧的內容:");<br />for (int i=1;i<MAXLEN;i++)<br />{<br />if (analysisStack[i]!=0)//列印非0元素<br />{<br />printf("%d,",analysisStack[i]);<br />}<br />}<br />}<br />void outputLeftString()//輸出剩餘串<br />{<br />printf("/n剩餘輸入串:");<br />for (int i=1;i<MAXLEN;i++)<br />{<br />if (leftString[i]!=0)//列印非0元素<br />{<br />printf("%d,",leftString[i]);<br />}<br />}<br />}</p><p>int _tmain(int argc, _TCHAR* argv[])<br />{<br />setLeftString();</p><p>int pointer1=1;//分析棧的指標<br />int pointer2=inputLength;//待分析串的指標</p><p>outputAnalysis();<br />outputLeftString();</p><p>int fenxicishu=0;//分析次數<br />while(fenxicishu<=20)//最多分析次數<br />{<br />printf("/n/n第%d次分析結果:",fenxicishu+1);<br />if (analysisStack[pointer1]==0 && leftString[pointer2]==0)//棧空,結束<br />{<br />printf("棧空/n");<br />break;<br />}<br />else<br />{<br />if (analysisStack[pointer1]==leftString[pointer2])//分析棧起始符號和剩餘輸入串起始符號匹配<br />{<br />printf("/n匹配");<br />analysisStack[pointer1]=0;<br />pointer1--;<br />leftString[pointer2]=0;<br />pointer2--;<br />fenxicishu++;<br />}<br />else<br />{<br />printf("/n不匹配,");<br />for(int i=0;i<10;i++)//產生式個數<br />{<br />if(analysisStack[pointer1]==product[i][0])//左邊匹配<br />{<br />if (pointer1-pointer2==1)<br />{<br />analysisStack[pointer1]=0;//選擇產生式->e<br />pointer1--;<br />break;<br />}<br />int k=i;//左邊相同的產生式<br />while (analysisStack[pointer1]==product[k][0])//左邊相同的產生式<br />{<br />if (leftString[pointer2]==product[k][1])//右邊以匹配的終結符開始<br />{<br />break;<br />}<br />k++;<br />}<br />i=k;</p><p>printf("找到產生式:%d->",product[i][0]);<br />int productLength=0;//產生式的長度<br />while(product[i][productLength]!=0)<br />{<br />productLength++;<br />printf("%d ",product[i][productLength]);<br />}</p><p>for (int j=1;j<productLength;j++)//產生式的長度<br />{<br />analysisStack[j+pointer1-1]=product[i][productLength-j];<br />}<br />pointer1=pointer1+productLength-2;<br />}<br />}<br />}<br />outputAnalysis();<br />outputLeftString();<br />fenxicishu++;<br />}<br />}<br />if(analysisStack[1]!=0 || leftString[1]!=0 )<br />{<br />printf("/n/n分析了%d次,仍沒成功匹配/n/n",fenxicishu);<br />}<br />else<br />{<br />printf("/n/n成功匹配!!/n/n");<br />}</p><p>system("pause");<br />return 0;<br />}</p><p>