2009-06-21 5 views
0

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

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

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

ответ

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

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

+0

Это недействительное регулярное выражение JFlex, или, по крайней мере, это не значит, что ответ говорит в JFlex. '\ 1' не имеет особого значения в JFlex и просто сопоставляется с символом' 1'. – lsf37

3
\[(=*)\[.*?\]\1\] 
+0

30 секунд слишком поздно мой друг :) – SpliFF

+0

Отличается от ответа SpliFF одним персонажем; мой ответ также принимает длинные скобки с нулевыми знаками. – Pumpuli

+0

Теперь он исправил это. (25 секунд кстати: P) – Pumpuli

5

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

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

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

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

+0

Вы также можете использовать лексические состояния: сопоставить открывающий скобок как '\ [= * \ [', хранить его длину, перейти к новому состоянию, соответствовать содержимому и любому закрытию '\] = * \]' , Если заключительное совпадение имеет нужную длину, верните токен, если он имеет неправильную длину, добавьте его в контент. – lsf37

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

  • Нет связанных вопросов^_^