Как насчёт маленького примерчика. Например небольшой калькулятор :)
И начнём пожалуй с конца, а именно конструктор класса нашего парсера
- Whitespace = Rep(Char(' ').Or(Char('\t').Or(Char('\n')).Or(Char('\r'))));
- WsChr = chr => Whitespace.And(Char(chr));
- Id = from w in Whitespace
- from c in Char(char.IsLetter)
- from cs in Rep(Char(char.IsLetterOrDigit))
- select cs.Aggregate(c.ToString(), (acc, ch) => acc + ch);
- Number = from w in Whitespace
- from cs in Rep(Char(char.IsDigit))
- select cs.Aggregate(cs.ToString(), (acc, ch) => acc + ch);
- Ident = (from n in Number
- select n)
- .Or(from i in Id
- select i);
- Sub = (from id in Ident
- from u in WsChr('+')
- from s in Sub
- select (Term)((AgreggateTerm)s).Add(id, u.ToString()))
- .Or(from id in Ident
- from u in WsChr('-')
- from s in Sub
- select (Term)((AgreggateTerm)s).Add(id, u.ToString()))
- .Or(from id in Ident
- select (Term)new AgreggateTerm(id));
- Mult = (from s in Sub
- from u in WsChr('*')
- from m in Mult
- select (Term)((AgreggateTerm)m).Add((AgreggateTerm)s, u.ToString()))
- .Or(from s in Sub
- from u in WsChr('/')
- from m in Mult
- select (Term)((AgreggateTerm)m).Add((AgreggateTerm)s, u.ToString()))
- .Or(from s in Sub
- select (Term)new AgreggateTerm((AgreggateTerm)s));
- All = from m in Mult select m;
По сути всё просто мы переопределяем всякие select, where, or и прочие вещи, чтобы с помощью LINQ пробежать по всем char'ом в строке. Только в отличии от стандартного способа в виде while - switch это подход выглядит очень красиво. Главное достоинство в расширяемости. По приведенной выше ссылке можно найти полный код, в котором всего лишь надо заменить конструктор парсера, например на тот что я привёл, в результате получим парсер нашего языка, вот так всё просто :)
Комментариев нет:
Отправить комментарий