Парсер - писать самому или взять генератор
От: bybor  
Дата: 15.06.09 12:52
Оценка:
Надо написать парсер выражений. Язык программирования — C#. В выражении могут быть арифметические операции, предопределенные функции (MIN, MAX, ABS, ...), и в качестве переменных — названия полей таблиц базы данных. Парсер будет использоваться для "вычисляемых" полей в отчётах. Вычисление будет задаваться выражением, которое требуется разобрать (желательно на этапе ввода, чтобы не заниматься этим при отображении отчёта), подставить туда значения для текущего кортежа и вернуть результат.

Как я понимаю, задача сводится к обычному "калькулятору" с возможностью задания переменных.

Вопрос собственно по реализации. Можно всё это сделать самому или попробовать ANTLR (Coco/R ? ).
Опыта в этой области нет вообще. Если делать самому, то всё не очень страшно, но смущает дальнейшее расширение функциональности. Например, логические операции или ещё что-нить такое. В готовых примерах, на которые я натыкался — на том же CodeProject, почти весь код имеет некоторые ограничения — например поддержка унарных операторов или вложенные скобки в логических выражениях. Я не понимаю, являются ли эти задачи сложными для реализации, или они настолько тривиальны, что авторы не стали тратить на это время.

Может быть лучше будет построить грамматику и использовать ANTLR/CocoR для генерации кода парсера на C#? Насколько это будет трудоёмко для чайника? И насколько хорошо в эту грамматику лягут названия полей из базы данных?

Время на разработку как бы есть, но чем быстрее, тем лучше.

Спасибо.
парсер
Re: Парсер - писать самому или взять генератор
От: fortuna  
Дата: 15.06.09 13:09
Оценка:
Здравствуйте, bybor, Вы писали:

B>Надо написать парсер выражений. Язык программирования — C#. В выражении могут быть арифметические операции, предопределенные функции (MIN, MAX, ABS, ...), и в качестве переменных — названия полей таблиц базы данных. Парсер будет использоваться для "вычисляемых" полей в отчётах. Вычисление будет задаваться выражением, которое требуется разобрать (желательно на этапе ввода, чтобы не заниматься этим при отображении отчёта), подставить туда значения для текущего кортежа и вернуть результат.


B>Как я понимаю, задача сводится к обычному "калькулятору" с возможностью задания переменных.


B>Вопрос собственно по реализации. Можно всё это сделать самому или попробовать ANTLR (Coco/R ? ).

B>Опыта в этой области нет вообще. Если делать самому, то всё не очень страшно, но смущает дальнейшее расширение функциональности. Например, логические операции или ещё что-нить такое. В готовых примерах, на которые я натыкался — на том же CodeProject, почти весь код имеет некоторые ограничения — например поддержка унарных операторов или вложенные скобки в логических выражениях. Я не понимаю, являются ли эти задачи сложными для реализации, или они настолько тривиальны, что авторы не стали тратить на это время.

B>Может быть лучше будет построить грамматику и использовать ANTLR/CocoR для генерации кода парсера на C#? Насколько это будет трудоёмко для чайника? И насколько хорошо в эту грамматику лягут названия полей из базы данных?


B>Время на разработку как бы есть, но чем быстрее, тем лучше.


B>Спасибо.



Бери генератор аля Yacc Bison + Lex( Flex ) , ну или похожие инструменты,
потратишь время на то, чтобы разобраться и долетишь за 5 мин,
плюс дальше времени на изменения в синтаксисе или функционале будут занимать минимум времени.
Я в свое время только на lex, сделал парсер wiki синтаксиса.

Хотя руками это тоже не страшно, строишь дерево по выражению, ну с глубины начинаешь считать результат.
Если надо потом будет часто что-то добавлять то однозначно генератор.
Если редко то тоже генератор
Re: Парсер - писать самому или взять генератор
От: vmpire Россия  
Дата: 15.06.09 13:10
Оценка: 1 (1)
Здравствуйте, bybor, Вы писали:

B>Надо написать парсер выражений. Язык программирования — C#. В выражении могут быть арифметические операции, предопределенные функции (MIN, MAX, ABS, ...), и в качестве переменных — названия полей таблиц базы данных. Парсер будет использоваться для "вычисляемых" полей в отчётах. Вычисление будет задаваться выражением, которое требуется разобрать (желательно на этапе ввода, чтобы не заниматься этим при отображении отчёта), подставить туда значения для текущего кортежа и вернуть результат.


B>Как я понимаю, задача сводится к обычному "калькулятору" с возможностью задания переменных.


Самый быстрый и реально работающий способ (не без недостатков, конечно) это тупо писать выражения на C#, а потом компилировать их в runtime и выполнять. Удобно для этого завести базовый класс с виртуальным методом типа Calculate, а динамический класс от него наследовать. В нём тогда можно наопределять protected методов Min, Max и всё, что угодно.

