rampelstinskin/ParserGenerator — Issue #10: Ограничения на AST
Author: VladD2
Created: 2012-02-04 02:05:07+00:00
State: open

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

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

Пример типичного квалифицированного имени типа:

```nemerle
A.B[X[Y]].Z
```
В соответствие с правилами языка недопустимы конструкции вроде:

```nemerle
A[X]
A.[X]
```
Такую грамматику весьма не просто описать, так как "." является оператором у которого и справа и с лева может быть произвольное выражение. В то же время отсутствие параметров типа в конце имени можно легко описать с помощью дополнительного ограничения в виде образца (pattern-matching):

```nemerle
<[ $_ . $(Identifier) ]> | Identifier
```
Этот образец описывает, что приемлемое AST должно быть оператором "." второй операнд которого является AST типа Identifier (т.е. сгенерированного правилом Identifier), или AST типа Identifier.

Ограничения должны задаваться при описании правил. Например, так:

```nemerle
QualifiedIdentifier = Expression where <[ $_ . $(Identifier) ]> | Identifier;
```
Эта запись означает, что QualifiedIdentifier - является частным случаем правила Expression удовлетворяющим ограничению заданному после where.

Вместо непосредственного задания ограничения в виде паттерна, можно задавать вместо него предикат (булеву функцию):
```nemerle
QualifiedIdentifier = Expression where IsQualifiedIdentifier;
...
class Parser
{
static IsQualifiedIdentifier(e : Expression) : bool
{
...
}
```