Соответствует Lua's & # 8220; Длинная скобка & # 8221; синтаксис строки
Вопрос
Я пишу лексер jFlex для Lua, и у меня возникают проблемы при разработке регулярного выражения, соответствующего одной конкретной части спецификации языка:
Литеральные строки также могут быть определены с использованием длинного формата, заключенного в длинные скобки. Мы определяем открывающую длинную скобку уровня n как открывающую квадратную скобку, за которой следуют n знаков равенства, за которыми следует другая открывающая квадратная скобка. Итак, открывающая длинная скобка уровня 0 записывается как [[, открывающая длинная скобка уровня 1 записывается как [= [и т. Д.]. Закрывающая длинная скобка определяется аналогично; например, закрывающая длинная скобка уровня 4 записывается как] ====]. Длинная строка начинается с открывающей длинной скобки любого уровня и заканчивается первой закрывающей длинной скобкой того же уровня. Литералы в этой форме в скобках могут работать на несколько строк, не интерпретировать любые escape-последовательности и игнорировать длинные скобки любого другого уровня. Они могут содержать все, кроме закрывающей скобки соответствующего уровня.
Короче говоря, я пытаюсь разработать регулярное выражение, которое будет соответствовать открывающей длинной скобке, содержимому строки между ними и закрывающей длинной скобке. Совпадение должно иметь место только тогда, когда открывающая длинная скобка и закрывающая длинная скобка имеют одинаковое количество знаков равенства, которое может быть равно нулю или более.
Решение
\[(=*)\[.*?\]\1\]
\ 1 захватывает первый ().
Другие советы
Ну, я боюсь, что токенизация с регулярными выражениями недостаточно хороша для этой задачи. Регулярные выражения просто недостаточно мощны.
Нет способа сравнить количество отметок '=' с помощью простых регулярных выражений в jFlex. В Perl для этого есть хак (\ 1, как предложено выше), но речь идет не о программировании на Perl, а о лексере jFlex.
Решение состоит в том, чтобы пойти с \ [= * \ [для левого скобочного токена, \] = * \] для правого скобочного токена, а затем сравнить его в слое выше (анализаторе), если они совпадают по длине. р>
В любом случае, вы можете посмотреть на read_long_string () в исходном коде lua в llex.c и посмотреть, как они это сделали, вообще не используя регулярные выражения.
\[(=*)\[.*?\]\1\]