我一直在寻找在线尝试解决我的问题的flex和bison教程,他们都使用非常简单的例子,我的更复杂。我需要解析一个包含输入的文件,如下所示:
f(x,g(x))
这些函数也可能有任意数量的参数。
问题是我需要f和g被解析器视为函数,而不是f作为函数而g作为x的参数。换句话说,我需要看起来像这样的输出:
[f,x,[g,x]]
而不喜欢:
[f, x, g(x)]
有人能告诉我如何最好地做到这一点,并可能提供正则表达式(因为我对他们不是很好)?
答案 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,]]