1. Trang chủ
  2. » Luận Văn - Báo Cáo

Phân tích từ vựng của ngôn ngữ lập trình

26 1,3K 6

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 26
Dung lượng 143,5 KB

Nội dung

Trong ngành khoa học máy tính, phân tích từ vựng en:Lexical Analysis, còn được gọi là scanning hoặc lexing là một quá trình chuyển đổi chuỗi ký tự nguồn thành một chuỗi liên tiếp các đoạ

Trang 1

TRƯỜNG ĐẠI HỌC KINH TẾ QUỐC DÂN

BỘ MÔN CÔNG NGHỆ THÔNG TIN

Trang 2

Trong ngành khoa học máy tính, phân tích từ vựng (en:Lexical Analysis,

còn được gọi là scanning hoặc lexing) là một quá trình chuyển đổi chuỗi ký

tự nguồn thành một chuỗi liên tiếp các đoạn ký tự ngắn hơn đã được phân

loại, gọi là tokens Chương trình dùng để phân tích từ vựng được gọi là bộ phân tích từ vựng (tiếng Anh là Lexer).

Token: Một token là một tập hợp các xâu kí tự có một nghĩa xác định,

ví dụ identifier token là tập hợp tất cả các identifier Token chính là các

kí hiệu kết thúc (terminal) trong định nghĩa văn phạm của một ngôn ngữ,

ví dụ: Các từ khoá, định danh, toán tử, hằng, xâu kí tự, dấu ngoặc đơn,dấu phẩy, dấu chấm phẩy

Tokens tương tự như loại từ trong ngôn ngữ học Tương tự như danh từ hay tính từ, động từ, tokens sẽ được định nghĩa gồm từ khóa (keyword), địnhdanh (identifier), số nguyên, số chấm động tùy theo đặc điểm của trình biên dịch

Để biểu diễn các tokens, người ta dùng biểu thức chính quy

a : có xuất hiện ký tự 'a'

ab : có xuất hiện ký tự 'b' theo sau ký tự 'a' (theo đúng thứ tự)

a|b : có 'a' hoặc có 'b'

a* : xuất hiện nhiều hoặc không xuất hiện ký tự 'a'

a+ : xuất hiện nhiều hoặc ít nhất là một ký tự 'a'

a3 : xuất hiện 3 ký tự a

a? : xuất hiện a hoặc không xuất hiện

• Phân tích từ vựng giúp cho các giai đoạn biên dịch tiếp theo dễ dàng hơn, ví dụ: Giai đoạn phân tích cú pháp không phải quan tâm đến các khoảng trắng cũng như các lời chú trích vì nó đã được loại bỏ khi khi phân tích từ vựng

• Giảm đáng kể thời gian đọc chương trình nguồn và nhóm thành các token nhờ một số chương trình xử lí chuyên dụng

I Bảng chữ,phân tích từ vựng của ngôn ngữ Pascal

1 Bảng chữ

1.1 Bộ ký tự

Trang 3

PROGRAM, BEGIN, END, PROCEDURE, FUNCTION

- Từ khóa để khai báo:

CONST, VAR, TYPE, ARRAY, STRING, RECORD, SET, FILE, LABEL

- Từ khóa của lệnh lựa chọn:

IF THEN ELSE, CASE OF

- Từ khóa của lệnh lặp:

FOR TO DO, FOR DOWNTO DO, WHILE DO,

REPEAT UNTIL

- Từ khóa điều khiển:

WITH, GOTO, EXIT, HALT

Boolean, Char, Integer, Word, Byte, Real, Text

False, True, MaxInt

Abs, Arctan, Chr, Cos, Sin, Eof, Eoln

Exp, Ln, Odd, Ord

Round, Trunc, Sqr, Pred, Succ

Dispose, New, Get, Put, Read, Readln,

Write, Writeln Reset, Rewrite

a Danh hiệu tự đặt

Trang 4

Trong Pascal để đặt tên cho các biến, hằng, kiểu, chương trình con ta

dùng các danh hiệu (identifier) Danh hiệu của Pascal được bắt đầu bằng một

chữ cái, sau đó có thể là các chữ cái, chữ số hay là dấu nối, không được có

khoảng trắng và độ dài tối đa cho phép là 127

Ví dụ: Sau đây là các danh hiệu: x; S1; Delta; PT_bac_2;

Pascal không phân biệt chữ thường và chữ hoa trong một danh hiệu

Ví dụ: aa và AA là một; XyZ_aBc và xyZ_AbC là một

-> Khi viết chương trình ta nên đặt các danh hiệu sao cho chúng nói lên

các ý nghĩa của đối tượng mà chúng biểu thị Ðiều này giúp chúng ta viết

chương trình dễ dàng và người khác cũng dễ hiểu nội dung chương trình

b Kiểu dữ liệu

