2011-05-18 115 views
0

我有以下令牌定義在我的詞法分析器定義CharacterString(例如「ABCD」):忽略令牌字符中的令牌?

CharacterString: 
    Apostrophe 
    (Alphanumeric)* 
    Apostrophe 
; 

是否可以忽略這兩個撇號,然後能夠得到令牌的字符串沒有他們在詞法分析器(通過$ CharacterString.text->字符)?

我想...

CharacterString: 
    Apostrophe { $channel = HIDDEN; } 
    (Alphanumeric)* 
    Apostrophe { $channel = HIDDEN; } 
; 

...沒有成功......這情況下甚至沒有了符合我的字符串(如「OIU」將在解析器失敗 - Missmatched組例外)。

謝謝:)

回答

2

內嵌代碼{$channel=HIDDEN;}影響整個CharacterString,所以你不能做到像你嘗試的方式。

您將需要添加一些自定義代碼並自己刪除引號。這裏有一個小C演示:

grammar T; 

options { 
    language=C; 
} 

parse 
    : (t=. {printf(">\%s<\n", $t.text->chars);})+ EOF 
    ; 

CharacterString 
    : '\'' ~'\''* '\'' 
    { 
     pANTLR3_STRING quoted = GETTEXT(); 
     SETTEXT(quoted->subString(quoted, 1, quoted->len-1)); 
    } 
    ; 

Any 
    : . 
    ; 

和一個小的測試功能:

#include "TLexer.h" 
#include "TParser.h" 

int main(int argc, char *argv[]) 
{ 
    pANTLR3_UINT8 fName = (pANTLR3_UINT8)"input.txt"; 
    pANTLR3_INPUT_STREAM input = antlr3AsciiFileStreamNew(fName); 

    if(input == NULL) 
    { 
    fprintf(stderr, "Failed to open file %s\n", (char *)fName); 
    exit(1); 
    } 

    pTLexer lexer = TLexerNew(input); 

    if(lexer == NULL) 
    { 
    fprintf(stderr, "Unable to create the lexer due to malloc() failure1\n"); 
    exit(1); 
    } 

    pANTLR3_COMMON_TOKEN_STREAM tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lexer)); 

    if(tstream == NULL) 
    { 
    fprintf(stderr, "Out of memory trying to allocate token stream\n"); 
    exit(1); 
    } 

    pTParser parser = TParserNew(tstream); 

    if(parser == NULL) 
    { 
    fprintf(stderr, "Out of memory trying to allocate parser\n"); 
    exit(ANTLR3_ERR_NOMEM); 
    } 

    parser->parse(parser); 

    parser->free(parser); parser = NULL; 
    tstream->free(tstream); tstream = NULL; 
    lexer->free(lexer);  lexer = NULL; 
    input->close(input); input = NULL; 

    return 0; 
} 

和測試input.txt文件包含:

'abc' 

如果現在1)生成的詞法和語法分析器,2)編譯所有.c源文件,以及3)運行main

# 1 
java -cp antlr-3.3.jar org.antlr.Tool T.g 

# 2 
gcc -Wall main.c TLexer.c TParser.c -l antlr3c -o main 

# 3 
./main 

您會看到abc(不帶引號)正在打印到控制檯。

+0

很高興知道它可以在詞法分析器中完成。現在,我不需要處理字符轉義,而前面給出的解決方案對我來說不起作用。 – 2011-05-18 19:25:53

+0

@Julio,看到我的修改答案,包括一個C演示。 – 2011-05-19 13:00:50

+0

謝謝。你是怎麼找到這些宏的? antlr文檔真的很糟糕... – 2011-05-21 12:20:30

1

您可以通過RecognizerSharedState state屬性的詞法分析器的影響令牌建設:

CharacterString: 
    Apostrophe 
    CharSequence 
    Apostrophe 
    { state.text = $CharSequence.text; } 
; 

fragment CharSequence: 
    Alphanumeric+ 
; 
+0

它不工作。狀態變量不存在,在詞法分析器或分析器中都不存在任何類型爲RecognizerSharedState的變量。 – 2011-05-18 19:12:45

+0

你沒有提到你正在使用C-target,而我沒有得到它,所以上面的答案是antlr-java。然而,我查閱了antlr C api和antlr的源代碼,發現這個語法可以訪問'pANTLR3_BASE_RECOGNIZER rec',它的'pANTLR3_RECOGNIZER_SHARED_STATE狀態':'lexer-> rec-> state-> text'。我沒有時間去測試它,但看看它是否有幫助。 – ilyaigpetrov 2011-05-19 14:59:41

+0

這可能是以前的宏所做的。謝謝你的時間 ! – 2011-05-21 12:21:19