2012-10-13 54 views
1

我正在編寫JFlex的詞法規範(就像flex,但是對於Java)。我對TraditionalComment(/* */)和DocumentationComment(/** */)有問題。到目前爲止,我有這個,從JFlex User's Manual採取:後來我路過行終止輸出刪除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。對於當前的詞法分析器,它將被轉換爲單行。輸出將是單個'\ n'。但我想要兩行,'\ n \ n'。一般來說,我希望我的輸出將始終具有與輸入相同的行數。怎麼做?

回答

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; 
        }