Грамматика регулярна, если она либо линейна, либо леволинейна. В этом учебнике утверждается, что из-за этого у него есть специальное свойство:
Регулярная грамматика обладает особым свойством: подставляя каждую нетерминальную (за исключением корневой) ее правую сторону, вы можете свести ее к единому произведению для корня с единственными терминалами и операторами с правой стороны... Сокращенное выражение терминалов и операторов можно записать в еще более компактной форме, называемой регулярным выражением
Поэтому я решил проверить эту идею и преобразовать нормальную грамматику EcmaScript для IdentifierName в регулятивные выражения:
IdentifierName ::
IdentifierStart
IdentifierName IdentifierPart
Предположим, что IdentifierStart
и IdentifierPart
ограничены следующим:
IdentifierStart :: IdentifierPart ::
A A
B C
C &
$
_
Но я не уверен, как действовать, поскольку грамматика для IdentifierName
имеет как рекурсию, так и чередование. Любая помощь?
Меня больше интересует подход, а не поиск результирующего выражения, которое, как показал @Bergi, - [ABC$_][AC&]*
.
В этом учебнике используются некоторые нестандартные (и удивительно неявные) определения.
Прежде всего, они используют операторы повторения в своей грамматике, поскольку они могут быть найдены в регулярных выражениях или EBNF. Затем они неявно определяют правильную грамматику как та, которая использует только те операторы повторения и не рекурсии. Учитывая это, тривиально превращать "регулярную грамматику" в регулярное выражение, просто вставляя все нетерминалы. Но по этому определению грамматика спецификации JS для идентификаторов не является регулярной, поскольку содержит рекурсию. Поэтому, прежде чем вы сможете встроить все, вам сначала нужно заменить рекурсию операторами повторения.
Однако это не стандартное определение того, что такое регулярная грамматика. Стандартное определение так же, как вы сказали: грамматика является регулярной, если она либо лево-линейная, либо линейно-линейная, то есть если только самый левый элемент производства является нетерминальным или если только самый правый. Операторы повторения не существуют в обычном определении формальной грамматики.
Теперь эти регулярные грамматики также могут быть преобразованы в регулярные выражения, но не путем простого применения метода, описанного в учебнике. Одним из способов было бы преобразование грамматики в конечный автомат, а затем применить алгоритм, описанный в этом ответе, например.
Однако на практике при выполнении преобразования вручную (вместо написания программы для этого) самым простым и наиболее распространенным способом выполнения преобразования является мысль о том, на каком языке грамматика описывает (в данном случае "язык всех слов, которые начните с символа IdentifierStart и затем укажите 0 или более символов IdentifierPart "), а затем придумайте регулярное выражение, выражающее этот язык (иначе" посмотрите на проблему очень сильно, пока не увидите решение "-algorithm).
[ABC$_][AC&]*