Pull to refresh

Comments 25

Спасибо, прочитал на одно дыхании. Продолжайте в том же духе))
UFO just landed and posted this here
И с русским языком тоже.
Извините, но я старался, честно!
Спасибо за статью.

P.S. Code Conventions наверное не читали? Тестов не хватает в проекте, нормальных junit-тестов, хотя бы.
> посоветуйте пожалуйста хостинг, куда можно залить архив код
github.com, bitbucket.org
Спасибо за наводку, учту в следующий раз. Пока залил на народ.
Я, глядя на иллюстрацию, ждал от статьи большего.
> Хочу поделится с вами реализацией алгоритма «Метод рекурсивного спуска» на примере написания парсера формул с поддержкой переменных и функций на языке Java

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

Иными словами, некорректно говорить об алгоритме «Метод рекурсивного спуска».
Согласен с Вами, возможно я несколько не так выразился. Наверное было бы лучше написать:

«Хочу поделится с вами реализацией парсера математических формул с поддержкой переменных и функций на основе алгоритма „Метод рекурсивного спуска“?
Человек хотел сказать, что «Метод рекурсивного спуска» — это метод, не алгоритм. Т.е. это общая идея, например, как «метод деления пополам», «разделяй и властвуй» или динамическое программирование. Это не конкретные алгоритмы, это подходы к решению задачи.
Задача хорошая, на 1м курсе такое решали. Рекомендую вам поработать над дизайном кода.
Неделя парсинга формул на хабре!
И ни слова про грамматики. Советую, вместо того чтобы читать подобные статьи в интернете, взять нормальную книжку по теме.
Честно говоря не понял в чем тут заключается метод рекурсивного спуска, какой-то код, что-то в него вносим, что-то он выдает.

Кстати, как сказали выше, о термах, грамматике ни слова.
Но Вы ведь знаете о существующих готовых парсерах грамматики? Например, ANTLR, с которым весь описанный выше функционал (парсинг выражений вида "(1+2)*3+4*5+6*sin(0.7)") выражается несколько проще:

grammar extcalc;

/*------------------------------------------------------------------
* PARSER RULES
*------------------------------------------------------------------*/

expr : plusminus* EOF ;

plusminus
: multdiv ( ( '+' | '-' ) multdiv )* ;

multdiv : factor ( ( '*' | '/' ) factor )* ;

factor : NUMBER | func | '(' plusminus ')' ;

func : NAME '(' plusminus ')' ;

/*------------------------------------------------------------------
* LEXER RULES
*------------------------------------------------------------------*/

NUMBER : (DIGIT)+ ('.' (DIGIT)+)* ;
NAME : (ALPHA)+ ;

WHITESPACE : ( '\t' | ' ' | '\r' | '\n'| '\u000C' )+ { $channel = HIDDEN; } ;

fragment DIGIT : '0'..'9' ;

fragment ALPHA : 'a'..'z' ;
Я думаю, автор ставил целью описать, как именно работает анализатор, изнутри. Готовые парсеры тут ни к месту. Но у него это, на мой взгляд, получилось не слишком хорошо — отсутствуют любые признаки теории.
Вообще, в этой теме, код — совсем не главное, потому что он получается довольно простой. Важно знание основ.
Всё-таки, в реальных случаях лучше использовать нормальные решения по парзингу, а не рекурсивный спуск. Мне до сих пор стыдно за то, что в DN OSP используется мой старый вычислитель на базе рекурсивного спуска :(
например: есть выражение: 4--4
Парсер воспринимает это как: 4 — (-4), а что должно значить **?
Кстати заметьте, 4++4 он также не пропустит
Намного проще и естественней для обозначения степени использовать "^"
Для того что бы разобраться как это работает, предлагаю добавить поддержку степени самостоятельно.
а что это у вас за формула для привлечения внимания?
Просто обычная трёхэтажная формула) Выглядит вроде эффектно.
Извините если ввел вас в заблуждение и вы ожидали чего-то большего.
Sign up to leave a comment.

Articles