มาทำ scanner ด้วย flex กัน !!

ห้องนี้ของบัณฑิตเฟรชชี่ เมื่อปีที่แล้ว

Moderators: Spadez, Mahhow

มาทำ scanner ด้วย flex กัน !!

Postby natz » Wed Jul 02, 2008 9:24 pm

lex & yacc

หมายเหตุ ว่า
Code: Select all
ส่วนของ lex เราใช้โปรแกรม flex
ส่วนของ yacc เราใช้โปรแกรม bison

คำชี้แจงว่า
Code: Select all
flex และ bison เป็นโปรแกรมโปรแกรมหนึ่ง(สองอันก็สองโปรแกรม) ซึ่งทำงานบน linux

เราไม่แน่ใจนะว่าใน windows มีให้ใช้หรือเปล่า แล้วใช้โปรแกรมอะไร
แต่ว่าเราลอง search ว่าflex on windows มันก็มี .exe ให้ดาวน์โหลดนะ
แต่ยังไม่ได้ลองใช้

อยากได้ข้อมูลเพิ่มเติม เข้า http://www.google.co.th แล้วลอง search flex , bison หรือ lex & yacc ดูนะ


นี่ก็ได้ลองศึกษาไปแล้วบ้าง แต่ทำต่อไม่ได้ เลยเอามาเขียน
เผื่อจะมีประโยชน์และก็รอคนอื่นทำต่อด้วย

วิธีการติดตั้ง
เราใช้ ubuntu อยู่เป็น linux อะนะ
วิธีการลงก็ง่ายๆ
พิมพ์ code ข้างล่างลงใน terminal นะ
Code: Select all
sudo apt-get install flex
sudo apt-get install bison


แล้วก็มาว่าด้วย flex กันต่อ

flex ก็เหมือน compiler ที่ compile โค๊ดภาษา c อะแหละ
ซึ่ง compiler ภาษา c มันจะ compile ไฟล์ .c ให้เป็น ภาษาเครื่อง (.exe -- executable file)
แต่ว่าไอ้เจ้า flex เนี่ย จะ compile ไฟล์นามสกุล .l ให้เป็นไฟล์ภาษา c (ไฟล์ .c )
แล้วเราก็เอา ไฟล์ภาษา c ที่ได้มา compile ต่อเป็นภาษาเครื่อง

แล้วเราก็จะได้โปรแกรมที่รับ input แล้วเอาไปตัดเป็น tokens ตามที่เราตั้งกฎไว้

ยกตัวอย่าง ตามทีเราเขียนไว้นะ
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby natz » Wed Jul 02, 2008 9:26 pm

ไฟล์ nazt.l

Code: Select all
/*** Definition section ***/

%{
/* C code to be copied verbatim */
#include <stdio.h>
%}

/* This tells flex to read only one input file */
%option noyywrap

%%
    /*** Rules section ***/

    /* [0-9]+ matches a string of one or more digits */

[0-9]+  {
            /* yytext is a string containing the matched text. */
            printf("Saw an integer: %s\n", yytext);
        }

[a-z]    {
      printf("Saw an [a-z] character: %s\n", yytext);
   }

"go"       { printf ("Found go\n"); }
"transit"   { printf ("Found transit\n"); }
"q"[0-9]+   { printf ("Found state %s\n",yytext);}

[ \t\n]+        ;       /* ignore whitespace */

.               printf("Fuck !! Unknown character\n");


%%
/*** C Code section ***/

int main(void)
{
    /* Call the lexer, then quit. */
    yylex();
    return 0;
}



เราจะสนใจ ส่วน Rules section อย่างเดียวเลยนะ
มันจะมีรูปแบบดังนี้

เริ่มต้นด้วย
Code: Select all
%%
    /*** Rules section ***/
   ข้างในเป็นกฏ
%%

แล้วก็ปิด section แบบนี้
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby natz » Wed Jul 02, 2008 9:35 pm

กฎมันก็ใช้ regular expression ตามระเบียบนะน่ะ

อย่างเช่น
Code: Select all
[0-9]+ 
{
            /* yytext is a string containing the matched text. */
            printf("Saw an integer: %s\n", yytext);
}

