2014-04-01 42 views
0

我寫的,看起來像下面這樣的語言解析器:詞法分析器來處理與行號前綴線

L00<<identifier>> 
L10<<keyword>> 
L250<<identifier>> 
<<identifier>> 

也就是說,每行可能會或可能不會與形式的行號開始Lxxx..('L'後跟一個或多個數字),後跟一個標識符或關鍵字。標識符是標準的[a-zA-Z_][a-zA-Z0-9_]*,並且L後面的位數不固定。行號和後面的標識符/關鍵字之間的空格是可選的(大多數情況下不存在)。

我現在的詞法分析器的樣子:

// Parser rules 
commands  : command*; 
command  : LINE_NUM? keyword NEWLINE 
       | LINE_NUM? IDENTIFIER NEWLINE; 
keyword  : KEYWORD_A | KEYWORD_B | ... ; 

// Lexer rules 
fragment INT : [0-9]+; 
LINE_NUM  : 'L' INT; 
KEYWORD_A  : 'someKeyword'; 
KEYWORD_B  : 'reservedWord'; 
... 
IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_]* 

但是這導致了LINE_NUM令牌被符號化的IDENTIFIER S開頭的所有行。

有沒有辦法使用ANTLR語法正確標記這個輸入?

+0

'LINE_NUM'和'IDENTIFIER'之間是否有空格(或空格)? –

+0

@BartL'LINE_NUM'和'IDENTIFIER'之間的空白是可選的。我編輯了這個問題來澄清。 –

+0

您的示例意味着(如果它有效)標識符可以選擇以「LINE_NUM」開頭。語法表示這是強制性的。是對的嗎? – Onur

回答

1

你需要一個語義謂詞添加到IDENTIFIER

IDENTIFIER 
    : {_input.getCharPositionInLine() != 0 
     || _input.LA(1) != 'L' 
     || !Character.isDigit(_input.LA(2))}? 
    [a-zA-Z_] [a-zA-Z0-9_]* 
    ; 

您也可避免語義斷言使用詞法模式。

// 
// Default mode is active at the beginning of a line 
// 

LINE_NUM 
    : 'L' [0-9]+ -> pushMode(NotBeginningOfLine) 
    ; 

KEYWORD_A : 'someKeyword' -> pushMode(NotBeginningOfLine); 
KEYWORD_B : 'reservedWord' -> pushMode(NotBeginningOfLine); 
IDENTIFIER 
    : ('L' 
    | 'L' [a-zA-Z_] [a-zA-Z0-9_]* 
    | [a-zA-KM-Z_] [a-zA-Z0-9_]* 
    ) 
    -> pushMode(NotBeginningOfLine) 
    ; 
NL : ('\r' '\n'? | '\n'); 

mode NotBeginningOfLine; 

    NotBeginningOfLine_NL : ('\r' '\n'? | '\n') -> type(NL), popMode; 
    NotBeginningOfLine_KEYWORD_A : KEYWORD_A -> type(KEYWORD_A); 
    NotBeginningOfLine_KEYWORD_B : KEYWORD_B -> type(KEYWORD_B); 
    NotBeginningOfLine_IDENTIFIER 
    : [a-zA-Z_] [a-zA-Z0-9_]* -> type(IDENTIFIER) 
    ; 
+0

這兩種方法看起來不錯,謝謝!我應該考慮的任何考慮因素都會促使我走向其中一個或另一個? –

+0

@HarrisonPaine詞法分析器不能評估語義謂詞,但組合語法中的詞法分析器不能有多種模式。如果是我,我會使用多種模式,因爲我始終將我的詞法分析器和解析器分開。 –

+0

我實施了第二種方法,並意識到我實際面臨着一個不同的問題,這在簡化問題中並不明顯。實際的語言以另一種格式嵌套,它提供了所有定義的標識符的列表。使用這裏的方法:http://stackoverflow.com/a/6108549/2483451我可以準確地標記每個標識符,節省了很多頭痛。不過,謝謝你回答我發佈的問題。你肯定幫助我擺脫攤位。 –