2012-04-16 80 views
0

我一直在尋找flex和野牛教程在線試圖解決我的問題,他們都使用非常簡單的例子,我的是更復雜。我需要解析一個可能包含如下輸入的文件:解析函數作爲參數在flex和野牛

f(x,g(x)) 

這些函數也可能有任意數量的參數。

問題是我需要將f和g作爲解析器的函數處理,而不是將f作爲函數,將g作爲x的參數。換句話說,我需要輸出,看起來像這樣:

[f,x,[g,x]] 

,而不是像:

[f, x, g(x)] 

有人能告訴我如何最好地做到這一點,可能提供正則表達式(因爲我沒那麼與他們好)?

回答

2

在詞彙(flex)級別,您將識別四個令牌作爲標識符:f,x,g和x。在語法(野牛)級別,您可以將g(x)和f(x,g(x))識別爲表達式。非常示意性地:

expression -> numeric-literal | 
       identifier | 
       identifier left-parenthesis arguments right-parenthesis 

arguments -> argument | 
      argument comma arguments 

argument -> expression 

這個小例子只會給你識別令牌和解析之間區別的味道。

您也可以解析論據:

arguments -> argument | 
      arguments comma argument 

有兩個之間有一些細微的差別,這可能是也可能不是有關您的問題。

在詞法層面識別標識符的正則表達式就是你喜歡的。也許

[a-zA-Z][a-zA-Z0-9]* 

換句話說,一個字母后跟可選的數字和字母。

一本好書首先是John Levine的lex & yacc。我還沒有用他的flex &野牛,,但我會推薦它在前面的書的力量。

0

如果它的簡單可能是一個遞歸正則表達式(這是在Perl中)。我相信用語言解析器可以更好地處理它,它可以徹底解決問題。

$str = 'some stuff F(g(x), tx, , 44, Y(hh()) , 99, b())'; 

$open  = '\b\w+\s*'; 

$regex = qr~ 
    (            # 1 
    ($open)          # 2 
    [(] 
     (           # 3      
      (?: (?> (?: (?!$open[(] | [)]) .)+) 
       | (?1)           
      )*            
     )             
    [)] 
    )             
~xs; 

print "Before: ", $str, "\n"; 
print "After: ", parse_func ($str), "\n"; 

### 
sub parse_func { 
    my ($core) = @_; 
    $core =~ s/$regex/ "[$2," . (parse_func($3)) . "]" /eg; 
    return $core; 
} 

輸出

Before: some stuff F(g(x), tx, , 44, Y(hh()) , 99, b()) 
After: some stuff [F, [g,x], tx, , 44, [Y,[hh,]] , 99, [b,]] 
+0

雖然生成所請求的輸出,這是不撓曲/野牛,作爲問題是具體地約。 – origo 2017-02-27 06:16:25

+1

@ user13733 - 雖然問題具體是關於flex/bison,但我發現接受的解決方案是閱讀一本書。這個答案中的正則表達式和生成的輸出是OP所需要的。 SO比理論討論更像是一個解決方案板。用我發佈的例子,在OP閱讀這本書之後,他可能會看到他不會看到的其他實際連接。隨意發佈一個工作的靈活/野牛解決方案。 – sln 2017-02-27 16:41:06