2017-02-18 14 views
1

Я пытаюсь написать грамматику, которая будет соответствовать шаблону конечного закрытия для регулярных выражений (т.е. foo {1,3} соответствует 1 to 3 'o' появления после префикса «fo»)Соответствие шаблону конечного закрытия ({x, y}) регулярных выражений

Чтобы идентифицировать строку {x, y} как конечное замыкание, она не должна содержать пробелы, например, {1, 3} распознана как последовательность из семи символов.

Я написал следующий файл лексера и парсера, но я не уверен, что это лучшее решение. Я использую лексический режим для шаблона замыкания, который активируется, когда регулярное выражение соответствует допустимому выражению закрытия.

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

Это выглядит довольно сложно для такой простой задачи. Вы можете легко позволить вашему лексеру соответствовать одной конструкции (желательно, чтобы без пробелов, если вы обычно пропустите их), и парсер соответствует другой форме. Для этого вам даже не нужны режимы lexer.

Определите правило закрытия:

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

Это правило не будет соответствовать какой-либо форме, которая содержит, например, пробелы. Итак, если ваш лексер не соответствует CLOSURE, вы получите все индивидуальные жетоны, такие как фигурные скобки и целые числа, которые попадают в ваш синтаксический анализатор для сопоставления (где вы можете относиться к ним как к чему-то другому).

NB: не включает определение закрытия также {,n} (то же, что и {n})? Это требует дополнительного alt в правиле ЗАКРЫТИЯ.

И, наконец, подсказка: ваше ДРУГОЕ правило, вероятно, даст вам проблемы, поскольку оно соответствует любому символу и даже расположено перед другими правилами. Если у вас есть правило whildcard, оно должно быть последним в вашей грамматике, сопоставляя все, что не соответствует никакому другому правилу.