當前位置:編程學習大全網 - 編程語言 - lex宿主語言可以用java嗎

lex宿主語言可以用java嗎

Lex是美國Bell實驗室用C語言研制的壹個詞法分析程序自生成工具

。它的基本原理就是使用正則表達式掃描匹配文本,並為每壹個匹配模式定義壹些操作,當用C語言作宿主語言時,這些操作都由C語言實現。

壹種匹配的正則表達式可能會包含相關的動作。這壹動作可能還包括返回壹個標記。當 Lex 接收到文件或文本形式的輸入時,它試圖將文本與正則表達式進行匹配。它壹次讀入壹個輸入字符,直到找到壹個匹配的模式。如果能夠找到壹個匹配的模式,Lex 就執行相關的動作(可能包括返回壹個標記)。另壹方面,如果沒有可以匹配的正則表達式,將會停止進壹步的處理,Lex 將顯示壹個錯誤消息。

Lex 和 C 是強耦合的。壹個 .l 文件(Lex 文件具有 .l 的擴展名)通過 lex 公用程序來傳遞,並生成 C 的輸出文件。這些文件被編譯為詞法分析器的可執行版本。

本程序對java源程序進行分析,主要實現以下兩個功能:

(1)、清除註釋。java源程序有三種註釋方法:1、單行註釋,以//開頭直到行結束;2、多行註釋,以/*為開始,*/為結束,可以註釋多行;3、java文檔註釋,這也是壹種多行註釋,但它可以通過java文檔生成工具寫入java程序文檔中。它以/**為開始,*/為結束。

(2)、通過程序行數計算工作量。

(3)、計算程序中類的個數,並判斷有沒有兩個public類,如果存在則報錯:There is an error:One java file cannot includes two public class。

單行註釋的清除。由於單行註釋以//開頭直到行結束,首先要匹配的就是//,然後清除從匹配處到行結束的所有字符。具體實現如下:

"//" {

int c;

while ( (c = input()) != '/n' &&

c != EOF )

{

;

}

code = add(code,'/n');

}

多行註釋的清除。多行註釋有兩種,壹種是普通多行註釋,另壹種是java文檔註釋。這兩種註釋都以*/結束,普通多行註釋以/*開始,java文檔註釋以/**開始。可以先匹配/*,然後向後搜索*/。要區別這兩種註釋就要看/*後面是否緊跟壹個*字符,如果不是則為普通多行註釋;如果是還要看下壹字符是否為/字符,如果是也為普通註釋,如果不是則為java文檔註釋。具體lex程序實現如下:

"/*" {

int c,ct=0;

char * javadoc = "/*there is a Java Doc Comment*/";

for ( ; ; )

{

while ( (c = input()) != '*' &&

c != EOF )

{

ct++;

}

if ( c == '*' )

{

c = input();

if ( c == '/' )

{

ct = 0;

break; /* found the end */

}

else

{

if(ct==0)

code = strcat(code,javadoc);

}

}

if ( c == EOF )

{

printf( "EOF in comment" );

break;

}

}

}

my.l即為lex程序。輸入壹段帶有註釋的java源程序,然後打入結束標誌$號,回車就可以看到在輸出的程序中所有註釋都已經刪除,在含有java文檔註釋的地方加上了壹句註釋:/*there is a Java Doc Comment*/。

經過仔細研究發現,上面的實現過程還是過分依賴C語言,沒有真正發揮Lex模式匹配的強大功能。單行註釋、普通多行註釋、Java文檔註釋可分別由下列模式匹配:

////.*/n

///*[^/*//]*/*//

///*/*[^/*//]*/*//

本程序還提供了識別類定義的功能,匹配模式如下:

public[ /n/t]+class[ /n/t]+[a-zA-Z][_a-zA-z0-9]*/[ /n/t]*/{[^/]}*/}

(public|protected|private)[ /n/t]+class[ /n/t]+[a-zA-Z][_a-zA-z0-9]*/[ /n/t]*/{[^/]}*/}

[ /n/t]*class[ /n/t]+[a-zA-Z][_a-zA-z0-9]*/[ /n/t]*/{[^/]}*/}

經完善後的lex程序如下所示:

%{

#include <string.h>

char * code = "";

int codelines = 0;

int classnum = 0;

int pubclass = 0;

char * classes[4]={"","","",""};

/*add a char c to the string code*/

char * add(char * code,char c)

{

char * temp;

if(code==NULL)

return "";

temp = (char*)malloc(sizeof(char)*2);

temp[0] = c;

temp[1] = '/0';

temp = strcat(code,temp);

return temp;

}

%}

%%

///*[^/*//]*/*// code = add(code,'');

///*/*[^/*//]*/*// code = strcat(code,"/*there is a Java Doc Comment*//n");

////.*/n code = add(code,'/n');

public[ /n/t]+class[ /n/t]+[a-zA-Z][_a-zA-z0-9]*/[ /n/t]*/{[^/}]*/} {

classes[classnum] = (char*)malloc(100);

classes[classnum] = strcpy(classes[classnum],yytext);

classnum++;

code = strcat(code,yytext);

pubclass++;

}

(public|protected|private)[ /n/t]+class[ /n/t]+[a-zA-Z][_a-zA-z0-9]*/[ /n/t]*/{[^/}]*/} {

classes[classnum] = (char*)malloc(100);

classes[classnum] = strcpy(classes[classnum],yytext);

classnum++;

code = strcat(code,yytext);

}

[ /n/t]*class[ /n/t]+[a-zA-Z][_a-zA-z0-9]*/[ /n/t]*/{[^/}]*/} {

classes[classnum] = (char*)malloc(100);

classes[classnum] = strcpy(classes[classnum],yytext);

classnum++;

code = strcat(code,yytext);

}

/n code = add(code,'/n');

. {

if(yytext[0] == ';')

codelines++;

code = add(code,yytext[0]);

}

%%

yywrap()

{

int i=0;

printf("/nBelow is the code without comment:/n/n");

printf(code);

printf("/n/nConclude:/nThis code weights %d lines/n",codelines);

printf("This code includes %d classes/n",classnum);

printf("classes:/n");

for(i=0;i<classnum;i++)

{

printf(classes[i]);

printf("/n");

}

if(pubclass>1)

printf("/nThere is an error: a java file cannot have two public class/n");

code = (char*)malloc(1);

code[0]='/0';

}

main()

{

yylex();

system("pause");

return 1;

}

這個程序還有另外兩個其他功能:1、根據程序的行數來確定程序工作量,行數等於分號的個數。在結果的末尾將會顯示行數;2、我們知道壹個java文件中不能存在兩個public類,本程序可以檢查壹個文件中存在幾個類,並判斷是否存在兩個或兩個以上的public類,如果存在就報錯。

註:my.l文件是改進前的lex程序,改進後的程序保存在my1.l文件中,Java.txt內含有壹個java源程序可以用來測試。運行lexyy.exe,復制java.txt裏面的內容粘貼到程序裏,加上輸入結束符Ctrl+z,然後回車即可看到結果;或者在dos下把java.txt作為lexyy.exe的參數運行lexyy.exe也可。

  • 上一篇:求壹篇關於3G在中國的應用和發展的畢業論文。
  • 下一篇:NC操機什麽意思
  • copyright 2024編程學習大全網