Соответствует Lua's & # 8220; Длинная скобка & # 8221; синтаксис строки

StackOverflow https://stackoverflow.com/questions/1023722

  •  06-07-2019
  •  | 
  •  

Вопрос

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

  

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

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

Это было полезно?

Решение

\[(=*)\[.*?\]\1\]

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

Другие советы

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

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

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

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

\[(=*)\[.*?\]\1\]
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top