Соответствует синтаксису строки "Длинная скобка" Lua - PullRequest
0 голосов
/ 21 июня 2009

Я пишу лексер jFlex для Lua, и у меня возникают проблемы при разработке регулярного выражения, соответствующего одной конкретной части спецификации языка:

Литеральные строки также могут быть определены с использованием длинного формата, заключенного в длинные скобки. Мы определяем открывающую длинную скобку уровня n как открывающую квадратную скобку, за которой следуют n знаков равенства, за которыми следует другая открывающая квадратная скобка. Итак, открывающая длинная скобка уровня 0 записывается как [[, открывающая длинная скобка уровня 1 записывается как [= [и т. Д.]. Закрывающая длинная скобка определяется аналогично; например, закрывающая длинная скобка уровня 4 записывается как] ====]. Длинная строка начинается с открывающей длинной скобки любого уровня и заканчивается первой закрывающей длинной скобкой того же уровня. Литералы в этой форме в скобках могут работать на несколько строк, не интерпретировать любые escape-последовательности и игнорировать длинные скобки любого другого уровня. Они могут содержать все, кроме закрывающей скобки соответствующего уровня.

Короче говоря, я пытаюсь разработать регулярное выражение, которое будет соответствовать открывающей длинной скобке, содержимому строки между ними и закрывающей длинной скобке. Совпадение должно иметь место только тогда, когда открывающая длинная скобка и закрывающая длинная скобка имеют одинаковое количество знаков равенства, которое может быть равно нулю или более.

Ответы [ 3 ]

5 голосов
/ 22 июня 2009

Ну, я боюсь, что токенизация с регулярными выражениями недостаточно хороша для этой задачи. Регулярные выражения просто недостаточно мощны.

Нет способа сравнить количество меток '=' с помощью простых регулярных выражений в jFlex. В Perl для этого есть хак (\ 1, как предложено выше), но речь идет не о программировании на Perl, а о лексере jFlex.

Решение состоит в том, чтобы пойти с \ [= * \ [для левого скобочного токена, \] = * \] для правого скобочного токена, а затем в слое выше (синтаксическом анализаторе) сравнить, если они совпадают по длине.

В любом случае, вы можете посмотреть на read_long_string () в исходном коде lua в llex.c и посмотреть, как они это сделали, вообще не используя регулярные выражения.

4 голосов
/ 21 июня 2009
\[(=*)\[.*?\]\1\]

\ 1 захватывает первый ().

3 голосов
/ 21 июня 2009
\[(=*)\[.*?\]\1\]
...