[0-9]+ อันนี้แปลว่า รับเลข 0-9 แล้วมีเครื่องหมาย + มันจะแปลว่ากี่ตัวก็ได้
ถ้าไม่มีมันจะเป็นเลขโดด 0-9 เท่านั้น ถ้าเจอ 10 มันจะแยกอ่านเป็น 1 กับ 0
แล้วในปีกกา
Code: Select all
{
          ในปีกกา มันคือคำสั่งว่าจะให้ทำอะไร ในตัวอย่างก็คือ
          ถ้ามันเจอตัวเลขมันจะปริ้นว่า
          Saw an integer แล้วแสดงตัวเลขที่มันเจอออกมา
}
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby natz » Wed Jul 02, 2008 9:39 pm

Code: Select all
"q"[0-9]+   { printf ("Found state %s\n",yytext);}

อันนี้แปลว่า ถ้า เจอ q แล้วตามด้วยตัวเลขกี่ตัวก็ได้ให้พิมพ์ Found state แล้ว พิมพ์ว่าเจออะไร
เช่น q111 มันจะพิมพ์ว่า Found state q111


Code: Select all
.               printf("Fuck !! Unknown character\n");

ส่วนตรงนี้คือเมื่อเจอ string ที่นอกเหนือกฎทั้งหลายทั้งปวงที่เราตั้งไว้น่ะ

ส่วนอย่างอื่น ก็ลองศึกษาดูน้า แล้วมาสอนเค้าด้วยยยยยยยยยยย
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby natz » Wed Jul 02, 2008 9:43 pm

คราวนี้มาสั่ง compile กัน

ตอนแรกเราก็ต้องแปลง ภาษา lex (ไฟล์นามสกุล .l) มาแปลงเป็นไฟล์ภาษา c ก่อนด้วยคำสั่ง

Code: Select all
flex nazt.l


ง่ายปะล่ะ แล้วเราจะได้ไฟล์ lex.yy.c ออกมา

แล้วเราก็มาคอมไพล์ให้เป็นภาษาเครื่องด้วยคำสั่ง

Code: Select all
cc lex.yy.c หรือจะคอมไพล์ว่า  cc lex.yy.c -o output_name ก็ได้


ก็จะได้ไฟล์ภาษาเครื่องออกมา

ถ้าแบบแรกเราก็จะ execute มันด้วยคำสั่ง

Code: Select all
./a.out


มันก็จะให้เรา input string เข้าไป
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby natz » Wed Jul 02, 2008 9:46 pm

หรือจะใช้
bash โปรแกรมของเรา

แบบนี้

ไฟล์ชื่อ build
Code: Select all
#!/bin/bash         
echo
if [ -a lex.yy.c ]
then
   echo "found lex.yy.c"
   rm lex.yy.c
else
   echo "not found lex.yy.c"
fi

if [ -a nazt.l ]
then
   echo "found nazt.l"
   echo "lex nazt.l is running"
   lex nazt.l
   echo "lex nazt.l was completed"
   echo "compiling lex.yy.c"
   cc lex.yy.c
   echo "lex.yy.c was compiled to a.out"
   #rm lex.yy.c
else
   echo "not found nazt.l"
   exit;
fi
echo
echo "Executing a.out :"
./a.out
echo "a.out has been terminated"


แล้วเรียก ./build ทีเดียวเสร็จ
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby natz » Wed Jul 02, 2008 9:49 pm

คราวนี้มาลองรันโปรแกรมกัน จะได้ผลดังนี้ๆๆๆๆ

คอมไพล์และเรียกโปรแกรมด้วยคำสั่ง ./build

Code: Select all
nazt@nazt-laptop:~$ ./build

found lex.yy.c
found nazt.l
lex nazt.l is running
lex nazt.l was completed
compiling lex.yy.c
lex.yy.c was compiled to a.out

Executing a.out :

nazt1234q112q1df
Code: Select all
Saw an [a-z] character: n
Saw an [a-z] character: a
Saw an [a-z] character: z
Saw an [a-z] character: t
Saw an integer: 1234
Found state q112
Found state q1
Saw an [a-z] character: d
Saw an [a-z] character: f

gotransitq12a21
Code: Select all
Found go
Found transit
Found state q12
Saw an [a-z] character: a
Saw an integer: 21


ตัวแดงๆ คือ input ที่เราใส่เข้าไปนะ
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby natz » Wed Jul 02, 2008 9:54 pm

SRC CODE

ไฟล์
nazt.l
Code: Select all
/*** Definition section ***/

%{
/* C code to be copied verbatim */
#include <stdio.h>
%}

/* This tells flex to read only one input file */
%option noyywrap

%%
    /*** Rules section ***/

    /* [0-9]+ matches a string of one or more digits */

