regex - ANTLR4 RegEx 词法分析器模式

标签 regex antlr4

我正在为 XSD 中的 RegEx 开发一个 Regx 解析器。 我以前的问题在这里描述:ANTLR4 parsing RegEx

从那时起我就拆分了 Lexer 和 Parser。 现在我在解析括号内的括号时遇到问题。它们应该被视为方括号内的字符,而在外方则被视为分组标记。 这是我的词法分析器语法:

lexer grammar RegExLexer;

Char    : ALPHA ;
Int     : DIGIT ;

LBrack  : '[' ;//-> pushMode(modeRange) ;
RBrack  : ']' ;//-> popMode ;
LBrace  : '(' ;
RBrace  : ')' ;
Semi    : ';' ;
Comma   : ',' ;
Asterisk: '*' ;
Plus    : '+' ;
Dot     : '.' ;
Dash    : '-' ;
Question: '?' ;
LCBrace : '{' ;
RCBrace : '}' ;
Pipe    : '|' ;
Esc     : '\\' ;

WS : [ \t\r\n]+ -> skip ;

fragment DIGIT : [0-9] ;
fragment ALPHA : [a-zA-Z] ;

这里是例子:

[0-9a-z()]+

我觉得我应该使用方括号上的模式来改变 ALPHA 片段的行为。如果我复制该片段,我会收到一条错误消息,提示我不能声明两次。 我已经阅读了有关此的引用资料,但我仍然不明白我应该做什么。

如何实现这些模式?

最佳答案

这是一个快速演示,说明如何使用 ANTLR4 的词法模式创建上下文敏感的词法分析器:

lexer grammar RegexLexer;

START_CHAR_CLASS
 : '[' -> pushMode(CharClass)
 ;

START_GROUP
 : '('
 ;

END_GROUP
 : ')'
 ;

PLAIN_ATOM
 : ~[()\[\]]
 ;

mode CharClass;

END_CHAR_CLASS
 : ']' -> popMode
 ;

CHAR_CLASS_ATOM
 : ~[\r\n\\\]]
 | '\\' .
 ;

词法分析器生成后,可以使用下面的类进行测试:

import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.Token;

public class Main {
    public static void main(String[] args) {
        RegexLexer lexer = new RegexLexer(new ANTLRInputStream("([()\\]])"));
        for (Token token : lexer.getAllTokens()) {
            System.out.printf("%-20s %s\n", RegexLexer.VOCABULARY.getSymbolicName(token.getType()), token.getText());
        }
    }
}

如果您运行这个 Main 类,以下内容将打印到您的控制台:

START_GROUP          (
START_CHAR_CLASS     [
CHAR_CLASS_ATOM      (
CHAR_CLASS_ATOM      )
CHAR_CLASS_ATOM      \]
END_CHAR_CLASS       ]
END_GROUP            )

如您所见,() 在字符类外部的标记化与它们在字符类内部的不同。

关于regex - ANTLR4 RegEx 词法分析器模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34229658/

相关文章:

java - 读取 ANTLR 中的多行值,直到出现特殊符号

javascript - 正则表达式禁止所有特殊字符但允许 jQuery 中的德语变音符号?

Java字符串用正则表达式分割,忽略括号中的内容

php - 如何找到最后一个段落元素?

c - Antlr4 预处理器语法与 C 语法集成

antlr4 - 错误还是功能?在标记规则上输入监听器的方法

parsing - ANTLR4 - '#' 语法错误(替代规则标签)

php - 相当于 PHP preg_replace 的 JavaScript

python - django - 使用正则表达式去除和替换 urlfield

antlr - 匹配可选元素序列中的至少一个元素(ANTLR)