2015-12-11 2 views
1

Я работаю над парсером Regx для RegEx внутри XSD. Моя предыдущая проблема была описана здесь: ANTLR4 parsing RegExANTLR4 Режимы lexer 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 фрагмента. Если я скопирую фрагмент, я получаю сообщение о том, что не могу иметь объявление дважды. Я прочитал ссылку об этом, и я до сих пор не понимаю, что я должен делать.

Как реализовать режимы?

+0

Как насчет 'CharSet: '[' '^'? ']'? '-'? ([^] \\ -] '-' [^] \\ -] | [^] \\ -] | ESCAPE_SEQUENCE) * '-'? ']' ' – programmerjake

+0

Я просто не знаю, что вы имели в виду, и позвольте использовать это. – user1941235

+0

это токен для antlr, который является классом символов. – programmerjake

ответ

2

Вам придется обрабатывать это в парсере, а не лексере. Когда lexer видит '(', он вернет токен LBrace.Для lexer нет никакого контекста относительно того, где токен просматривается, он просто выдает ввод в токены. Вам нужно будет определить правила синтаксического разбора и при обработке дерева синтаксического анализа, то вы можете определить, был LBrace внутри скобок или не

+0

Я пытаюсь получить это весь день :-) Если я попробую этот пример '[0-9] {3} - (([0-9() + \ -] | G {1}) | ([ AZ] {2})) 'Я получаю это дерево (фигурные скобки внизу слева) [link] (http://z62i.imgup.net/tree520b.png) Я бы хотел увидеть их как exactChar.alphNum , Но если я просто добавлю фигурные скобки в алфавит или какой-то новый токен, это будет бесполезно для всей группы. Каждая фигурка становится точным персонажем. – user1941235

+0

ОК, я думаю, я понял. -> [link] (http://x88i.imgup.net/tree04df.png) – user1941235

+2

Да, вы можете обрабатывать его в синтаксическом анализаторе, но с ANTLR4 режимы также могут использоваться, чтобы дать лексеру некоторую чувствительность к контексту. –

3

Вот краткий демо о том, как можно создать контекстную лексера, используя лексические-режимы 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()); 
     } 
    } 
} 

И если вы запустите этот главный класс, происходит некорректно будет выводиться на консоль:

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

Как вы можете видеть, ( и ) являются лексемы по-разному вне символьного класса, поскольку они находятся внутри него.

+0

Большое спасибо за этот пример. Я думаю, что я хорошо разбираюсь в решении парсера, но я, конечно же, буду проверять режимы лексера! В этот момент основное внимание уделяется получению кода C#, который работает с этой базовой грамматикой, которую я создал. И пока я понятия не имею, как подойти к нему :-) – user1941235

+0

Нет проблем. Вы также можете взглянуть на эту грамматику PCRE: https://github.com/bkiers/pcre-parser/blob/master/src/main/antlr4/nl/bigo/pcreparser/PCRE.g4 –

Смежные вопросы