使用 Parse::Lex,有没有办法只在某些状态/条件下返回令牌



假设我只需要标记和解析多行注释,我将如何使用 Parse::Lex 来做到这一点。使用 flex-bisson 时,lex 文件的规则部分中任何模式的默认操作曾经是"skip"。

%%
.*    ;
%%

怎么做这里?

[编辑] 好吧,我试过了,我仍然缺少一些东西 - 这是我的代码 - 和结果。我哪里出错了??

我的简化 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

Trace is ON in class Parse::Lex
Can't call method "name" on an undefined value at qnlex.pl line 26, <STDIN> line 1.

使用此处显示的 skip 设置使用 Regexp::Common 来帮助构造与平衡的注释分隔符对匹配的正则表达式。我假设/* */作为注释分隔符,但它们可以是任何东西。

$lexer->skip(qr! [ t]+ | $RE{balanced}{-begin=>'/*'}{-end=>'*/'} !xms);

[ t]+替代方案保持不变,因为这是默认值。

嗯,我想通了:)非常简单 - 我所要做的就是在遇到我要跳过的令牌时让 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;
    }
}

最新更新