匹配正则表达式的有限闭包模式 ({x,y})
Matching the finite closure pattern ({x,y}) of regular expressions
我正在尝试编写一个语法来匹配正则表达式的有限闭包模式(即 foo{1,3} 匹配 'fo' 前缀后的 1 到 3 'o' 次出现)
要将字符串 {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;
有没有更好的方法来处理这种情况?
提前致谢
对于这样一个简单的任务来说,这看起来相当复杂。你可以很容易地让你的词法分析器匹配一个结构(最好是没有空格,如果你通常跳过它们)并且解析器匹配另一种形式。你甚至不需要词法分析器模式。
定义您的关闭规则:
CLOSURE
: OPEN_CURLY INTEGER (COMMA INTEGER?)? CLOSE_CURLY
;
此规则将不匹配任何包含例如空格。因此,如果您的词法分析器与 CLOSURE 不匹配,您将获得所有单独的标记,例如花括号和整数,这些标记最终会出现在您的解析器中以进行匹配(然后您可以将它们视为不同的东西)。
注意: 闭包定义是否也允许 {,n}
(与 {n}
相同)?这需要在 CLOSURE 规则中添加一个额外的 alt。
最后提示:您的 OTHER 规则可能会给您带来麻烦,因为它匹配任何字符,甚至位于其他规则之前。如果您有一个通配符规则,那么它应该是您语法中的最后一个,匹配任何其他规则不匹配的所有内容。
我正在尝试编写一个语法来匹配正则表达式的有限闭包模式(即 foo{1,3} 匹配 'fo' 前缀后的 1 到 3 'o' 次出现)
要将字符串 {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;
有没有更好的方法来处理这种情况? 提前致谢
对于这样一个简单的任务来说,这看起来相当复杂。你可以很容易地让你的词法分析器匹配一个结构(最好是没有空格,如果你通常跳过它们)并且解析器匹配另一种形式。你甚至不需要词法分析器模式。
定义您的关闭规则:
CLOSURE
: OPEN_CURLY INTEGER (COMMA INTEGER?)? CLOSE_CURLY
;
此规则将不匹配任何包含例如空格。因此,如果您的词法分析器与 CLOSURE 不匹配,您将获得所有单独的标记,例如花括号和整数,这些标记最终会出现在您的解析器中以进行匹配(然后您可以将它们视为不同的东西)。
注意: 闭包定义是否也允许 {,n}
(与 {n}
相同)?这需要在 CLOSURE 规则中添加一个额外的 alt。
最后提示:您的 OTHER 规则可能会给您带来麻烦,因为它匹配任何字符,甚至位于其他规则之前。如果您有一个通配符规则,那么它应该是您语法中的最后一个,匹配任何其他规则不匹配的所有内容。