2020-10-29
實驗一 TINY語言的詞法分析
一、實驗?zāi)康?br /> (評價依據(jù),描述是否準(zhǔn)確到位)
利用第三方的lex工具構(gòu)造tiny語言的詞法分析器(掃描器)并使得構(gòu)造出的掃描器能夠讀入教材樣例中給出的tiny語言的示例代碼,分解成token輸出。
學(xué)習(xí)如何使用flex,配置它的環(huán)境并使用。
學(xué)習(xí)如何編寫正則表達式和tiny語法結(jié)構(gòu)。
學(xué)習(xí)如何使用工具獲取tokens。
二、實驗設(shè)計
(評價依據(jù)實驗方案設(shè)計是否合理)
由詞法分析器的工作方式可以知道,實驗需要做到:理解并使用tiny語言,使用構(gòu)造出的掃描器,能夠讀入教材樣例中給出的tiny語言的示例代碼,分解成token輸出。,經(jīng)編譯后在c編譯器上使用和調(diào)用。
三、內(nèi)容和步驟
1.配置環(huán)境:
配置環(huán)境變量:右擊此電腦->屬性->高級系統(tǒng)設(shè)置->“高級”一欄下的環(huán)境變量 在系統(tǒng)變量Path中增加win_flex_bison的路徑。直接在桌面新建一個test文件夾,里面創(chuàng)建文本文件后改名lex.l打開cmd,同樣方法獲得路徑,輸入cd :路徑,比如我cd C:\Users\Administrator\Desktop\test 回車后進入。沒有報錯,文件夾出現(xiàn)新文件,說明配置成功
2.代碼:
%{ #include "stdio.h" #include "stdlib.h" %}INT_DEX [1-9][0-9]*|[0] INT_HEX [0][Xx]([1-9][0-9]*|[0]) INT_OCT [0][0-7] FLOAT [0-9]*[.][0-9]+([eE][+-]?[0-9]*|[0])?f? SEMI [;] COMMA [,] ASSIGNOP [=] RELOP [>]|[<]|[>][=]|[<][=]|[=][=]|[!][=](^[=]) PLUS [+] MINUS [-] STAR [*] DIV [/] AND [&][&] OR [|][|] DOT [.] NOT [!] TYPE int|float LP \( RP \) LB \[ RB \] LC \{ RC \} STRUCT struct RETURN return IF if ELSE else WHILE while SPACE [ \n\t] ID [a-zA-Z_][a-zA-Z_0-9]* /*end of definition*/ %% {SEMI} {printf("get semmi : %s\n", yytext);}{COMMA} {printf("get comma : %s\n", yytext); } {ASSIGNOP} {printf("get assignop : %s\n", yytext); }{INT_DEX} | {INT_HEX} | {INT_OCT} {printf("get an integer: %s\n", yytext); }{FLOAT} {printf("get a float: %s\n", yytext); }{PLUS} | {MINUS} | {DIV} | {STAR} {printf("get an operator: %s\n", yytext); }{RELOP} {printf("get a relop: %s\n", yytext); }{AND} | {OR} | {NOT} {printf("get a logic operator: %s\n", yytext); }{DOT} {printf("get a dot: %s\n", yytext); } {STRUCT} | {RETURN} | {IF} | {ELSE} | {WHILE} {printf("get keyword: %s\n", yytext); }{TYPE} {printf("get type: %s\n", yytext); }{LP} | {RP} | {LB} | {RB} | {LC} | {RC} {printf("get brackets : %s\n", yytext); }{SPACE} | . { /*ABANDON THESE CHARACTORS*/ }{ID} {printf("get an ID: %s\n", yytext); } %% int yywrap() {return 1; }int main(int argc, char** argv) {if (argc > 1) {if (!(yyin = fopen(argv[1], "r"))) { perror(argv[1]);return 1;}}while (yylex());return 0; }3.結(jié)果:
測試如下案例(書本23頁):
{ sample progarm
in tiny language -
computer factorial
}
read x;{ input an integer }
if x < 0 then { don’t compute if x <= 0}
fact := 1;
repeat
fact := fact * x;
x := x - 1
until x = 0;
write fact {output factorial of x}
End
四、實驗結(jié)論:
1 理論基礎(chǔ)(評價依據(jù) 理論知識非常清楚)
TINY的程序結(jié)構(gòu)是一個由分號分隔開的語句序列。另外,它既無過程也無聲明。所有的變量都是整型變量,通過對其賦值可較輕易地聲明變量(類似FORTRAN或BASIC)。它只有兩個控制語句:i f語句和repea語句,這兩個控制語句本身也可包含語句序列。If語句有一個可選的else部分且必須由關(guān)鍵字end結(jié)束。除此之外,read語句和write語句完成輸入/輸出。在花括號中可以有注釋,但注釋不能嵌套。
TINY的表達式也局限于布爾表達式和整型算術(shù)表達式。布爾表達式由對兩個算術(shù)表達式的比較組成,該比較使用<與=比較算符。算術(shù)表達式可以包括整型常數(shù)、變量、參數(shù)以及4個整型算符+、-、*、/,此外還有一般的數(shù)學(xué)屬性。布爾表達式可能只作為測試出現(xiàn)在控制語句中——而沒有布爾型變量、賦值或I / O。
本次書上的測試案例:
{ sample progarm
in tiny language -
computer factorial
}
read x;{ input an integer }
if x < 0 then { don’t compute if x <= 0}
fact := 1;
repeat
fact := fact * x;
x := x - 1
until x = 0;
write fact {output factorial of x}
End
definitions:LABEL REGULAR_EXPRESSION
LABEL是這里類字符串的名稱,REGULAR_EXPRESSION則是匹配這種字符串的正則表達式。
正則表達式的語法:
| 或
[] 括號中的字符取其一
- a-z表示ascii碼中介于a-z包括a.z的字符
\ 轉(zhuǎn)義(flex不能識別除字母外的字符)
- 0或多個字符
? 0或1個字符
- 1或多個字符
^ 除此之外的其余字符
. 除\n外的所有字符,等價于^\n
2、分析和總結(jié)(評價依據(jù):是否能夠?qū)嶒灲Y(jié)果作出完整和準(zhǔn)確的描述,是否能夠捕捉到實驗中的各種現(xiàn)象,是否有強的信息綜合能力,是否能得出正確的結(jié)論。)
整個實驗的流程其實很清楚:
(1)環(huán)境配置
(2)編寫.l文件,并利用flex,devc++編譯
(3)運行并輸入tiny例子,完成分析
本實驗的唯一難點在于編寫.l文件,文件分為定義段,規(guī)則段,代碼段三部分。
{definitions}/定義段
%%
{rules}/規(guī)則段
%%
{user subroutines}/代碼段
規(guī)則段用于提取,代碼段用于c程序的運行。
在正則表達式上會有些難度,規(guī)則段其實按照例子來就很簡單,代碼段搞不懂說明c語言沒有掌握透徹。
3、對工具的評價(優(yōu)缺點及其局限性的總結(jié))
lex是一個產(chǎn)生詞法分析器, Lex常常與yacc語法分析器產(chǎn)生程序。
Lex讀進一個代表詞法分析器規(guī)則的輸入字符串流,然后輸出以C語言實做的詞法分析器源代碼。有名的Lex公開源代碼版本是flex,代表"快速的詞法分析器"。因此優(yōu)點在于速度快,但是必然會失去部分穩(wěn)定性。
總結(jié)
以上是生活随笔為你收集整理的2020-10-29的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php 字符串划线,php – 在ela
- 下一篇: 程序员,35岁是职业发展的转折点 (1