2012-04-16 84 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