Như đã nói trong tiêu đề, loại dữ liệu nào nên trả về / cung cấp cho trình phân tích cú pháp? Khi đọc bài viết phân tích từ vựng mà Wikipedia có, nó đã tuyên bố rằng:
Trong khoa học máy tính, phân tích từ vựng là quá trình chuyển đổi một chuỗi các ký tự (chẳng hạn như trong chương trình máy tính hoặc trang web) thành một chuỗi các mã thông báo ( chuỗi có "nghĩa" được xác định).
Tuy nhiên, hoàn toàn mâu thuẫn với tuyên bố trên, Khi một câu hỏi khác tôi hỏi trên một trang web khác ( Đánh giá mã nếu bạn tò mò) đã được trả lời, Người trả lời đã nói rằng:
Các lexer thường đọc chuỗi và chuyển đổi nó thành một luồng ... của các từ vựng. Các từ vựng chỉ cần là một dòng số .
và ông đã đưa ra hình ảnh này:
nl_output => 256
output => 257
<string> => 258
Sau đó, trong bài viết, ông đã đề cập Flex
, một từ vựng đã tồn tại và nói rằng viết 'quy tắc' với nó sẽ đơn giản hơn so với viết một từ vựng bằng tay. Anh ta tiến hành đưa cho tôi ví dụ này:
Space [ \r\n\t]
QuotedString "[^"]*"
%%
nl_output {return 256;}
output {return 257;}
{QuotedString} {return 258;}
{Space} {/* Ignore */}
. {error("Unmatched character");}
%%
Để hiểu rõ hơn và có thêm thông tin, tôi đã đọc bài viết trên Wikipedia về Flex . bài viết Flex cho thấy rằng bạn có thể xác định một tập hợp các quy tắc cú pháp, với các mã thông báo, theo cách sau:
digit [0-9]
letter [a-zA-Z]
%%
"+" { return PLUS; }
"-" { return MINUS; }
"*" { return TIMES; }
"/" { return SLASH; }
"(" { return LPAREN; }
")" { return RPAREN; }
";" { return SEMICOLON; }
"," { return COMMA; }
"." { return PERIOD; }
":=" { return BECOMES; }
"=" { return EQL; }
"<>" { return NEQ; }
"<" { return LSS; }
">" { return GTR; }
"<=" { return LEQ; }
">=" { return GEQ; }
"begin" { return BEGINSYM; }
"call" { return CALLSYM; }
"const" { return CONSTSYM; }
"do" { return DOSYM; }
"end" { return ENDSYM; }
"if" { return IFSYM; }
"odd" { return ODDSYM; }
"procedure" { return PROCSYM; }
"then" { return THENSYM; }
"var" { return VARSYM; }
"while" { return WHILESYM; }
Dường như với tôi rằng lexer Flex đang trả về các chuỗi từ khóa \ token. Nhưng nó có thể là các hằng số trả về bằng số nhất định.
Nếu lexer sẽ trả về số, làm thế nào nó đọc được chuỗi ký tự? trả về một số là tốt cho các từ khóa duy nhất, nhưng làm thế nào bạn sẽ đối phó với một chuỗi? Lexer sẽ không phải chuyển đổi chuỗi thành số nhị phân và sau đó trình phân tích cú pháp sẽ chuyển đổi số trở lại thành chuỗi. Có vẻ hợp lý hơn (và dễ dàng hơn) đối với lexer để trả về các chuỗi, và sau đó cho phép trình phân tích cú pháp chuyển đổi bất kỳ chuỗi ký tự chuỗi số nào thành số thực.
Hoặc lexer có thể trả lại cả hai? Tôi đã cố gắng viết một từ vựng đơn giản trong c ++, cho phép bạn chỉ có một kiểu trả về cho các hàm của mình. Do đó dẫn tôi đến câu hỏi của tôi.
Để cô đọng câu hỏi của tôi thành một đoạn văn: Khi viết một từ vựng và giả sử rằng nó chỉ có thể trả về một loại dữ liệu (chuỗi hoặc số), đó sẽ là lựa chọn hợp lý hơn?