Pascal có 4 kiểu dữ liệu cơ bản:

Integer : kiểu số nguyên

Real : kiểu số thực

Char : kiểu kí tự

Boolean : kiểu logic

1.5.1 Kiểu số nguyên (integer type)

có nghĩa sau dấu phẩy

SINGER 4 1.5E-45…3.4E38, 7-8 chữ số có nghĩa sau dấu phẩy.DOUBLE 8 5.0E-324 1.7E308, 15-16 chữ số có nghĩa sau dấu

phẩy

EXTENDED 10 3.4E-4932…1.1E4932, 19-20 chữ số có nghĩa sau dấu

phẩy

Trang 5

1.5.3 Kiểu logic (Boolean)

Một dữ liệu thuộc kiểu BOOLEAN là một đại lượng được chứa trong 1 byte ở Turbo Pascal và chỉ có thể nhận được một trong hai giá trị logic là TRUE (đúng) và FALSE (sai)

1.5.4 Kiểu kí tự (char type)

Kí tự là một trong các kí hiệu trong bảng mã ASCII (American StandardCode for Information Interchange) Trong Turbo Pascal, nhiều kí tự liên tiếp tạo thành một kiểu dữ liệu mới là String String có độ dài trong khoảng 0…255

Trong Turbo Pascal mỗi kí tự được chứa trong 1 byte

2 Bộ phân tích từ vựng

Hướng dẫn tạo bộ phân tích từ vựng cho ngôn ngữ Pascal, tức là chương trình đọc tệp pas và in kết quả phân tích từ vựng ra màn hình

Cách dễ dàng và nhanh chóng nhất để xây dựng bộ phân tích từ vựng cho

1 ngôn ngữ nào đó là dùng ngôn ngữ Lex (Lexical Analyzer Generator) FileLex chứa các biểu thức chính quy, mỗi biểu thức chính quy miêu tả 1 token

cụ thể của ngôn ngữ, định dạng tổng quát của file Lex như sau:

%{

//các lệnh định nghĩa viết bằng C hay C++

%}

Trang 6

%%

//các biểu thức chính quy nhận dạng các token

%%

//các đoạn code C hay C++ miêu tả ứng dụng

Sau đây là file Lex đọc file mã nguồn pascal rồi xuất ra danh sách các tokentương ứng:

Trang 7

[-][0-9]*[.][0-9]*[eE][-]*[0-9]+ { printf ("[rconst,%s] ", yytext); }

[pP][rR][oO][gG][rR][aA][mM] { printf ("[program] "); }

[uU][sS][eE][sS] { printf ("[uses] "); }

[vV][aA][rR] { printf ("[var] "); }

[tT][yY][pP][eE] { printf ("[type] "); }

[bB][eE][gG][iI][nN] { printf ("[begin] "); }

[eE][nN][dD] { printf ("[end] "); }

[fF][uU][nN][cC][tT][iI][oO][nN] { printf ("[function] "); }

[pP][rR][oO][cC][eE][dD][uU][rR][eE] { printf ("[procedure] "); }

[iI][fF] { printf ("[if] "); }

[tT][hH][eE][nN] { printf ("[then] "); }

[eE][lL][sS][eE] { printf ("[else] "); }

[dD][oO] { printf ("[do] "); }

[rR][eE][pP][eE][aA][tT] { printf ("[repeat] "); }

[uU][nN][tT][iI][lL] { printf ("[until] "); }

Trang 8

[a-zA-Z][a-zA-Z0-9\_]* { printf ("[ident,%s] ", yytext);}

//điểm nhập của chương trình

