2014-12-18 134 views
1

我使用Flex來標記輸入文件,以便我最終可以使用Bison來製作簡單的C編譯器。C標識符的正則表達式

所以我還在鬼混與Flex,我試圖提取數量,而忽略標識符和空格

%{ 

#include "stdio.h" 

%} 

dgt [0-9] 
letter [A-Za-z] 
white [ \r\t]+ 
id {letter}({letter}|{dgt})* 
number {dgt}+ 

%% 
{number} return atoi(yytext); 
{id} { } 
{white} { } 

%% 

void main(){ 
    int val=0; 
    while((val=yylex())>0) 
    printf("You Entered %d\n",val); 
} 

這裏的問題是,隨着輸入文件像這樣:

hello 123 test assadf507ascv 123asd 0 

我得到這樣的輸出:

You Entered 123 
You Entered 123 

我需要它RECOG nize只是數字,第二個輸出來自123asd,這應該是一個無效的標識符。

我哪裏出錯了? 我應該制定一個明確檢測該案例的規則嗎?

回答

3

您的號碼定義只是找1個或多個數字,這將匹配任何地方組數字,即使他們與非數字字符連接起來。

number {dgt}+ 

這是正則表達式相當於:

[0-9]+ 

這聽起來像你需要測試,有沒有多餘的字符後,立即將數字字符提取您的有效數字以下。我通過創建另一個規則來顯式匹配這些不好的術語,從而導致它們被忽略爲「數字」。

舉例:test.flex:

%{ 

#include "stdio.h" 

%} 

letter [A-Za-z] 
white [ \r\t]+ 
id {letter}({letter}|{dgt})* 
dgt [0-9] 
number {dgt}+ 
invalid [0-9]+[a-zA-Z_]+ 

%% 

{id} { } 
{white} { } 
{invalid} { } 
{number} return atoi(yytext); 

%% 

void main(){ 
    int val=0; 
    while((val=yylex())>0) 
    printf("You Entered %d\n",val); 
} 

您可能需要改變invalid定義下半年,具體取決於哪個字符你不想跟着數字。另請注意,invalid規則必須位於number規則之前,因此它將首先匹配並放棄無效條款。

hello 123 test assadf507ascv 234asdf 456 0 
You Entered 123 
You Entered 456 

Flex manual chapter on Patterns

+0

我明白了,但爲什麼使用尾隨?爲什麼不直接連接? – Maverick 2014-12-19 01:09:40

+0

啊,是的。抱歉。當我試圖讓一條規則只匹配一個數字*而沒有*其他字符時,我正在擺弄尾隨的上下文。類似於[0-9] +/[^ a-zA-Z_]。但是這並不奏效,我忘記了我不需要最後的解決方案。答案已更新。 – 2014-12-19 01:16:02

+0

太棒了,對我也有效,謝謝。 – Maverick 2014-12-19 01:18:17

0

我不熟悉Flex,但也許你可以試試這個:

dgt [0-9] 
letter [A-Za-z] 
white [ \r\t]+ 
id {letter}({letter}|{dgt})* 
number \b{dgt}+\b 

是否支持\b我不知道,但在正則表達式的意思是「單詞邊界」。如果不支持,您還可以嘗試:

number {white}{dgt}+{white} 

但請注意,這不會捕獲出現在行首或末尾的數字。也許

number (^|{white}){dgt}+($|{white})