2010-10-01 35 views
2

我試圖解析一個特定的(本土種植的)JavaDoc標籤在我的JavaScript文件中,我正在努力瞭解如何實現這一點。 ANTLR抱怨如下記載:使用ANTLR來解析JavaDoc評論

jsDocComment 
    : '/**' (importJsDocCommand | ~('*/'))* '*/' <== See note 1 
    ; 

importJsDocCommand 
    : '@import' gav 
    ; 

gav 
    : gavGroup ':' gavArtifact 
    -> ^(IMPORT gavGroup gavArtifact) 
    ; 

gavGroup 
    : gavIdentifier 
    ; 

gavArtifact 
    : gavIdentifier 
    ; 

gavIdentifier 
    : ('a'..'z'|'A'..'Z') ('a'..'z'|'A'..'Z'|'0'..'9'|'_'|'-'|'.')* <== See note 2 
    ; 
  • 注1:下面的替代品不能匹配:1

  • 注2:決定可以匹配輸入諸如「 '_' ..」 '。」使用多個備選方案:1,2結果,替代(S)2爲輸入

這裏禁用就是我試圖解析:

/** a */ 
/** @something */ 
/** @import com.jquery:jquery */ 

所有行應解析正常,只需在名爲「IMPORT」的AST樹元素下創建的@import語句(及其Maven組:artifact值)。

感謝您的協助。

+0

這與Javascript有什麼關係? – Pointy 2010-10-01 02:46:59

+1

我在JavaScript文件中使用JavaDoc註釋 - 上面的第一句話。 :-) – 2010-10-01 02:53:08

回答

0

我對這個問題的解決方案是使用ANTLR沒有語法分析器的詞法分析器,過濾掉了我不感興趣的東西。下面是我想到的(它也查找全局定義的變量以及進口):

lexer grammar ECMAScriptLexer; 

options {filter=true;} 

@lexer::header { 
    package com.classactionpl.mojo.javascript; 
} 

@members { 
    int scopeLevel = 0; 
} 

IMPORTDOC 
    : '/**' .* IMPORT .* (IMPORT)* '*/' 
    ; 

fragment 
IMPORT 
    : '@import' WS groupId=GAVID ':' artifactId=GAVID 
     {System.out.println("found import: " + $groupId.text + ":" + $artifactId.text);} 
    ; 

fragment 
GAVID 
    : ('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'-'|'0'..'9'|'.')* 
    ; 

COMMENT 
    : '/*' .* '*/' 
    ; 

SL_COMMENT 
    : '//' .* '\n' 
    ; 

ENTER_SCOPE 
    : '{' {++scopeLevel;} 
    ; 

EXIT_SCOPE 
    : '}' {--scopeLevel;} 
    ; 

WINDOW_VAR 
    : 'window.' name=ID WS? value=(';' | '=') ~('=') 
     { 
      System.out.println("found window var " + $name.text + " = " + ($value == ';')); 
     } 
    ; 

GLOBAL_VAR 
    : 'var' WS name=ID WS? value=(';' | '=') ~('=') 
     { 
      if (scopeLevel == 0) { 
       System.out.println("found global var " + $name.text + " = " + ($value == ';')); 
      } 
     } 
    ; 

fragment 
ID : ('a'..'z'|'A'..'Z'|'$'|'_') ('a'..'z'|'A'..'Z'|'$'|'_'|'0'..'9')* 
    ; 

fragment 
WS : (' '|'\t'|'\n')+ 
    ; 
+0

你不應該考慮字符串文字嗎?當你遇到'var s =「{」;'時,你的詞法分析器將產生無效的標記,因爲你的字符串中的'{''會增加'scopeLevel'。 – 2010-10-15 20:12:44

+0

啊哈 - 是的,好點。我最好這樣做。 :-)然而,我的主要觀點是使用詞法分析器而不是解析器。不過謝謝。 – 2010-10-17 04:09:10

2

克里斯托弗·亨特寫道:

  • 注1:下面的方案不能匹配:1

~('*/')是不正確的:你只能否定在詞法分析器單個字符規則(!)。在你的代碼片段中,你試圖否定解析器規則中的某些內容。在解析器規則中,您不是否定字符,而是記號。例如:

parse : ~A; 
foo : .; 
A  : 'A'; 
B  : 'B'; 
C  : 'C'; 

parse規則將比賽除了'A'任何字符,但無論是匹配或'B''C'foo確實不是匹配任何字符,但匹配任何標記(或詞法分析規則)。

克里斯托弗亨特寫道:

  • 注2:決策可以使用多個替代匹配輸入諸如 「 '_' .. ''」:1,2。結果,替代( S)2例爲輸入禁用

兩個問題:

  1. 你發佈了整個語法嗎?
  2. 你試圖解析整個JS文件,或者你只是「過濾」JS文件並拔出JavaDoc註釋?

如果是後者,使用ANTLR有更簡單的方法來做到這一點(並且可以給出解釋,如果是這種情況)。

編輯

這是最簡單的,只是增加一個新的DocComment規則詞法分析器和訂貨量大它只是上面的(現有的)Comment規則:

DocComment 
    : '/**' (options {greedy=false;} : .)* '*/' 
    ; 

Comment 
    : '/*' (options {greedy=false;} : .)* '*/' {$channel=HIDDEN;} 
    ; 
+0

感謝您的澄清。角色與令牌 - 這對我來說很有意義!我沒有發表整個語法 - 對不起。我將添加到ECMAScript語法(http://www.antlr.org/grammar/1206736738015/JavaScript.g)。感謝您的大力幫助。 – 2010-10-01 22:47:49

+0

@Christopher,沒問題。你還有問題嗎?如果是這樣,你可以發佈修改過的語法並指出問題是什麼嗎? – 2010-10-02 07:07:19

+0

我真的很感激反饋,但如果我定義了DocComment,那麼我如何解析其中包含的@import聲明?對不起,ANTLR非常新穎,並感謝指導。 – 2010-10-03 00:01:21