void main(int argc,char *argv[]) {

flex -tl pascalscan.l >pascalscan.c

Sau khi đã có file *.c, bạn có thể dùng chương trình dịch C hay C++ dịch nó

ra file khả thi Sau khi có file khả thi (thí dụ tên là pascalscan.exe), bạn có thể dùng nó với cú pháp sau đây:

pascalscan mypro.pas để đọc file mã nguồn Pascal rồi hiển thị các token tương ứng lên màn hình Hoặc dùng hàng lệnh sau:

pascalscan mypro.pas >output để đọc file mã nguồn Pascal rồi xuất các token tương ứng lên file "output" để tham khảo sau đó

Lưu ý rằng chuỗi token nhận dạng được bởi bộ phân tích từ vựng thường được gửi tới bộ phân tích cú pháp chứ ít ai hiển thị hay xuất ra file như thí

dụ trên

Trang 9

Bạn có thể tải tiện ích FLEX trên Internet (đây là ứng dụng mã nguồn mở).

http://download1us.softpedia.com/dl/

2c924d2b8352678eb6dde18745e1e960/4d04d70e/100120309/softwar

Tôi muốn viết một ứng dụng đọc và hiển thị file TXT dạng Unicode trên Windows, nhưng tôi không thể hiển thị đúng các ký tự Unicode mặc dù đã

sử dụng kiểu widestring và widechar

Mặc dù mã Unicode đã được chuẩn hóa và tổng quát để miêu tả đồng thời nhiều ký tự của nhiều ngôn ngữ, nhưng hiện nay việc hiện thực xử lý mã Unicode không hoàn hảo, tùy vào môi trường lập trình và ngôn ngữ lập trìnhđược dùng mà mức độ hỗ trợ mã Unicode rất khác nhau Thí dụ nếu bạn dùng môi trường Net (VC#, VJ#, VB Net) thì mức độ hỗ trợ mã Unicode làrất tốt, hầu như trong suốt hoàn toàn với code mà bạn viết Tuy nhiên nếu bạn dùng VB hay tệ hơn là VC++ thì mức độ hỗ trợ mã Unicode còn khá thấp và chưa được trong suốt cho người lập trình Thí dụ các đối tượng giao diện có sẵn của môi trường VB 6.0 trở xuống không thể hiển thị đúng được chuỗi Unicode, bạn phải dùng các đối tượng tương ứng trong thư viện

Form2 kèm theo VB Còn trong VC++, nếu bạn dịch ứng dụng ở chế độ mặcđịnh (ANSI) thì ứng dụng sẽ không xử lý được chuỗi Unicode Điều kiện tiên quyết để viết ứng dụng xử lý tốt chuỗi Unicode trong VC++ là phải dịchứng dụng ở chế độ Unicode (dùng macro dịch là -D "Unicode") Về mặt lập trình VC++, nếu bạn muốn xử lý chuỗi Unicode cấp thấp hay muốn gọi các hàm API Windows để xử lý chuỗi Unicode, bạn sẽ dùng kiểu dữ liệu

widechar và widestring để định nghĩa các biến chứa ký tự hay chuỗi

Unicode Lưu ý rằng Windows chia tập các hàm có thông số chuỗi ra thành

2 loại: loại chỉ xử lý chuỗi ANSI và loại chỉ xử lý chuỗi Unicode Thí dụ hàm TextOut() chỉ hiển thị chuỗi ANSI, còn hàm TextOutW() chỉ hiển thị chuỗi Unicode Việc chuyển chuỗi ANSI về mã Unicode luôn thành công, nhưng ngược lại, việc chuyển chuỗi Unicode về ANSI có thể làm mất thông tin

Sau đây là đoạn code VC++ thực hiện việc thiết lập font hỗ trợ Unicode cho Form, gọi hàm API TextOutW() để xuất chuỗi Unicode "Nguyễn Văn Hiệp" ra vị trí (10,100), xuất chuỗi "Nguyễn Văn Hiệp" ra TextBox được nhận dạng bởi biến m_edit

//xây dựng record miêu tả font cần dùng

LOGFONT lgcursfont; // font structure

Trang 10

buf[2] = 'u'; buf[3] = 'y';

buf[4] = 0x1ec5; buf[5] = 'n';

Trang 11

- Các chữ số : 0,1, , 9.

- Ký tự gạch nối _ ( chú ý phân biệt dấu - )

- Dấu cách ( space) : dùng để phân biệt các từ :

Ví dụ : lop Học( 7 kí tự) - LopHoc( 6 kí tự)

1.2 Tên

Tên ( định danh ) : là 1 dãy kí tự bắt đầu bằng chữ hoặc ký tự gạch

dưới, theo sau là chữ cái, chữ số hoặc ký tự gạch nối (-)

- Tên : dùng làm tên hằnp, tên biến , nhãn , tên hàm

Ví dụ : Tên đúng : _abc, Delta_1, BETA

Tên sai : 1xyz ( vì bắt đầu là 1 chữ số )

trong C gồm : Break, char, continue, case, do, double, default, else,

float, for, goto, int,if, long, return, struct, switch, unsigned,

while, typedef, union voi, volatile,

1.4 Các kiểu dữ liệu cơ bản trong C : 4 kiểu : char, Int, float, double.

- Kiểu char ( 1 byte ) : biễu diễn 1 ký tự thuộc ASCII ( thực chất là số

- Kiểu Int : 3 loại : Int, long Int ( long ) và unsigned Int ( unsigned)

- Kiểu Float : biểu diễn các số thực độ chính xác định

Trang 12

- Kiểu double : biễu diễn các số thực độ chính xác kép.

5 Float 3.4e - 38 3.4e + 38 4 bytes

6 double 1.7e - 308 1.7e + 308 8 bytes

- Kiểu void: Kiểu không giá trị, củ dùng để biểu diễn kết quả hàm

cũng như nội dung củ pointer Kiểu này sẽ nói chi tiết ở các phần liên

Int a,b = 20; float e = 35.1; x=30.5;

b/ Mảng: là tập hợp các phần tử có cùng 1 kiểu và chung 1 tên

* Chú ý : &Mang1[3] đúng nhưng &Bang[2][5]sai ( Ðúng đối với 1 chiều

và sai đối với nhiều chiều)

1.6 Hằng : Ðại lượng không thay đổi

a/ Hằng nguyên ( Int ): có giá trị từ -32768 đến 32767

- Có thể viết theo hệ 16 bằng cách thêm tiền tố Ox hoặc theo cơ số 8 bằng cách thêm tiền tố O ( Octal = bát phân )

* Ví dụ : O306 viết theo cơ số 8 : Giá trị = 6 * 8 0 + 3* 8 * 8 = 198 trong hệ10

Trang 13

c/Hằng thực ( float và double ) : Có 2 cách viết

- Cách 1 : ( dạng thập phân) Số gồm : phần nguyên, dấu chấm thập phân và phần phân

*Ví dụ : chữ a mã hệ 10 là 97 đổi ra hệ 8 là O141 => \141='a';

\ 101='A';

\ 142 ='b'

* Một số hằng đặc biệt được viết theo qui ước như sau :

Viết Ký tự Diễn giải

' \ " ' dấu nháy đơn

Trang 14

- Hằng ký tự thực sự là số nguyên => có thể dùng số nguyên hệ 10 đê biểu diễn ký tự

- Hằng có thể được đinh nghĩa đối với toán tử define

+ Cú pháp : # define < tên hằng > < giá trị>

Trong chương trình mọi biến max đều được thay đổi giá trị 100

Chú ý : - n++ : giá trị n được lấy trước khi tăng n

- ++n : giá trị n được lấy sau khi tăng n

- tương tự n , n ;

+ Toán tử thao tác bit : Không áp dụng cho kiểu float hoặc double

& : phép hội các bít ( và)

| : phép tuyển các bit ( hoặc)

^ : phép tuyển các bit loại trừ

Toán tử chuyển đổi kiểu : ta có thể dùng toánt ử chuyển kiểu để chuyển

1 kiểu bất kỳ sang kiểu mong muốn bằng cách dùng toán tử sắc thái (

cast) theo quy tắc sau :

ép Kiểu ( type cast ) : ( kiểu ) Biến Kiểu mong muốn

* Ví dụ : int i = 10

ă ( float ) i => 10.0

Trang 15

- Chú ý : + Một số kiểu float khi chuyển sang kiểu Int sẽ bị chặt cụt phần thập phân.

+ Một số kiểu long khi chuyển sang kiểu Int sẽ cắt bỏ vài chữ số

ý : Các phép toán trong C có độ ưu tiên khác nhau và quy tắc kết hợp

khác nhau => Bảng liệt kê các phép toán theo thứ tự ưu tiên từ trên

xuống dưới, các phép toán trên dòng có thứ tự như nhau

Phép toán Trình tự kết hợp

(),[ ], ă trái qua phải

|, dấu ngã, &*, - -, + + , ( type ) size of phải qua trái

*,/, % trái qua phải

+, - trái qua phải

<< ,>> trái qua phải

<,<= ,> ,>= trái qua phải

& trái qua phải

| trái qua phải

&& trái qua phải

|| trái qua phải

? phải qua trái

= =, !=, +=, -= phải qua trái

1.8 Biểu thức : được xây dựng bằng các toán tử , toán hạng là các hằng,

biến, hàm

- Biểu thức gán : Ví dụ : A = B =C =5 => A=5, B = 5, C = 5

- Biểu thức điều kiện có dạng : B1?E1 : E2 : Nếu B 1 đúng giá trị biểu thức

= E1 ngược lại E2

* Ví dụ : S=x>y ? x:y cho giá trị lớn nhất của x và y

2 Bộ phân tích từ vựng ngôn ngữ C

Trang 16

const char* ErrorType[]={"'&' expected","'|' expected","Token Too Long",

"SymTable OverFlow","Unknown Character"};

Trang 17

int flag;//flag=0 nghia la da do vao nen khong do lai.

int testlength();//tra ve true neu token dai qua gioi han

int fail(int);//co kem theo dieu kien de bat co flag

void retract(int i);//co kem theo dieu kien de bat co flag

void update();//co xet flag de xem co do vao khong

int lookup(char const *s);

int insert(char const *s,int type);

int gettoken(int i);

void display();

void save();

};

Trang 18

if (( p1<=LexerMax/2-1 && p2>LexerMax/2-1 )||

( p1 >LexerMax/2-1 && p2<LexerMax/2-1 ))

flag=0;

p2=p1;

if (i== 1) return(10);else

if (i==10) return(13);else

Trang 25

int main(int n, char *arg[])

Ngày đăng: 01/03/2016, 09:04

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w