使用函数作为flex和bison中的参数解析函数

时间:2012-04-16 20:07:39

标签: regex parsing bison flex-lexer

我一直在寻找在线尝试解决我的问题的flex和bison教程,他们都使用非常简单的例子,我的更复杂。我需要解析一个包含输入的文件,如下所示:

f(x,g(x))

这些函数也可能有任意数量的参数。

问题是我需要f和g被解析器视为函数,而不是f作为函数而g作为x的参数。换句话说,我需要看起来像这样的输出:

[f,x,[g,x]]

而不喜欢:

[f, x, g(x)]

有人能告诉我如何最好地做到这一点,并可能提供正则表达式(因为我对他们不是很好)?

2 个答案:

答案 0 :(得分:3)

在词法(flex)级别,您会将四个标记识别为标识符:f,x,g和x。在语法(bison)级别,您将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&野牛,,但我会根据之前的书推荐它。

答案 1 :(得分: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,]]