編譯原理預測分析法
❶ 求助!編譯原理練習題
1、編譯方法中自底向上的語法分析演算法有:簡單優先分析演算法、算符優先分析演算法、SLR方法、LR(K)方法、LALR(K)方法,自頂向下的語法分析演算法有:遞歸子程序法、LL(K)分析算、預測分析方法。
2、詞法分析器的輸入是源程序的字元流,輸出是詞法記號流。
3、等價
4、(a|b)*(aa|bb)(a|b)*
❷ 編譯原理實現判斷是不是一個文法的句子
構造LL(1)語法分析程序,任意輸入一個文法符號串,並判斷它是否為文法的一個句子。程序要求為該文法構造預測分析表,並按照預測分析演算法對輸入串進行語法分析,判別程序是否符合已知的語法規則,如果不符合(編譯出錯),則輸出錯誤信息。
❸ 編譯原理語法分析中消除左遞歸的問題。比如A→Ab|c中為什麼說它是左遞歸呢,明明是A定義為Ab或者
A->Ab|c為什麼是左遞歸,和為什麼要消除左遞歸:
定義,就無需爭辯了。至於為什麼自頂向下文法不能處理左遞歸,解釋如下:
c∈FIRST(A),所以當預測分析的棧頂出現非終結符A,而輸入字元串最左邊為c時,就不知道用產生式A->Ab還是A->c了。無法構造預測分析表。比如輸入字元串為cbb,我們人當然容易知道是A->Ab->Abb->cbb了,但是電腦沒那麼聰明,如果不消除左遞歸,只有回溯了。
❹ 怎樣理解編譯原理
如果你在學編譯原理的話,你可以把它理解為一個編寫《編譯器》的時間課程~
當然,事實上,編譯原理的老師也是這么要求的~
編譯器就是把你編寫的源程序代碼變成程序可理解的二進制代碼的過程。
而把這個過程細化之後就可以歸納為:1、預處理過程(例如去掉不需要的空格、注釋之類的~)、2、詞法分析(就是把你寫的程序從頭到尾掃描一遍,識別出你的程序中所有的「單詞」,並編號記錄,按順序放在一張大的二維表中,一遍下一個處理過程用到~,當然,如果你的單詞有錯的話,還要做相應的出錯處理哈~)、3、語法分析(處理的是第二部中得到的單詞二維表,經過一定的演算法處理,可以得到一張成為預測分析表的東東~簡單的說就是按照預測分析表對一個個句子進行檢查,全部通過就進入下一關節,否則出錯處理)、4、語義分析、5、目標代碼的生成(這部分生成基本的與機器無關的單步執行的代碼)
之後的步驟就是與機器有關的東西了~目標代碼優化>匯編代碼生成>生成二進制代碼~
恩,差不多就是這么個流程,你可以再去針對自己感興趣的部分網路一下哈~
❺ 編譯原理語法分析器程序設計,用c語言或C++,哪裡有這個程序
1.文法簡略,沒有實現的部分,可以在此文法的基礎上進行擴充,本程序的採用自頂向下的LL(1)文法。
2.可以自動實現求First
集和
Follow
集。
3.處終結符外(有些硬編碼的成分),終結符的文法可以自定義,也就是說讀者可以自定義文法。
4.為方便理解,C語言的文法描述寫成中文。
5.程序將詞法分析和語法分析結合起來,詞法分析的結果作為語法分析的輸入。
6.最終結果在控制台顯示的有:詞法分析、First集、Follow集、Select集,在preciateResult.txt
中寫入了語法分析結果,在preciateTable.txt
中寫入了預測分析表。
7.文法的詞素之間必須有空格分開。
❻ 編譯原理單選題,求助!!!急!!!
西交《數字邏輯電路》在線作業免費答案
算符優先分析法每次都是對( )進行歸約:
A.句柄
B.最左素短語
C.素短語
D.簡單短語
正確答案:B
表達式-a+b*(-c+d)的逆波蘭式是( )。
A.ab+-cd+-*
B.a-b+c-d+*
C.a-b+c-d+*
D.a-bc-d+*+
正確答案:D
以( )作為輸出,允許自程序單獨編譯。
A.絕對機器代碼
B.可再定位機器語言
C.匯編語言程序
D.中間語言
正確答案:B
太多了,不打字了,剩下的加好友發給你剩下的吧。
❼ 學完編譯原理這門課,用c語言或者c++語言,編一個預測分析的程序,對預測分析也至少測試三個句子(含錯誤
我寫好的.
scan.h
/*
* scan.h
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#ifndef _SCAN_H_
#define _SCAN_H_
#include <string>
#include <fstream>
using namespace std;
typedef enum
{
ENDFILE,ERROR,
ELSE,IF,INT,RETURN,VOID,WHILE,
ID,NUM,
ASSIGN,EQ,LT,GT,LE,GE,NE,ADD,SUB,MUL,DIV,SEMI,LPAREN,RPAREN,LZK,RZK,LDK,RDK,COMMA
}
TokenType;
class Scan
{
private:
string tokenStr;
string linebuffer;
ifstream * in;
int linepos;
int lineno;
bool EOF_Flag;
bool traceScan;
void printToken(TokenType tt,const string &tok);
public:
Scan(ifstream * in)
{
this->in=in;
linepos=0;
linebuffer="";
lineno=0;
EOF_Flag=false
traceScan=true;
}
char getNextChar();
void ungetNextChar();
TokenType reservedLookup(string &s);
void setTraceScan(bool f);
bool getTraceScan();
TokenType getToken();
string getTokenStr();
};
#endif
scan.cpp
/*
* scan.cpp
* ccompiler
*
* Created by on 09-10-12.
* Copyright 2009 __MyCompanyName__. All rights reserved.
*
*/
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
#include "scan.h"
typedef enum
StateType;
static struct
{
string str;
TokenType tok;
} reservedWords[6]
=,,,,,};
char Scan::getNextChar()
{
if(linepos>=linebuffer.size())
{
if(getline(*in,linebuffer))
{
linebuffer+="\n";
lineno++;
linepos=0;
return linebuffer[linepos++];
}
else
{
EOF_Flag=true;
return EOF;
}
}
else
return linebuffer[linepos++];
}
void Scan::ungetNextChar()
{
if(!EOF_Flag) linepos--;
}
TokenType Scan::reservedLookup(string &s)
{
for(int i=0;i<6;i++)
if(s==reservedWords[i].str)
return reservedWords[i].tok;
return ID;
}
void Scan::setTraceScan(bool f)
{
traceScan=f;
}
bool Scan::getTraceScan()
{
return traceScan;
}
TokenType Scan::getToken()
{
tokenStr="";
TokenType currentToken;
StateType state=START;
while(state!=DONE)
{
bool save=false;
char c=getNextChar();
switch (state) {
case START:
if(c>='0'&&c<='9'){
state=INNUM;
save=true;
}
else if((c>='a'&&c<='z')||(c>='A'&&c<='Z')){
state=INID;
save=true;
}
else if(c==' '||c=='\t'||c=='\n')
{
state=START;
}
else if(c=='/'){
state=SLASH;
}
else if(c=='='){
state=TEMPE;
}
else if(c=='>')
state=TEMPG;
else if(c=='<')
state=TEMPL;
else if(c=='!')
state=INNOTEQ;
else
{
state=DONE;
switch (c) {
case EOF:
currentToken=ENDFILE;
break;
case '+':
currentToken=ADD;
break;
case '-':
currentToken=SUB;
break;
case '*':
currentToken=MUL;
break;
case '(':
currentToken=LPAREN;
break;
case ')':
currentToken=RPAREN;
break;
case '[':
currentToken=LZK;
break;
case ']':
currentToken=RZK;
break;
case '{':
currentToken=LDK;
break;
case '}':
currentToken=RDK;
break;
case ';':
currentToken=SEMI;
break;
case ',':
currentToken=COMMA;
break;
default:
currentToken=ERROR;
break;
}
}
break;
case INNUM:
if(c<'0'||c>'9')
{
ungetNextChar();
state=DONE;
currentToken=NUM;
}
else
save=true;
break;
case INID:
if(!((c>='a'&&c<='z')||(c>='A'&&c<='Z')))
{
ungetNextChar();
state=DONE;
currentToken=ID;
}
else
save=true;
break;
case SLASH:
if (c!='*')
{
state=DONE;
currentToken=DIV;
}
else
state=INCOMMENT1;
break;
case INCOMMENT1:
if (c!='*')
state=INCOMMENT1;
else if(c==EOF){
state=DONE;
currentToken=ENDFILE;
}
else
state=INCOMMENT2;
break;
case INCOMMENT2:
if (c=='*') {
state=INCOMMENT2;
}else if(c=='/'){
state=START;
}else if(c==EOF){
state=DONE;
currentToken=ENDFILE;
}else {
state=INCOMMENT1;
}
break;
case TEMPE:
if (c=='=') {
state=DONE;
currentToken=EQ;
}else{
state=DONE;
ungetNextChar();
currentToken=ASSIGN;
}
break;
case TEMPG:
if (c=='=') {
state=DONE;
currentToken=GE;
}else{
state=DONE;
ungetNextChar();
currentToken=GT;
}
break;
case TEMPL:
if (c=='=') {
state=DONE;
currentToken=LE;
}else{
state=DONE;
ungetNextChar();
currentToken=LT;
}
break;
case INNOTEQ:
if (c=='=') {
state=DONE;
currentToken=NE;
}else {
state=DONE;
ungetNextChar();
currentToken=ERROR;
}
break;
default:
cerr<<"Scanner Bug: state= "<<state<<endl;
state=DONE;
currentToken=ERROR;
break;
}
if(save){
string newChar(1,c);
tokenStr+=newChar;
}
if (state==DONE&¤tToken==ID)
currentToken=reservedLookup(tokenStr);
}
if (traceScan) {
cout<<"Scan at line "<<lineno<<" token: ";
printToken(currentToken, tokenStr);
cout<<endl;
}
return currentToken;
}
string Scan::getTokenStr()
{
return tokenStr;
}
void Scan::printToken(TokenType tt,const string &tok)
{
string type;
switch (tt) {
case ENDFILE:
type="EOF";
break;
case ERROR:
type="ERROR";
break;
case ELSE:
case IF:
case INT:
case RETURN:
case VOID:
case WHILE:
type="reserved word";
break;
case ID:
type="ID";
break;
case NUM:
type="NUM";
break;
case ASSIGN:
type="=";
break;
case EQ:
type="==";
break;
case LT:
type="<";
break;
case GT:
type=">";
break;
case LE:
type="<=";
break;
case GE:
type=">=";
break;
case NE:
type="!=";
break;
case ADD:
type="+";
break;
case SUB:
type="-";
break;
case MUL:
type="*";
break;
case DIV:
type="/";
break;
case SEMI:
type=";";
break;
case LPAREN:
type="(";
break;
case RPAREN:
type=")";
break;
case LZK:
type="[";
break;
case RZK:
type="]";
break;
case LDK:
type="{";
case RDK:
type="}";
break;
case COMMA:
type=",";
break;
default:
break;
}
cout << type<<": "<<tok;
}
main.cpp
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
#include "scan.h"
int main (int argc, char * const argv[]) {
string fileName="/Users/huanglongyin/scan_in.txt";
//cout<< "File name: ";
//cin>>fileName;
ifstream in(fileName.c_str());
if(!in){
cerr<<"Error occurs when openning file "<<fileName<<endl;
return -1;
}
Scan scan(&in);
while(scan.getToken()!=ENDFILE);
return 0;
}
❽ 在從上到下的語法分析中,預測分析法與遞歸下降法各有什麼優點和缺點
你說的應該是編譯原理吧。 遞歸下降分析程序的實現思想是:識別程序由一組子程序組成。每個子程序對應於一個非終結符號。 每一個子程序的功能是:選擇正確的右部,掃描完相應的字。在右部中有非終結符號時,調用該非終結符號對應的子程序來完成。 所以,當有左遞歸出現時,遞歸下降分析程序就會出現回朔,將可能產生無限的循環,所以遞歸下降分析的前提條件之一就是消除左遞歸。
❾ 編譯原理:預測分析法判斷輸入串i*i+i是否是文法G3的句子
不管什麼法,有表就是查表。 分析自頂向下,搞個棧 ,再搞個輸入:
#E i*i+i$
#E'T i*i+i$
#E'T'F i*i+i$
#E'T'i i*i+i$ 匹配i
#E'T' *i+i$
#E'T'F* *i+i$ 匹配*
#E'T'F i+i$
#E'T'i i+i$ 匹配i
#E'T' +i$
#E' +i$
#E'T+ +i$ 匹配+
#E'T i$
#E'T'F i$
#E'T'i i$ 匹配i
#E'T' $
#E' $
# $ 接受
這樣OK?
❿ 求 編譯原理 語法分析程序
可以參考我的空間,我在三年前寫過類似代碼。
http://hi..com/逄韶華/ihome/myblog