2017-02-18 72 views
1

我正在嘗試編寫一個匹配正則表達式的有限閉合模式的語法(即foo {1,3}匹配1到3'o'在'fo'前綴後面出現)匹配正則表達式的有限閉合模式({x,y})

要將字符串{x,y}識別爲有限閉包,它不得包含空格,例如{1,3}被識別爲一個由7個字符組成的序列。

我寫了下面的詞法分析器和解析器文件,但我不確定這是否是最佳解決方案。我正在使用一個詞法模式來處理封閉模式,當正則表達式匹配一個有效的閉包表達式時,它將被激活。

lexer grammar closure_lexer; 

@header { using System; 
      using System.IO; } 

@lexer::members{ 
       public static bool guard = true; 
       public static int LBindex = 0; 
} 

OTHER : .; 
NL : '\r'? '\n' ; 
CLOSURE_FLAG : {guard}? {LBindex =InputStream.Index; } 
        '{' INTEGER (',' INTEGER?)? '}' 
    { closure_lexer.guard  = false; 
     // Go back to the opening brace 
     InputStream.Seek(LBindex); 
     Console.WriteLine("Enter Closure Mode"); 
     Mode(CLOSURE); 
     } -> skip 

; 

mode CLOSURE; 
LB : '{'; 
RB : '}' { closure_lexer.guard = true; 
      Mode(0); Console.WriteLine("Enter  Default Mode"); }; 
COMMA : ',' ; 
NUMBER : INTEGER ; 


fragment INTEGER : [1-9][0-9]*; 

和解析器語法

parser grammar closure_parser; 

@header { using System; 
     using System.IO; } 

options { tokenVocab = closure_lexer; } 

compileUnit 
:  (other {Console.WriteLine("OTHER: {0}",$other.text);} | 
    closure {Console.WriteLine("CLOSURE: {0}",$closure.text);})+ 
; 

other : (OTHER | NL)+; 

closure : LB NUMBER (COMMA NUMBER?)? RB; 

有沒有更好的方式來處理這種情況呢? 在此先感謝

回答

0

對於如此簡單的任務,這看起來相當複雜。您可以輕鬆讓您的詞法分析器匹配一個構造(最好沒有空格,如果您通常跳過它們)並且解析器與其他表單匹配。你甚至不需要詞法分析模式。

定義你的閉合規則:

CLOSURE 
    : OPEN_CURLY INTEGER (COMMA INTEGER?)? CLOSE_CURLY 
; 

此規則將不會匹配任何形式包含例如空格。因此,如果您的詞法分析器與CLOSURE不匹配,您將得到所有單個令牌,例如大括號和整數,最後在您的解析器中進行匹配(然後您可以將它們視爲不同的東西)。

注:不封閉的定義還允許{,n}(與{n}相同)?這需要在CLOSURE規則中增加一個alt。

最後提示:您的OTHER規則可能會給您帶來麻煩,因爲它與任何字符匹配,甚至位於其他規則之前。如果你有一個whildcard規則,那麼它應該是你語法中的最後一個,匹配沒有任何其他規則匹配的所有東西。