Плюсы — выражение будет вычисляться быстро и очень легко расширять дополнительными функциями.
Минус — на C# пользователь может написать больше, чем того хотелость, то есть тут потенцияльная дырка в секьюрити. Дырка закрывается дополнительной валидацией скомпилированного.
Re[2]: Парсер - писать самому или взять генератор
От: bybor  
Дата: 15.06.09 13:37
Оценка:
Здравствуйте, fortuna, Вы писали:

F>Бери генератор аля Yacc Bison + Lex( Flex ) , ну или похожие инструменты,

F>потратишь время на то, чтобы разобраться и долетишь за 5 мин,
Т.к. у меня C#, то соответственно — ANTLR и Coco.

F>плюс дальше времени на изменения в синтаксисе или функционале будут занимать минимум времени.

F>Я в свое время только на lex, сделал парсер wiki синтаксиса.
Передача значений в моём случае — это будут переменные в грамматике?
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[2]: Парсер - писать самому или взять генератор
От: bybor  
Дата: 15.06.09 13:37
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Самый быстрый и реально работающий способ (не без недостатков, конечно) это тупо писать выражения на C#, а потом компилировать их в runtime и выполнять. Удобно для этого завести базовый класс с виртуальным методом типа Calculate, а динамический класс от него наследовать. В нём тогда можно наопределять protected методов Min, Max и всё, что угодно.

Мне всё равно придётся парсить каким-то образом введённый текст. Хотя бы для выделения имён переменных (полей таблицы). В случае ошибки ввода — будет сложнее сказать пользователю что не так. Отдавать ему сообщения компилятора как-то не катит. Одно дело генерить код на C# на основе ввода, а другое — рассматривать ввод как готовый код. ИМХО, конечно.

V>Плюсы — выражение будет вычисляться быстро и очень легко расширять дополнительными функциями.

V>Минус — на C# пользователь может написать больше, чем того хотелость, то есть тут потенцияльная дырка в секьюрити. Дырка закрывается дополнительной валидацией скомпилированного.
Ага, принцип понял. Спасибо.
... << RSDN@Home 1.2.0 alpha 4 rev. 1228>>
Re[2]: Парсер - писать самому или взять генератор
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 15.06.09 13:56
Оценка:
Здравствуйте, vmpire, Вы писали:

V>Самый быстрый и реально работающий способ (не без недостатков, конечно) это тупо писать выражения на C#, а потом компилировать их в runtime и выполнять.


При таком способе в силу отдельных ньюнсов при развитии кода может встать необходимость в парсере, который бы понимал весь C#.
Re[3]: Парсер - писать самому или взять генератор
От: vmpire Россия  
Дата: 15.06.09 14:06
Оценка:
Здравствуйте, Mystic, Вы писали:

V>>Самый быстрый и реально работающий способ (не без недостатков, конечно) это тупо писать выражения на C#, а потом компилировать их в runtime и выполнять.


M>При таком способе в силу отдельных ньюнсов при развитии кода может встать необходимость в парсере, который бы понимал весь C#.

Зачем?
Re[3]: Парсер - писать самому или взять генератор
От: fortuna  
Дата: 15.06.09 14:39
Оценка:
Здравствуйте, bybor, Вы писали:

B>Здравствуйте, fortuna, Вы писали:


F>>Бери генератор аля Yacc Bison + Lex( Flex ) , ну или похожие инструменты,

F>>потратишь время на то, чтобы разобраться и долетишь за 5 мин,
B>Т.к. у меня C#, то соответственно — ANTLR и Coco.

F>>плюс дальше времени на изменения в синтаксисе или функционале будут занимать минимум времени.

F>>Я в свое время только на lex, сделал парсер wiki синтаксиса.
B>Передача значений в моём случае — это будут переменные в грамматике?

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

MIN( (a+b), (b+10), f(c+d) )
получится как нечто такое
(MIN
(+ (a b ))
(+ (b 10 ))
(f
(+ ( c d ))
)
)
начинаем c глубины т.е c
+ ( c d ) далее f от результата, т.к. выражения MIN на одном уровне их вычисляем в любом порядке,
и вычисляем MIN для них.

я бы посоветовал для начала почитать немного теории.
Re[4]: Парсер - писать самому или взять генератор
От: fortuna  
Дата: 15.06.09 14:45
Оценка:
так лучше видно структуру.

MIN( (a+b), (b+10), f(c+d) ) 
получится как нечто такое 
(MIN 
     (+ (a b  )) 
     (+ (b 10 ))
     (f 
        (+ ( c d ))
     )
)
Re: Парсер - писать самому или взять генератор
От: Mr.Cat  
Дата: 15.06.09 16:43
Оценка:
Поковыряй встроенный в дотнет интерпретатор jscript (Microsoft.JScript) — может, пригодится.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.