Улучшить BNF для математических выражений - PullRequest
2 голосов
/ 28 сентября 2010

Хорошее упражнение при изучении программирования - написать калькулятор. Для этого я создал DSL в BNF и хочу попросить вас о помощи, чтобы улучшить его. С этим миниязыком вы сможете add, multiply и assign значения и выражения для имен (например, создавать переменные и функции).

Сначала взглянем на БНФ:

<Program>     ::= <Line>(<NewLine><Line>)*
<Line>        ::= {"("}<Expression>{")"}|<Assignment>
<Assignment>  ::= <Identifier>"="<Expression>
<Identifier>  ::= <Name>{"("<Name>(","<Name>)*")"}
<Expression>  ::= <Summand>(("+"|"-")<Summand>)*
<Summand>     ::= <Factor>(("*"|"/")<Factor>)*
<Factor>      ::= <Number>|<Call>
<Call>        ::= <Name> {"("<Expression>(","<Expression>)*")"}
<Name>        ::= <Letter>(<Letter>|<Digit>)*
<Number>      ::= {"+"|"-"}(<Digit>|<DigitNoZero><Digit>+)
<Digit>       ::= "0"|<DigitNoZero>
<DigitNoZero> ::= "1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9"
<Letter>      ::= [a-zA-Z]
<NewLine>     ::= "\n"|"\r"|"\r\n"

Как вы можете видеть, этот BNF не обрабатывает пробелы рядом с NewLine. Перед началом синтаксического анализа я планирую удалить все пробелы (кроме, конечно, NewLine) из строки для анализа. В любом случае, это не обязательно для парсера.

Есть 4 вещи, которые могут привести к проблемам при использовании этого языка, как определено прямо сейчас, и я надеюсь, что вы можете помочь мне найти подходящие решения:

  1. Я пытался следовать нисходящему подходу при создании этой грамматики, но между <Expression>, <Summand>, <Factor> и <Call>.
  2. Грамматика обрабатывает переменные и функции точно так же. Большинство языков программирования имеют значение. Нужно ли здесь дифференцироваться?
  3. Может быть, есть некоторые вещи, которые я не знаю о программировании, BNF, что угодно, что убьет меня позже, пытаясь реализовать BNF. Но вы можете заметить это до того, как я начну.
  4. Могут быть простые и глупые ошибки, которые я не мог найти сам. Извините в этом случае. Я надеюсь, что больше нет ни одной из этих ошибок.

Используя руку и мозг, я мог бы успешно проанализировать следующие тестовые примеры:

"3"
"-3"
"3-3"
"a=3"
"a=3+b"
"a=3+b\nc=a+3"
"a(b,c)=b*c\ra(1+2,2*3)"

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

редактирование: Этот БНФ действительно не закончен. Он не обрабатывает случаи «2 + -3» (должен потерпеть неудачу, но не) и «2 + (- 3)» (не должен потерпеть неудачу, но делает) правильно.

1 Ответ

2 голосов
/ 28 сентября 2010

Грамматика обрабатывает переменные и функции одинаково. Большинство языков программирования имеют значение. Здесь необходимо различать?

Способность обрабатывать результат вызова функции точно так же, как локальная переменная или константное выражение как раз и является точкой определения (математических) функций в первую очередь , Я не могу представить себе использование грамматики, которая допускает функции, но не обрабатывает

1 + 1

точно так же, как

1 + a

или

1 + sin(x)
...