Опубликован: 23.07.2006 | Доступ: свободный | Студентов: 2215 / 889 | Оценка: 4.28 / 4.17 | Длительность: 21:37:00
Специальности: Системный архитектор
Лекция 5:

Лексический анализ

< Лекция 4 || Лекция 5: 123456 || Лекция 6 >

Использование регулярных выражений .NET

Для решения некоторых локальных задач лексического анализа удобно использовать механизм регулярных выражений, предоставляемый .NET (см. классы Regex, Match в пространстве имен System.Text.RegularExpressions ).

Класс Regex реализует максимальный по функциональности механизм регулярных выражений. Этот механизм представляет собой недетерминированный поиск регулярных выражений в строке, основанный на "жадном" алгоритме с возвратами (аналогичные механизмы используются в Perl и Python). При таком подходе входная строка в определенном порядке проверяется на наличие любого варианта заданного регулярного выражения и в качестве результата принимается первое же совпадение. У такого подхода есть некоторые недостатки. Во-первых, в связи с тем, что механизм подразумевает возвраты, теоретически мы можем побывать в одном и том же состоянии многократно; таким образом, в худшем случае алгоритм может отработать за экспоненциальное время. Во-вторых, так как алгоритм останавливается на первой же найденной подходящей подстроке, этот алгоритм потенциально может не найти более длинные совпадения с данным регулярным выражением.

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

Пример использования механизма регулярных выражений .NET

Пример использования механизма регулярных выражений .NET

void DumpHrefs(String inputString) 
{   
  Regex r;   
  Match m;   
  r = new Regex("href\\s*=\\s*(?:\"(?<1> [^\"]*)\"|(?<1>\\S+))",   
     RegexOptions.IgnoreCase|RegexOptions.Compiled);   
  for (m = r.Match(inputString); m.Success; m = m.NextMatch())   
  {     
     Console.WriteLine("Found href " + m.Groups[1] + " at "     
     + m.Groups[1].Index);   
  } 
}

Рассмотрим пример использования регулярных выражений .NET. В примере выше приведена функция, позволяющая найти в строке все выражения вида href="…". Для этого используются два объекта - Regex, задающий регулярное выражение для поиска, и Match, позволяющий обработать результаты применения регулярного выражения ко входной строке.

Регулярное выражение r описывает следующий шаблон для поиска: строка href, за которой следует произвольное количество пробелов, за которыми следует символ = , затем снова произвольное количество пробелов, за которым следует кавычка. Начиная с кавычки, все последующие символы до закрывающей кавычки записываются в специальную строку под номером один <1>. Эта строка впоследствии выводится на печать для всех найденных вхождений такого шаблона (см. печать m. Groups[1] ).

Более подробное описание синтаксиса и возможностей регулярных выражений можно найти в документации к Visual Studio.NET.

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

Литература к лекции

  • А. Ахо, Дж. Ульман "Теория синтаксического анализа, перевода и компиляции", Т.1 "Синтаксический анализ", М.: Мир, 1978
  • Р. Хантер "Проектирование и конструирование компиляторов", ФиС, 1984
< Лекция 4 || Лекция 5: 123456 || Лекция 6 >