1

私はJFlexの字句仕様を書いています(flexに似ていますが、Java用です)。TraditionalComment(/* */)とDocumentationComment(/** */)に問題があります。これまでのところ、これはJFlexユーザーズマニュアルから抜粋したものです。

LineTerminator = \r|\n|\r\n
InputCharacter = [^\r\n]
WhiteSpace     = {LineTerminator} | [ \t\f]

/* comments */
Comment = {TraditionalComment} | {EndOfLineComment} | {DocumentationComment}

TraditionalComment   = "/*" [^*] ~"*/" | "/*" "*"+ "/"
EndOfLineComment     = "//" {InputCharacter}* {LineTerminator}
DocumentationComment = "/**" {CommentContent} "*"+ "/"
CommentContent       = ( [^*] | \*+ [^/*] )*

{Comment}           { /* Ignore comments */ }
{LineTerminator}    { return LexerToken.PASS; }

LexerToken.PASS後で出力にラインターミネータを渡すことを意味します。今、私がやりたいことは次のとおりです。

改行ターミネータを除いて、コメント内にあるものはすべて無視してください。

たとえば、次のような入力について考えてみます。

/* Some
 * quite long comment. */

実はです/* Some\n * quite long comment. */\n。現在のレクサーでは、1行に変換されます。出力は単一の'\n'になります。しかし、2行にしたいのですが、'\ n\n'です。一般的に、出力には常に入力と同じ行数が必要です。どうやってするの?

4

1 に答える 1

2

数日後、私は解決策を見つけました。ここに投稿します。おそらく誰かが同じ問題を抱えているでしょう。

秘訣は、コメントの中にいることを認識した後、その本文をもう一度調べて、改行ターミネータを見つけた場合は、それらを渡すことです。無視しないでください。

%{
public StringBuilder newLines;
%}

// ...

{Comment}           { 
                        char[] ch; 
                        ch = yytext().toCharArray(); 
                        newLines = new StringBuilder();
                        for (char c : ch)
                        {
                            if (c == '\n')
                            {
                                newLines.append(c);
                            }
                        } 
                        return LexerToken.NEW_LINES;
                    }
于 2012-10-16T09:41:54.843 に答える