編譯原理文法規則處理
⑴ 編譯原理簡單文法歸約計算
編譯原理中的語法和文法是不一樣的,但卻融會貫通。
在計算機科學中,文法是編譯原理的基礎,是描述一門程序設計語言和實現其編譯器的方法。
文法分成四種類型,即0型、1型、2型和3型。這幾類文法的差別在於對產生式施加不同的限制。
形式語言,這種理論對計算機科學有著深刻的影響,特別是對程序設計語言的設計、編譯方法和計算復雜性等方面更有重大的作用。
多數程序設計語言的單詞的語法都能用正規文法或3型文法(3型文法G=(VN,VT,P,S)的P中的規則有兩種形式:一種是前面定義的形式,即:A→aB或A→a其中A,B∈VN ,a∈VT*,另一種形式是:A→Ba或A→a,前者稱為右線性文法,後者稱為左線性文法。正規文法所描述的是VT*上的正規集)來描述。
四個文法類的定義是逐漸增加限制的,因此每一種正規文法都是上下文無關的,每一種上下文無關文法都是上下文有關的,而每一種上下文有關文法都是0型文法。稱0型文法產生的語言為0型語言。上下文有關文法、上下文無關文法和正規文法產生的語言分別稱為上下文有關語言、上下文無關語言和正規語言。
⑵ 規約的編譯原理
推導的逆過程稱為規約。規約就是選擇一個文法規則:X→ABC,依次從棧頂彈出C、B、A,再將X壓進棧。規范規約是文法中句子的一個最右推導的逆過程,而最左推導對應的是最右規約 。
另外在程序設計中的規約:∏和∏'是兩個判定性問題,如果存在一個確定性演算法A使得對於一個∏的實例I,A可以將I在多項式時間里轉換成∏'的實例P,使得I得到肯定的回答,當且僅當I'得到肯定回答,則稱∏在多項式時間里規約到∏',記為∏∝poly∏'.
⑶ 編譯原理文法分析
改完了,能文法分析出來了!!
大概 跟你說下 你的錯誤吧:
出錯地點:
1.聲明的stack[50]沒有初始化;
2.stack的入棧是錯誤的,按照你的方式,如果原來有TM,再加入T->FN,則M就被擠出來了.(這里很關鍵,你對照我給你改的再看看)
3.s指針在你入棧操作以後並沒有指向棧頂,而是保持了不變,這肯定是有問題的.(傳入push函數的時候直接傳參數s就好了.)
4.if(*s==*p){***}else{}的else的右括弧管轄的范圍 有錯誤
不嫌棄的話,可以去http://blog.csdn.net/fangguanya,我的BLOG,不怎麼充實,呵呵,有這個程序的運行結果的. 謝謝 呵呵.
總之你對照我給你改的再看看吧. 我把我的測試輸出 也給保留了.你好對照點.
(PS.我用的vs2005,用的時候你改下頭申明,其他一樣)
// grammar.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<iostream>
using namespace std;
char * spush(char *stack,char *pt);
bool analyse(char *p);
void main()
{
//將分析串存放在二維數組中
char input[5][10]={"i+i#",
"i*(i+i)#",
"i*i+i#",
"i+*#",
"+i*i#"};
bool flag; //定義一個布爾型的標記量
for(int h=0;h<5;++h)
{
flag=analyse(input[h]);
if(flag) cout<<"恭喜你!"<<input[h]<<"語法分析成功,合法!"<<endl;
else cout<<"對不起!"<<input[h]<<"語法分析失敗,非法!"<<endl;
}
int aaa;
cin>>aaa;
}
//定義各一將串逆序入棧的函數
char * spush(char *stack,char *pt)
{
int l=0;
//while循環的作用是將指針指向字元串的末尾,然後再由後向前入棧,從而實現逆序
while(*pt!='\0')
{
pt++;
l++;
}
if (*stack == '#')
{
stack++;
}
while(l)
{
pt--;
char cTempIntoStack = (*pt);
*stack=cTempIntoStack;
stack++;
l--;
}
stack--; //由於前面向前加了一位,要返回
////////////////
return stack;
///////////////////////////////////
}
/*LL(1)分析表
i + * ( ) #
E TM +TM
F i (E)
M TM e e
N e *FN e e
T FN FN
*/
//分析函數
bool analyse(char *p){
char analyseTable[5][6][4]={
"TM", "", "", "TM", "", "",
"i", "", "", "(E)", "", "",
"", "+TM", "", "", "e", "e",
"", "e", "*FN", "", "e", "e",
"FN", "", "", "TN", "", ""
};
char *stack = new char[50]; //定義一個棧空間
for (int iStack = 0;iStack<50 ;iStack++)
{
stack[iStack] = 0;
}
char *s=stack; //用指針*s指向棧的起始地址
*s='#'; //將「#」入棧
s++; //指針加1
*s='E'; //將「E」入棧
//下面的while循環實現字元串的詞法分析操作
int count = 0;
while(*s!='#' || *p!='#'){
count++;
char * temp = s;
cout<<"NO."<<count<<endl;
cout<<"STACK"<<endl;
while (*temp != '#')
{
cout<<*temp<<" ";
temp--;
}
cout<<endl;
int x,y;
//若果棧頂數據和分析串的字元匹配,則將符號棧的棧頂數據出棧(即將棧頂指針減1)
if(*s==*p){
cout<<"Before :"<<*s<<endl;
s--;
p++;
cout<<"After :"<<*s<<endl;
}
//當符號棧和分析串的字元不匹配時,查分析表
else {
switch(*s){
case 'E':x=0;break;
case 'F':x=1;break;
case 'M':x=2;break;
case 'N':x=3;break;
case 'T':x=4;break;
default:return false;
}
switch(*p){
case 'i':y=0;break;
case '+':y=1;break;
case '*':y=2;break;
case '(':y=3;break;
case ')':y=4;break;
case '#':y=5;break;
default:return false;
}
//若果對應的為空,則分析串非法,退出
if(analyseTable[x][y][0]=='\0') return false;
//若查表所對應的為'e',則將符號棧的棧頂數據出棧
else if(analyseTable[x][y][0]=='e') s--;
//其它,這時將查表所得的項逆序入符號棧
else {
s=spush(s,analyseTable[x][y]);
}
}
}
return true; //分析成功,返回
}
⑷ 編譯原理中如何用c語言來編寫程序判斷輸入的字元串是否符合文法規則
LEX可以進行詞法分析。
如果要自己寫,主要是把正則文法轉化為自動機,根據輸入串進行狀態轉移。
⑸ 編譯原理中如何用c語言來編寫程序判斷輸入的字元串是否符合文法規則
scanf()有返回值,若返回值是0,則不符合文法規則
一般情況下,scanf()返回值是輸入的字元數
⑹ 編譯原理,為文法添加語義規則,求圖片上題的詳細解答過程,越細越好,完全不會啊,求大神指導。。
每個產生式後面{ }中的內容即語義子程序。
給每個非終結符設計一個語義值VAL,表示該非終結符對應的值
⑺ 編譯原理中文法二義性問題
二義性文法
【定義】 若文法中存在這樣的句型,它具有兩棵不同的語法樹,則稱該文法是二義性文法。
二義性文法會引起歧義,應盡量避免之!
E E
E + E E * E
i E * E E + E i
i i i i
都可以表示i+i*i
所以G(E):E -> E+E | E*E | (E) | i ;文法具有二義性。
文法二義性的消除:
【方法1】不改變文法的原有規則,加進一些非形式規定。
加進運算符的優先順序和結合規則對G(E),規定*優於+,*和+服從左結合
【方法2】構造一個等價的無二義性文法,將排除 二義性的規則合並到文法中
G(E) -> G´(E) : E -> E+T | T T -> T*F | F F -> (E) | i ;
⑻ 編譯原理中的語法和文法一樣嗎
編譯原理中的語法和文法是不一樣的,但卻融會貫通。
在計算機科學中,文法是編譯原理的基礎,是描述一門程序設計語言和實現其編譯器的方法。
文法分成四種類型,即0型、1型、2型和3型。這幾類文法的差別在於對產生式施加不同的限制。
形式語言,這種理論對計算機科學有著深刻的影響,特別是對程序設計語言的設計、編譯方法和計算復雜性等方面更有重大的作用。
多數程序設計語言的單詞的語法都能用正規文法或3型文法(3型文法G=(VN,VT,P,S)的P中的規則有兩種形式:一種是前面定義的形式,即:A→aB或A→a其中A,B∈VN ,a∈VT*,另一種形式是:A→Ba或A→a,前者稱為右線性文法,後者稱為左線性文法。正規文法所描述的是VT*上的正規集)來描述。
四個文法類的定義是逐漸增加限制的,因此每一種正規文法都是上下文無關的,每一種上下文無關文法都是上下文有關的,而每一種上下文有關文法都是0型文法。稱0型文法產生的語言為0型語言。上下文有關文法、上下文無關文法和正規文法產生的語言分別稱為上下文有關語言、上下文無關語言和正規語言。
⑼ 編譯原理的文法是什麼
文法是描述語言規則的形式規則。實際上就是用一個四元組G=(VT,VN,S,P)定義的一個推理方式。其中VT是終結符,VN是非終結符,S是開始符號,P是一組產生規則。
⑽ 如何由文法推導語法樹(編譯原理)
語法樹,是針對上下文無關文法,用來表示一個句型的生成過程的一種描述手段。
對於給定的句型,依據文法構造它的語法樹,是語法分析的任務。
編譯原理課程中重點學習的各種語法分析方法,都是解決語法樹的構造的具體分析方法。
在學習並掌握各種語法分析方法之前,一般只能依據直覺印象,通過猜測、拼湊等手段,去試著推演,湊出符合要求的句型的語法樹。所以這個階段練慣用的題目一般也不很復雜,通過多多練習也能找到一些技巧(其實主要是後面將要學習的自頂向下語法分析中的一些原則)。
對於給定的文法,有一些句型可能能構建出兩棵甚至多棵結構不同的語法樹,結果不一定是唯一的。這樣的文法就是所謂的二義性文法。
對於非二義性文法而言,任意一個句型的語法樹都是唯一的。