[0-9]+  {
            /* yytext is a string containing the matched text. */
            printf("Saw an integer: %s\n", yytext);
        }

[a-z]    {
      printf("Saw an [a-z] character: %s\n", yytext);
   }

"go"       { printf ("Found go\n"); }
"transit"   { printf ("Found transit\n"); }
"q"[0-9]+   { printf ("Found state %s\n",yytext);}

[ \t\n]+        ;       /* ignore whitespace */

   .               printf("Fuck !! Unknown character\n");


%%
/*** C Code section ***/

int main(void)
{
    /* Call the lexer, then quit. */
    yylex();
    return 0;
}


ไฟล์ lex.yy.cc

Code: Select all
เอาออก แม่งยาวจัดใครอยากได้เอาไปลอง compile msn มาจ้าา


ไฟล์ build
Code: Select all
#!/bin/bash         
echo
if [ -a lex.yy.c ]
then
   echo "found lex.yy.c"
   rm lex.yy.c
else
   echo "not found lex.yy.c"
fi

if [ -a nazt.l ]
then
   echo "found nazt.l"
   echo "lex nazt.l is running"
   lex nazt.l
   echo "lex nazt.l was completed"
   echo "compiling lex.yy.c"
   cc lex.yy.c
   echo "lex.yy.c was compiled to a.out"
   #rm lex.yy.c
else
   echo "not found nazt.l"
   exit;
fi
echo
echo "Executing a.out :"
./a.out
echo "a.out has been terminated"
Last edited by natz on Wed Jul 02, 2008 10:08 pm, edited 1 time in total.
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby natz » Wed Jul 02, 2008 9:55 pm


ทำได้เท่านี้แหละ น้อยนิดมากๆๆๆๆๆ ทำต่อไม่เป็น

ใครทำอะไรได้มาสอนด้วยนะ

โดยเฉพาะ yacc น่ะ


จะรอจ้าาาา
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby HolyShadow » Wed Jul 02, 2008 10:01 pm

ยาวชะมัด เหอๆๆ งานเยอะแยะมากมายยยยยย
User avatar
HolyShadow
Administrator
 
Posts: 2024
Joined: Sun May 28, 2006 11:40 pm

Postby natz » Wed Jul 02, 2008 10:03 pm

ปล. ใน windows รู้สึกใช้ cygwin ได้นะ แต่ไม่เคยทำได้ หรือไม่ โปรแกรมพวก virtual pc ก็ได้น้าา พวก VM Ware

อ้อ แล้วการใช้ lex กับ yacc รวมกันลองโหลดนี่ไปดูนะ

http://epaperpress.com/lexandyacc/download/code.zip
จากเว็ป
http://epaperpress.com/lexandyacc/


ใครเข้าใจมาสอนด้วยยยย


ได้มานาน ยังไม่เข้าใจซักทีแค่ คอมไพล์มันได้แค่นั้นอะ
natz
Member
 
Posts: 119
Joined: Sat May 27, 2006 12:17 pm

Postby XEON » Wed Jul 02, 2008 10:07 pm

:o thx ja
User avatar
XEON
Member
 
Posts: 316
Joined: Sun Apr 23, 2006 9:47 pm
Location: On the Air

Postby jjmedz » Wed Jul 02, 2008 10:12 pm

:o ช้านดูโง่กว่าเดิมอีกก
Image
User avatar
jjmedz
Member
 
Posts: 1787
Joined: Wed Jun 07, 2006 2:51 pm
Location: หน้าคอม

Postby azoonnoe » Wed Jul 02, 2008 10:13 pm

ขอบคุนมากๆนะนัท

แต่ว่า

ดูแระปวดหัวอ่ะ

ทามไมยากจังเนี่ย

เค้าจารอดมะเนี่ย

:cry:
♀ O สู s น้ o E # ๒๑ ( @^^@)
User avatar
azoonnoe
Member
 
Posts: 17
Joined: Sun Jul 02, 2006 10:20 pm

Postby azoonnoe » Wed Jul 02, 2008 10:14 pm

HolyShadow wrote:ยาวชะมัด เหอๆๆ งานเยอะแยะมากมายยยยยย


เหงด้วยอย่างแรง

TT
♀ O สู s น้ o E # ๒๑ ( @^^@)
User avatar
azoonnoe
Member
 
Posts: 17
Joined: Sun Jul 02, 2006 10:20 pm

Next

Return to Com-Sci#49 (CS รุ่น21)

Who is online

Users browsing this forum: No registered users and 2 guests

cron