4

複数行のコメントのみをトークン化して解析する必要があると仮定すると、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.
4

2 に答える 2

1

Regexp :: Commonskipを使用してここに示されている設定を使用して、コメント区切り文字のバランスの取れたペアに一致する正規表現を作成します。コメント区切り文字として想定しましたが、何でもかまいません。/* */

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

これ[ \t]+がデフォルトであるため、代替案はそのまま残されます。

于 2012-08-15T17:58:17.140 に答える
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;
    }
}
于 2012-10-09T19:28:04.623 に答える