Hi, could someone please help me few steps further? I'm almost finished with the parser I need.
The only missing part is grokking C-preprocessor-like #if defined / #endif expressions, which can be surrounded by brackets and contain && and || as binary operators. Unfortunately my script fails already with some syntax error, which I couldn't fix yet: Parse::RecDescent: Treating "conjunction:" as a rule declaration Warning: Undefined (sub)rule "keyword" used in a production. (Hint: Will you be providing this rule later, or did you perhaps misspell "keyword"? Otherwise it will be treated as an immediate <reject>.) Warning: Undefined (sub)rule "value" used in a production. (Hint: Will you be providing this rule later, or did you perhaps misspell "value"? Otherwise it will be treated as an immediate <reject>.) Also, please any suggestions on how to handle the nested brackets properly? I keep looking at the demo_operator.pl and other P::RD examples but couldn't figure it out yet... What I also don't know yet, is in which datastructure to save the binary operators and conditions that I'm trying to parse. I'm trying to convert the format below to the GNU make's ifdef/ifndef Regards Alex #!/usr/bin/perl -w use strict; use vars qw($parser $text %top); use Data::Dumper; use Parse::RecDescent; $RD_WARN = 1; $RD_HINT = 1; $RD_TRACE = 120; $parser = Parse::RecDescent->new(q( mmpfile: chunk(s) /^\Z/ chunk: assignment | <error> assignment: keyword <skip: '[ \t]+'> value(s) { push @{$::top{uc $item{keyword}}}, @{$item[-1]}; } ifdef: /#\s*if/ <skip: '[ \t]+'> condition <skip: $item[2]> chunk(s?) /#\s*endif/ condition: '(' conjunction ')' | conjunction conjunction: disjunction(s /&&/i) disjunction: unary_expr(s /\|\|/i) unary_expr: '!' defined_expr | defined_expr defined_expr: 'defined' '(' value ')' | 'defined' value value: /VAL\d+\b/i keyword: /KEY\d+\b/i )) or die 'Bad grammar'; $text .= $_ while (<DATA>); defined $parser->mmpfile($text) or die 'Bad text'; print Data::Dumper->Dump([\%top], [qw(top)]); __DATA__ #if defined val1 key1 val2 #endif #if ! ( (defined ( val3 ) ) || ( defined (val4) ) ) key2 val5 #endif