Почему JFlex отклоняют. +? (? = ->) - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь создать простой плагин языковой идеи. Я хочу сопоставить приведенный ниже пример кода как 3 токена в виде текста до ->, между -> и :, после :

Пример: First part -> Second Part: Third part

Для первой части когда я пытаюсь регулярное выражение .+?(?=->) на https://regex101.com/r/TDBWg0/1 это работает. Но согласно JFlex .+?(?=->) имеет синтаксическую ошибку:

Error in file "Simple.flex" (line 41):  
Syntax error.
FIRST_PART=.+(?=(->))  
              ^

1 Ответ

0 голосов
/ 15 февраля 2020

Генераторы Lexer, такие как JFlex, часто имеют другой синтаксис и набор функций, чем большинство других реализаций regex, поэтому такие помощники, как regex101, не всегда так полезны для них. Вместо этого вы должны взглянуть на руководство по JFlex , чтобы увидеть, какой синтаксис поддерживает JFlex.

Здесь есть две вещи, на которые следует обратить внимание:

  • Синтаксис для lookahead: /regex not (?=regex)
  • Нет синтаксиса для не жадных квантификаторов
  • <и> необходимо заключать в кавычки или экранировать

Так что .+/"->" будет допустимое регулярное выражение, но при наличии нескольких -> s оно будет соответствовать последнему ->, а не первому. Предположительно, вы пытались сделать + не жадным, чтобы он совпадал только с первым, так что это бесполезно.

Поскольку в JFlex нет не жадных модификаторов, нам нужен другой подход. Если мы снова посмотрим на доступные функции регулярных выражений, то увидим, что есть оператор ~, который работает следующим образом:

~a (upto)

соответствует всему до (и включая) первое вхождение текста, соответствующего a. Выражение ~a эквивалентно !([^]* a [^]*) a. Традиционный комментарий C в стиле соответствует "/*" ~"*/".

Таким образом, вы хотите использовать регулярное выражение просто ~"->".

Другой подход, который работает практически с каждым регулярным выражением В качестве реализации можно было бы написать регулярное выражение, которое определенно соответствует всему, что не является ->, то есть любым не - символом или -, за которым не следует >. Так что это будет:

([^-]|-[^\>])+
...