2017-02-18 73 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规则,那么它应该是你语法中的最后一个,匹配没有任何其他规则匹配的所有东西。