假设我只需要标记化和解析多行注释,我将如何使用Parse :: Lex执行此操作。使用flex-bison时,lex文件规则部分中任何模式的默认操作都是“跳过”。
%%
.* ;
%%
这里怎么做?
[编辑]嗯,我试过了,我仍然缺少一些东西 - 这是我的代码 - 和结果。我哪里出错了?
我简化的lex文件:
use Parse::Lex;
use Regexp::Common;
use YParser;
my $lexer;
my @token = (
qw|esp:TA abcdefgh|,
qw(esp:REST .|\n),
);
Parse::Lex->trace;
Parse::Lex->exclusive('esp');
$lexer = Parse::Lex->new(@token);
$lexer->from(\*STDIN);
$lexer->skip(qr! [ \t]+ | $RE{balanced}{-begin=>'/*'}{-end=>'*/'} !xms);
$lexer->start('esp');
my $j = YParser->new();
$j->YYParse(yylex => \&lex);
sub lex {
my $token = $lexer->next;
return ('', undef) if $lexer->eoi;
if ($token->name eq 'TA' || $token->name eq 'REST') {
return ($token->name, {LINENO => $lexer->line, TEXT => $token->text});
}
}
我的简化语法文件
% token TA REST
%%
Program: Element
| Program Element
;
Element: TA
| REST
;
%%
输入文件:
abcdefgh
/*sdf*/
结果: perl lexfile.pl< inputfile中
Trace is ON in class Parse::Lex
Can't call method "name" on an undefined value at qnlex.pl line 26, <STDIN> line 1.
答案 0 :(得分:1)
使用skip
设置,此处显示使用Regexp::Common来帮助构建匹配平衡的注释分隔符对的正则表达式。我假设/* */
为评论分隔符,但它们可以是任何内容。
$lexer->skip(qr! [ \t]+ | $RE{balanced}{-begin=>'/*'}{-end=>'*/'} !xms);
由于这是默认设置,因此保留了[ \t]+
替代方案。
答案 1 :(得分:1)
好吧,我想出来了:)很简单 - 我所要做的就是让lex在遇到我想跳过的令牌时获得下一个令牌。下面是跳过将令牌“REST”传递给解析器的代码。
sub lex {
my $token;
NEXTTOKEN:
$token = $lexer->next;
return ('', undef) if $lexer->eoi;
if ($token->name eq 'TA') {
return ($token->name, {LINENO => $lexer->line, TEXT => $token->text});
}
elsif ($token->name eq 'REST') {
goto NEXTTOKEN;
}
}