㈠ C加加用哪個編譯器測試
vc6.0, vs2013,2015, dev cpp, codeblocks等。
㈡ C#編寫的編譯器,實現詞法分析和語法分析功能!!求運行文件和代碼示例!!
算你強。C#的編譯器roslyn開源了,有空你自己去研究下吧。
dotnet/roslyn
https://github.com/dotnet/roslyn
㈢ 編寫程序,程序是人寫,編譯器卻測試,它怎麼知道在哪裡寫錯了,
因為它有自己的規則,你不按規則寫程序就要報錯唄
㈣ c語言編程怎麼測試程序的對錯
編譯器會根據C語言的規則來判斷你是否有語法錯誤,但是不能判斷語意錯誤,即設計錯誤。
㈤ 求一個盡量完整的編譯器:詞法分析器+語法分析器
在一個模式被匹配之前,詞法分析器往往需要超前掃描該詞素後面的若干個字元,使用將字元退回輸入流的方法,需要移動大量字元的時間,由於 詞法分析器是編譯期間唯一需要逐一掃描源程序字元的過程,因此它的效率將極大的影響編譯器的性能,因此人們發明了雙緩沖區的技術。
雙緩沖區技術原理如下:
把一個緩沖區分成前後兩個部分,每部分能夠容納N(1024/4096)個字元,每次系統讀命令讀入N個字元到前半部分或者後半部分,如果剩餘的不足N個字元,則在最後增加一個不同於其他任何字元的字元,如eof/#,用於標識源文件的結束。緩沖區包括兩個指針beginning和forward,在兩個指針之間的字元串就是當前的詞素。一開始兩個指針都指向第一個字元,然後forward向後掃描,直至發現一個匹配的詞素為止。如果forward跨過中間標記,則往後半部分讀入N個字元。如果forward指針移過最後位置,則向前半部分讀入N個字元,且forward指針重新指向開始繼續處理過程。為了處理方便在兩個部分的最後都增加一個文件結束標識eof。示意圖如下:
______________________________________________________________________
|............for......while.... ........................................ |....int i .................................................. ...................| |_______________________________eof|_______________eof________________eof|
| |
beginning forward
下面是雙緩沖區的一個c實現:
#include <stdio.h>
#include <string.h>
#define MAXWORD 1000
struct bibuffer
{
char* buffer[2048]; //緩沖區空間
char* beginning,forward; //前向和後向指針
int count; //前向指針記數
} bbuf;
void parse(char c)
{
if(c=' ')
{
memcpy(word[i],beginning,(size_t)(forward-beginning));
i++;
}
else forward++;
}
int main(int argc,char* argv)
{
File* fp;
char* word[MAXWORD];
int i=0;
buffer=new char[2048];
fp=open("test.c","r");
read(fp,buffer,1023);
buffer[1023]='#';
read(fp,buffer+1024,1023);
buffer[2047]='#';
bbuf->buffer=buffer;
bbuf->beginning=bbuf->forward=bbuf->buffer;
bbuf->count=0;
while(1)
{
forward=forward+1;
if(count==1023)
{
read(fp,buffer+1024,1023);
forward++;
//這個函數的具體代碼就要和具體的詞法分析規則而定,這里假設只識別空格分割的單詞
parse(*forward);
}
else if(count>=2048)
{
read(fp,buffer,1023);
forward=bbuf->buffer;
//這個函數的具體代碼就要和具體的詞法分析規則而定,這里假設只識別空格分割的單詞
parse(*forward);
}
else if(count!=1023&&count<2048&&(*forward)='#')
{
break; //詞法分析結束
}
}
}
㈥ 為什麼編譯器需要復雜的語法
新的版本都是基於舊的版本升級過來的,以此來改善編譯器的性能、增加對新平台的支持以及提高競爭能力。不同的編譯器支持的標准語法是一致的(不然沒資格稱C編譯器),但是每個編譯器自身可以添加額外的語法、庫來擴展語言的表達能力,這就是所謂的xx編譯器擴展。使用語言擴展通常能獲得較高的性能和靈活性,但是損失了跨平台性。不僅僅是編譯器有很多版本,語言本身都有很多版本,目前C語言的版本是C11,下一個版本為C1y。
㈦ 編譯器本身是如何進行測試的
編譯器最重要的性質就是保證語義的正確。比如,從高級語言翻譯到機器指令之後,指令必須正確的表達原來程序的意思。所以一般編譯器測試都包含一些源程序,用來覆蓋可能出現的各種情況。基本的原則是:原來程序的結果 = 編譯後機器指令運行的結果。機器指令運行的結果很容易知道,運行一下就知道了。可是原來程序的結果你怎麼知道呢?
為了解決這個「原來程序語義」的問題,最好是寫一個解釋器,准確無誤的表達原來的代碼的語義。所以我們的要求就是:
高級語言解釋器(源程序) = 機器執行(機器代碼)
由於處理器其實就是一個用來執行機器代碼的解釋器,這里有一個很美好的對稱關系:
interp1(L1) = interp2(L2)
另外還有一個問題,就是編譯器一般需要經過多個轉化步驟(叫做 pass)才能最後編譯為機器指令。比如,
L2 = pass1(source)
L3 = pass2(L2)
L4 = pass3(L3)
Ln = passN(Ln-1)
machine_code = codegen(Ln)
由於源程序經過了很多步驟猜得到最後的機器指令,如果你使用上面的公式,就會出現以下一些情況:
1. 知道結果錯了,但是卻不知道到底是哪一個 pass 錯了。
2. 結果沒有錯,但是中間卻有 pass 實際上是錯的。但是由於之前的 pass 把輸入程序的一些結構給「優化」掉了,所以錯的那個 pass 其實沒能得到觸發錯誤的那個數據結構。所以測試沒能發現錯誤。如果以後前面的那個 pass 被修改,錯誤就會暴露出來。這是非常難以發現的潛伏的危險。
為了防止這些情況出現,一些編譯器(比如 Chez Scheme 和 Kent Dybvig 的課程編譯器)使用了對每一個 pass 進行測試的做法。具體的方法就是為每一個中間語言都寫一個解釋器,把這語言的語義完全的表示出來。這樣我們就需要檢查一組等式:
L2 = pass1(source)
高級語言編譯器(源程序) = interp2(L2) // 測試 pass1 的正確性
L3 = pass2(L2)
interp2(L2) = interp3(L3) // 測試 pass2 的正確性
這樣一來我們就能獨立的判斷每一個 pass 的正確性了。
這些是基本的語義測試原理。另外除了語義,可能還有一些「表面」一些的測試,它們看代碼本身,而不只看它的語義。比如尾遞歸優化的測試應該確保輸出程序的尾遞歸得到正確的處理,等等。這些是語義測試檢查不到的,因為尾遞歸沒有正確處理的程序大部分也能輸出正確的結果。
普通的單元測試方法也可以用來測試一些編譯器里的輔助函數,但那些不是編譯器特有的,所以就不講了。
另外,就像所有測試的局限性一樣,你沒法枚舉所有可能出現的輸入,所以以上的測試方法其實也不能保證編譯器的完全正確。
㈧ C編譯器問題。不同編譯器中編寫C/C++程序語法是否有不同
for(int i=0;i<10;++i) cout<<i;
cout<<i;
Dev-c++里,是錯的。i的作用域只是for
vc6.0里是對的。
這只是c++的寫法。c里變數聲明必須放在前面,不會有這種情況。
其他的沒用過。
㈨ c語言改錯 怎麼通過編譯程序檢查出語法錯誤
編譯器編譯時對你的代碼錯誤自動顯示出來,告訴你錯在何處,為什麼錯,你可以根據顯示的錯誤改正代碼