Формальное описание МиП

МиП (сокращение от Мини Паскаль) - это узкое подмножество языка Паскаль. Любая программа на МиП является, в то же время правильно построенной программой на Паскале. Обратное далеко не всегда верно. Главное достоинство МиП - его компактность, позволяющая легко формально определить этот язык в БНФ. Этому и посвящена данная статья.
Полное синтаксическое описание МиП, несколько примеров-задач и обсуждения можно найти здесь.
Вопросы, собственные мысли и комментарии по структуре описания и возможностям МиП можно размещать здесь же, ниже.

Вот несколько новых задач по МиП

(ответы строго обосновывать!):
МиП. Задача1. Верна ли в МиП следующая запись:

  1. program p1;
  2. begin writeln(2+3) end.

МиП. Задача2. Верна ли в МиП следующая запись:

  1. program p2
  2.     ;var a: ShortInt;
  3. begin read(a);;write('') end.

МиП. Задача3. Верна ли в МиП следующая запись:
  1. program p3;
  2. begin writeln(1 div 0); writeln('writeln(1 div 0);'); end.

МиП. Задача4. Используя БНФ-описания МиП, приведите несколько примеров терминального уровня детализации МиП понятия <объявление_константы>.

МиП задача 1. Является

МиП задача 1.

Является верной записью на языке МиП.

  1. program p1
  2. begin writeln(2+3) end.;

Соответствует:
  1. <МиП-программа> ::= <заголовок_программы>; <блок> <точка>
  2. <точка> ::= .
  3. <заголовок_программы> ::= program <имя_программы>
  4. <имя_программы> ::= <идентификатор>
  5. <идентификатор> ::= <буква> | <идентификатор> <буква> | <идентификатор> <цифра>
  6. <буква> ::= а | b | ... | y | z | A | B | ... | Y | Z | _
  7. <цифра> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9

Т.е. соблюдены все правила построения заголовка программы...

А также выполнены условия построения блока программы:

  1. <составной_оператор> ::= begin <оп_последовательность> end
  2. <оп_последовательность> ::= <оператор> | <оп_последовательность>;<оператор>
  3. <оператор> ::= <оп_ввода> | <оп_вывода> | <оп_присваивания> | <пустой_оп>
  4.  <оп_ввода> ::= readln | readln(<список_ввода>)
  5. <список_ввода> ::= <список_переменных>
  6.  
  7.  <оп_вывода> ::= writeln(<список_вывода>)
  8. <список_вывода> ::= <список_выражений>
  9.  <список_выражений> ::= <выр> | <список_выражений>,<выр>
  10. <выр> ::= <арифм_выр> | <текст_выр>
  11. <арифм_выр> ::= <целая_константа> | <переменная> | <арифм_выр> <знак_ар_оп> <арифм_выр>
  12. <знак_ар_оп> ::= + | - | * | div | mod
  13. <текст_выр> ::= <текст_константа>

Насколько я понимаю в данной задаче в операторе вывода прописана последовательность ascii символов, что соответствует:

  1. <текст_константа> ::= '<ascii-последовательность>'
  2. <ascii-последовательность> ::= <пусто> | <ascii-символ> |
  3.                      <ascii-последовательность> <ascii-символ>

О МиП задаче1 Кирилла

Во-первых, приведённая Кириллом версия программы точно МиП программой не является.
Во-вторых, "вываленое" полное описание синтаксиса МиП само по себе ничего не доказывает.
В-третьих, как действительно строить доказательство показано в уже размещённых на сайте комментах прошлого года на эту тему.
В-четвёртых, <текст_константа> здесь совсем непричём.

задача 1 МиП

  1. program p1;
  2. begin writeln(2+3) end.

является правильно построенной МиП программой. Т.к. в МиП. пробелы и переходы на новую строку не учитываются перепишем данный код в эквивалентной форме

  1. program p1; begin writeln(2+3) end.

В этом виде можно рассматривать данный код как СЛОВО, состоящее из лексем. Выясним принадлежат ли эти лексемы МиП.
Выведем данный код из исходного нетерминального символа <МиП-программа>
  1. <МиП-программа> => <заголовок_программы> ; <блок> <точка> =>
  2. program <имя программы> ; <блок> <точка>=>
  3. program <идентификатор> ; <блок> <точка>=>
  4. program <буква><цифра> ; <блок> <точка>=>
  5. program p1 ; <блок> <точка>=>
  6. program p1 ; <декларативная_часть> <составной_оператор> <точка>=>
  7. program p1 ; <пусто> <составной_оператор> <точка>=>
  8. program p1 ; <составной_оператор> <точка>=>
  9. program p1 ; begin <оп_последовательность> end <точка>=>
  10. program p1 ; begin <оператор> end <точка>=>
  11. program p1 ; begin <оп_вывода> end <точка>=>
  12. program p1 ; begin writeln (<список_вывода>) end <точка>=>
  13. program p1 ; begin writeln (<список_выражений>) end <точка>=>
  14. program p1 ; begin writeln (<выражение>) end <точка>=>
  15. program p1 ; begin writeln (<арифм_выр>) end <точка>=>
  16. program p1 ; begin writeln (<арифм_выр> <знак_арифм_операции> <арифм_выр>) end <точка>=>
  17. program p1 ; begin writeln (<целая_константа> <знак_арифм_операции> <целая_константа>) end <точка>=>
  18. program p1 ; begin writeln (2+3) end <точка>=>
  19. program p1 ; begin writeln (2+3) end .

Ай опередил.

Ай Кирил, обогнал, только хотел написать, уже на листочке все составил. Только у меня вопрос. После writeln разве не нужен знак (;)?

вроде нет

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

насчет опередил: там еще 3 задачи:)) дерзаем:)

задача 2

Буду объяснять свое решение как могу, т.к. с программированием у меня пока туговато.
Вот исходная запись задачи.

  1.  program p2
  2.     ;var a: ShortInt;
  3. begin read(a);;write('') end.

Мне, кажется, что это неверная запись. Программа, по-моему, должна принять такой вид:
  1.  program p2;
  2.     var a: ShortInt;
  3. begin read(a); write(''); end.
.
Теперь это является правильно построенной МиП программой. Т.к. в МиП. пробелы и переходы на новую строку не учитываются перепишем данный код в эквивалентной форме. И сразу приступим к док-ву.
  1.   program p2; var a: ShortInt; begin read(a); write(''); end.
  2. <МиП-программа> ::= <заголовок_программы>; <блок> <точка> =>
  3. program <имя_программы>; <блок> <точка> =>
  4. program <идентификатор>; <блок> <точка> =>
  5. program <буква>; <блок> <точка> =>      
  6. program p2; <блок> <точка> =>                  //"p2 не  <буква> ! "  
  7. program p2; <декларативная_часть> <составной_оператор> <точка> =>
  8. program p2; <список_секций> ; <составной_оператор> <точка> =>
  9. program p2; <секция> ; <составной_оператор> <точка> =>
  10. program p2; <секция_переменных> ; <составной_оператор> <точка> =>
  11. program p2; var <список_описаний_переменных> ; <составной_оператор> <точка> =>
  12. program p2; var <описание_переменных> ; <составной_оператор> <точка> =>
  13. program p2; var <список_переменных> : <тип> ; <составной_оператор> <точка> =>
  14. program p2; var <переменная>, : <тип> ; <составной_оператор> <точка> =>
  15. program p2; var <идентификатор> : <тип> ; <составной_оператор> <точка> =>
  16. program p2; var <буква> : <тип> ; <составной_оператор> <точка> =>
  17. program p2; var a : <тип> ; <составной_оператор> <точка> =>
  18. program p2; var a: ShortInt; <составной_оператор> <точка> =>
  19. program p2; var a: ShortInt; begin <оп_последовательность> end <точка> =>
  20. program p2; var a: ShortInt; begin <оп_последовательность>;<оператор> end <точка> =>
  21. program p2; var a: ShortInt; begin <оп_ввода>; <оператор> end <точка> =>
  22. program p2; var a: ShortInt; begin read <список_ввода>; <оп_вывода> end <точка>=>           //'потерял круглые скобки!'
  23. program p2; var a: ShortInt; begin read <переменная>; write <список_вывода>; end <точка>=> //'ещё одни! Зато лишняя ";"'
  24. program p2; var a: ShortInt; begin read <идентификатор>; write <пустой_символ>; end <точка>=> //'<пустой_символ>; ??? '
  25. program p2; var a: ShortInt; begin read <буква>; write(' '); end <точка>=>
  26. шнprogram p2; var a: ShortInt; begin read(a); write(' '); end <точка>=>
  27. program p2; var a: ShortInt; begin read(a); write(' '); end.

Ну вот моя версия решения, прошу не судить строго.

Кирилл и Дима поработали...

... но оба допустили ошибки.
Похоже, Дима переписывал описание МиП у Кирилла (повтор одной из ошибок).
Насторожил вопрос Димы и о точке с запятой.
Любой символ может присутствовать в тексте программы на ЯП тогда и только тогда, когда он может быть выведен согласно описанию этого языка.
В версию Димы я внёс замечания.

Не согласен Дим:(

Я считаю что

  1.  program p2
  2.     ;var a: ShortInt;
  3. begin read(a);;write('') end.

является верной МиП программой, т.к. в МиП не имеют значени переходы на новую строку и пробелы.
Представим данный кодв в виде строки, состоящей из лексем
  1. program p2; var a: ShortInt; begin read(a);; write(''); end.

Попробуем привести к данной строке терминальных символов первичное определение МиП программы.
  1. <МиП-программа> ::= <заголовок_программы>; <блок> <точка> =>
  2. program <имя_программы>; <блок> <точка> =>
  3. program <идентификатор>; <блок> <точка> =>
  4. program <буква><цифра>; <блок> <точка> =>
  5. program p2; <блок> <точка> =>
  6. program p2; <декларативная_часть> <составной_оператор> <точка> =>
  7. program p2; <список_секций> ; <составной_оператор> <точка> =>
  8. program p2; <секция> ; <составной_оператор> <точка> =>
  9. program p2; <секция_переменных> ; <составной_оператор> <точка> =>
  10. program p2; var <список_описаний_переменных> ; <составной_оператор> <точка> =>
  11. program p2; var <описание_переменных> ; <составной_оператор> <точка> =>
  12. program p2; var <список_переменных> : <тип> ; <составной_оператор> <точка> =>
  13. program p2; var <переменная> : <тип> ; <составной_оператор> <точка> =>
  14. program p2; var <идентификатор> : <тип> ; <составной_оператор> <точка> =>
  15. program p2; var <буква> : <тип> ; <составной_оператор> <точка> =>
  16. program p2; var a : <тип> ; <составной_оператор> <точка> =>
  17. program p2; var a: ShortInt; <составной_оператор> <точка> =>
  18. program p2; var a: ShortInt; begin <оп_последовательность> end <точка> =>
  19. program p2; var a: ShortInt; begin <оп_последовательность>;<оператор> end <точка> =>
  20. program p2; var a: ShortInt; begin <оп_последовательность><оператор>;<оператор> end <точка> =>
  21. program p2; var a: ShortInt; begin <оператор>;<оператор>;<оператор> end <точка> =>
  22. program p2; var a: ShortInt; begin <оп_ввода>;<пустой_оп>; <оп_вывода> end <точка> =>
  23. program p2; var a: ShortInt; begin read (<список_ввода>);; write (<список_вывода>) end <точка>=>
  24. program p2; var a: ShortInt; begin read (<переменная>);; write (<cписок выражений>); end <точка>=>
  25. program p2; var a: ShortInt; begin read (<идентификатор>);; write (<выр>); end <точка>=>
  26. program p2; var a: ShortInt; begin read (<буква>);; write (<текст_выр>); end <точка>=>
  27. program p2; var a: ShortInt; begin read (a);; write (<текст_константа>); end <точка>=>
  28. program p2; var a: ShortInt; begin read (a);; write ('<ascii-последовательность>'); end <точка>=>
  29. program p2; var a: ShortInt; begin read (a);; write ('<пусто>'); end <точка>=>
  30. program p2; var a: ShortInt; begin read (a);; write (''); end <точка>=>
  31. program p2; var a: ShortInt; begin read (a);; write (''); end .=>

Могу и ошибаться но по моему вот так.

P.S. данные рассуждение проходили с учетом того что writeln и write считаются равнозначными.

Да, Кирил

Да точно, я пересмотрел вторую задачу, запустил ее на BP, все работает. ; - пустой оператор, а он допустим.

Вернитесь Дима к условию Задачи 2

Вопрос был в том, правильна ли приведённая в условии Задачи 2 версия МиП-программы. Вместо доказательного ответа Вы пустились в рассмотрение другой программы. Вернитесь к исходному условию и будьте внимательны!
И ещё, разве в описании МиП есть терминальный символ write или read?

Наконец, я ведь никогда не спрашивал, работает или нет та иди иная программа в той или иной среде. Мы обсуждаем МиП. И работающая Паскаль программа может не быть МиП-программой.

Формально нас интересуют только две вещи:
1)конкретное БНФ- описание языка;
2)соответствие или несоответствие некоторого заданного слова этому описанию.
Всё остальное: работает, не работает, пишут так, не пишут, имеет это смысл, не имеет - от лукавого!

нету:)

вообще то напрямую нету такого символа. То есть write является уже расширением МиП, а задача2 не является верной МиП программой?
Свои выкладки я проводил с учетом того что это одно и то же:)

Посмотрите, Кирилл

Посмотрите, Кирилл конец предыдущего моего поста...

Важно!

Хочу вернуть читателей к посту "Да, Кирилл". Заканчивается он фразой " ... ; - пустой оператор, а он допустим.".
Я спрашиваю: Как из описания МиП следует, что он допустим? Из представленного вывода он никак не следует.

задача 2

  1. program p2
  2.     ;var a: ShortInt;
  3. begin read(a);;write('') end.

Не является верной МиП программой. Докажем это попыткой привести к данному слову первичное определение МиП программы.
  1. <МиП-программа> ::= <заголовок_программы>; <блок> <точка> =>
  2. program <имя_программы>; <блок> <точка> =>
  3. program <идентификатор>; <блок> <точка> =>
  4. program <буква><цифра>; <блок> <точка> =>
  5. program p2; <блок> <точка> =>
  6. program p2; <декларативная_часть> <составной_оператор> <точка> =>
  7. program p2; <список_секций> ; <составной_оператор> <точка> =>
  8. program p2; <секция> ; <составной_оператор> <точка> =>
  9. program p2; <секция_переменных> ; <составной_оператор> <точка> =>
  10. program p2; var <список_описаний_переменных> ; <составной_оператор> <точка> =>
  11. program p2; var <описание_переменных> ; <составной_оператор> <точка> =>
  12. program p2; var <список_переменных> : <тип> ; <составной_оператор> <точка> =>
  13. program p2; var <переменная> : <тип> ; <составной_оператор> <точка> =>
  14. program p2; var <идентификатор> : <тип> ; <составной_оператор> <точка> =>
  15. program p2; var <буква> : <тип> ; <составной_оператор> <точка> =>
  16. program p2; var a : <тип> ; <составной_оператор> <точка> =>
  17. program p2; var a: ShortInt; <составной_оператор> <точка> =>
  18. program p2; var a: ShortInt; begin <оп_последовательность> end <точка> =>
  19. program p2; var a: ShortInt; begin <оп_последовательность>;<оператор> end <точка> =>
  20. program p2; var a: ShortInt; begin <оп_последовательность><оператор>;<оператор> end <точка> =>
  21. program p2; var a: ShortInt; begin <оператор>;<оператор>;<оператор> end <точка> =>
  22. program p2; var a: ShortInt; begin <оп_ввода>;<пустой_оп>; <оп_вывода> end <точка> =>

следующая по логике строка переходов к исходному коду
program p2; var a: ShortInt; begin read (<список_ввода>);; write (<список_вывода>) end <точка>=>
уже не принадлежит описанию МиП программы, т.к. она не включает в себя оператор write, следовательно исходный код не является верной МиП программой, однако может являться верной Паскаль программой...

так?

пустой оператор

насчерт пустого оператора.

  1. <составной_оператор> ::= begin <оп_последовательность> end
  2. <оп_последовательность> ::= <оператор> | <оп_последовательность>;<оператор>
  3. <оператор> ::= <оп_ввода> | <оп_вывода> | <оп_присваивания> | <пустой_оп>
  4. <пустой_оп> ::= <пусто>
  5. <пусто>::=

на это я опирался. то есть оператор может быть пустым
  1. program p2; var a: ShortInt; <составной_оператор> <точка> =>
  2. program p2; var a: ShortInt; begin <оп_последовательность> end <точка> =>
  3. program p2; var a: ShortInt; begin <оп_последовательность>;<оператор> end <точка> =>
  4. program p2; var a: ShortInt; begin <оп_последовательность><оператор>;<оператор> end <точка> =>
  5. program p2; var a: ShortInt; begin <оператор>;<оператор>;<оператор> end <точка> =>
  6. program p2; var a: ShortInt; begin <оп_ввода>;<пустой_оп>; <оп_вывода> end <точка> =>
  7. program p2; var a: ShortInt; begin <оп_ввода>;<пусто>; <оп_вывода> end <точка> =>
  8. program p2; var a: ShortInt; begin read (<список_ввода>);; write (<список_вывода>) end <точка>=>

так я показал его в своем выводе уважаемые читатели:)

Вроде так. Я правильно понял вопрос?

Решение Задачи 2.

  1. program p2; var a: ShortInt; begin read(a);; write('') end.
  2.  
  3. <МиП-программа> ::= <заголовок_программы> ; <блок> <точка> =>
  4. program <имя_программы> ; <блок> <точка> =>
  5. program <идентификатор> ; <блок> <точка> =>
  6. program <буква><цифра> ; <блок> <точка> =>
  7. program p2; <блок> <точка> =>
  8. program p2; <декларативная_часть> <составной_оператор> <точка> =>
  9. program p2; <список_секций> ; <составной_оператор> <точка> =>
  10. program p2; <секция> ; <составной_оператор> <точка> =>
  11. program p2; <секция_переменных> ; <составной_оператор> <точка> =>
  12. program p2; var <список_описаний_переменных> ; <составной_оператор> <точка> =>
  13. program p2; var <описание_переменных> ; <составной_оператор> <точка> =>
  14. program p2; var <список_переменных> : <тип> ; <составной_оператор> <точка> =>
  15. program p2; var <переменная> : <тип> ; <составной_оператор> <точка> =>
  16. program p2; var <идентификатор> : <тип> ; <составной_оператор> <точка> =>
  17. program p2; var <буква> : <тип> ; <составной_оператор> <точка> =>
  18. program p2; var a : <тип> ; <составной_оператор> <точка> =>
  19. program p2; var a: ShortInt; <составной_оператор> <точка> =>
  20. program p2; var a: ShortInt; begin <оп_последовательность> end <точка> =>
  21. program p2; var a: ShortInt; begin <оп_последовательность>;<оператор> end <точка> =>
  22. program p2; var a: ShortInt; begin <оп_последовательность>;<оператор>;<оператор> end <точка> =>
  23. program p2; var a: ShortInt; begin <оператор>;<оператор>;<оператор> end <точка> =>
  24. program p2; var a: ShortInt; begin ОШИБКА ;<пустой_оп>; ОШИБКА end <точка>
  25. program p2; var a: ShortInt; begin ОШИБКА ;<пусто>; ОШИБКА end <точка>
  26. program p2; var a: ShortInt; begin ОШИБКА ;; ОШИБКА end <точка>
  27. program p2; var a: ShortInt; begin ОШИБКА ;; ОШИБКА end.

И еще вот. <оп_последовательность> ::= <оператор> | <оп_последовательность>;<оператор>
мне кажется должно быть
<оп_последовательность> ::= <оператор> | <оператор>;<оп_последовательность>
не удобнее ли было бы сделать так...

Кирилл!

Всё было прекрасно до 23 строки (появились даже ранее утраченные круглые скобки!). Вот тут бы Вам педантично остановиться и фиксировать ошибку - НЕСУЩЕСТВУЮЩИЕ ТЕРМИНАЛЫ read, write! Но Вы клюнули на удочку и включив своё "знание" произвольно решили что речь идёт о readln, writeln. Далее, так же произвольно Вы включили в конце символ ";" . Зачем? Без него всё было чудесно (кроме указанной выше ошибки). В исходном тексте -то его нет?

невнимательность и торопливость

Они меня погубят:) Я заметил сразу что в МиП описывается только Write/read и нету других операторов вывода/ввода, однако решил что они считаются равнозначными.
Да и действительно лучше учиться с 0, чем знать что то до этого урывками. Точка с запятой были поставлены по привычке:)
P.S. Сейчас заметил ошибку. Нету перехода от <пустой_оп> к <пусто>.

Всё теперь верно Кирилл!

Молодец, что довёл!
Дима, можно и так. Всё равно, слева или справа удлинять строку.

20-я строка.

В 20-й строке (задача 2) после <оп_последовательность> пропущен знак ";"

  1. program p2; var a: ShortInt; begin <оп_последовательность>;<оператор> end <точка> =>
  2. program p2; var a: ShortInt; begin <оп_последовательность><оператор>;<оператор> end <точка> =>

Задача 3

  1. program p3;
  2. begin writeln(1 div 0); writeln('writeln(1 div 0);'); end.

Является верной МиП программой. Представим данный код в виде строки:
  1. program p3; begin writeln(1 div 0); writeln('writeln(1 div 0);'); end.

Произведем переход от понятия МиП программы к получившемуся слову.
  1. <МиП-программа> ::= <заголовок_программы>; <блок> <точка> =>
  2. program <имя_программы>; <блок> <точка> =>
  3. program <идентификатор>; <блок> <точка> =>
  4. program <буква><цифра>; <блок> <точка> =>
  5. program p3; <блок> <точка> =>
  6. program p3; <декларативная_часть> <составной_оператор> <точка> =>
  7. program p3; <пусто> <составной_оператор> <точка> =>
  8. program p3 ; begin <оп_последовательность> end <точка>=>
  9. program p3 ; begin <оп_последовательность> ; <оператор> end <точка>=>
  10. program p3 ; begin <оп_последовательность> ; <оператор> ; <оператор> end <точка>=>
  11. program p3 ; begin <оператор> ; <оператор> ; <оператор> end <точка>=>
  12. program p3 ; begin <оп_вывода> ; <оп_вывода> ; <пустой_оператор> end <точка>=>
  13. program p3 ; begin writeln (<список_вывода>) ; writeln (<список_вывода>) ; <пустой_оператор> end <точка>=>
  14. program p3 ; begin writeln (<список_выражений>) ; writeln (<список_выражений>) ; <пустой_оператор> end <точка>=>
  15. program p3 ; begin writeln (<выр>) ; writeln (<выр>) ; <пустой_оператор> end <точка>=>
  16. program p3 ; begin writeln (<арифм_выр>) ; writeln (<текст_выр>) ; <пустой_оператор> end <точка>=>
  17. program p3 ; begin writeln (<арифм_выр> <знак_ар_оп> <арифм_выр>) ; writeln (<текст_константа>) ; <пустой_оператор> end <точка>=>
  18. program p3 ; begin writeln (<целая_константа> <знак_ар_оп> <целая_константа>) ; writeln ('<ascii-последовательность>') ; <пустой_оператор> end <точка>=>
  19. program p3 ; begin writeln (<целое_без_знака> <знак_ар_оп> <целое_без_знака>) ; writeln ('writeln(1 div 0);') ; <пустой_оператор> end <точка>=>
  20. program p3 ; begin writeln (<цифра> <знак_ар_оп> <цифра>) ; writeln ('writeln(1 div 0);') ; <пустой_оператор> end <точка>=>
  21. program p3 ; begin writeln (1 div 0) ; writeln ('writeln(1 div 0);') ; <пустой_оператор> end <точка>=>
  22. program p3 ; begin writeln (1 div 0) ; writeln ('writeln(1 div 0);') ; <пустой_оператор> end .=>
  23. program p3 ; begin writeln (1 div 0) ; writeln ('writeln(1 div 0);') ;  end .

Соответственно данный код является МиП программой
Вот таким вижу решение 3 задачи. Мог что то упустить от моей невнимательности, как показали предыдущие решения со мной это часто.

Дима, по 20-й строке задачи 2

Если Вы о коде Дмитрия (т.е. о своём собственном коде), не вижу там места для ";" ...

Кирилл, по задаче 3

Здесь уж и придраться не к чему ;-))

Задача 3

  1. program p3; begin writeln(1 div 0); writeln('writeln(1 div 0);'); end.
  2.  
  3. <МиП-программа>::=<заголовок_программы> ; <блок> <точка> =>
  4. program <имя программы> ; <блок> <точка> =>
  5. program <идентификатор> ; <блок> <точка> =>
  6. program <идентификатор><цифра> ; <блок> <точка> =>
  7. program <буква><цифра> ; <блок> <точка> =>
  8. program p3; <блок> <точка> =>
  9. program p3; <декларативная_часть> <составной_оператор> <точка> =>
  10. program p3; <пусто> <составной_оператор> <точка> =>
  11. program p3; <составной_оператор> <точка> =>
  12. program p3; begin <оп_последовательность> end<точка> =>
  13. program p3; begin <оп_последовательность>; <оператор> end<точка> =>
  14. program p3; begin <оп_последовательность>; <оператор>; <оператор> end<точка> =>
  15. program p3; begin <оператор>; <оператор>; <оператор> end<точка >=>
  16. program p3; begin <оп_вывода>;<оп_вывода>;<пустой_оп> end<точка> =>
  17. program p3; begin writeln(<список_вывода>); writeln(<список_вывода>);<пусто> end<точка> =>
  18. program p3; begin writeln(<список_выражений>); writeln(<список_выражений>); end<точка> =>
  19. program p3; begin writeln(<выр>); writeln(<выр>); end<точка> =>
  20. program p3; begin writeln(<арифм_выр>); writeln(<текст_выр>); end<точка> =>
  21. program p3; begin writeln(<арифм_выр> <знак_ар_оп> <арифм_выр>); writeln(<текст_константа>); end<точка> =>
  22. program p3; begin writeln(<целая_константа> <знак_арифм_операции> <целая_константа>); writeln('<ascii-последовательность>'); end<точка> =>
  23. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>'); end<точка> =>
  24. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>;'); end<точка> =>
  25. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>);'); end<точка> =>
  26. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>0);'); end<точка> =>
  27. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ> 0);'); end<точка> =>
  28. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>v 0);'); end<точка> =>
  29. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>iv 0);'); end<точка> =>
  30. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>div 0);'); end<точка> =>
  31. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ> div 0);'); end<точка> =>
  32. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>1 div 0);'); end<точка> =>
  33. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>(1 div 0);'); end<точка> =>
  34. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>n(1 div 0);'); end<точка> =>
  35. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>ln(1 div 0);'); end<точка> =>
  36. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>eln(1 div 0);'); end<точка> =>
  37. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>teln(1 div 0);'); end<точка> =>
  38. program p3; begin writeln(1 div 0); writeln('<ascii-последовательность><ascii-символ>iteln(1 div 0);'); end<точка> =>
  39. program p3; begin writeln(1 div 0); writeln('<ascii-символ>riteln(1 div 0);') ; end<точка> =>
  40. program p3; begin writeln(1 div 0); writeln('writeln(1 div 0);'); end<точка> =>
  41. program p3; begin writeln(1 div 0); writeln('writeln(1 div 0);'); end.

Вот мы и получили что данный код это есть МиП программа.Вот это Моя версия Задачи 3.

Возможно ошибка

Кирил, мне кажется в твоей версии третей задачи есть небольшие недочеты...
1. При описании <идентификатор> пропущено одно действие:
program <идентификатор>; <блок> <точка> =>
program <буква><цифра>; <блок> <точка> =>
из описания
<идентификатор> ::= <буква> | <идентификатор> <буква> | <идентификатор> <цифра>
2. Лишний пробел во всех writeln_(
program p3 ; begin writeln_(
из описания:
<оп_вывода> ::= writeln(<список_вывода>)
так как writeln() и writeln_() это разные выражения на МИП
3. Лексема <пустой_оператор>, нахывается иначе на МИП:
из описания:
<оператор> ::= <оп_ввода> | <оп_вывода> | <оп_присваивания> | <пустой_оп>
Они вроде незначительные, но без них программа работать не будет.

По задаче №3

А можно ли говорить о правельности программы в МиП, если в условиях изначально есть ошибка... ведь операция div отвечает за деление, А как мы знаем деление на ноль невозможно!!!
по условию:

  1. begin writeln(1 div 0);

Если я не прав прошу, исправить меня.

я тоже так думал

Я тоже так думал, но в описании ведь ничего про ноль не сказано, можно делить или нельзя. Тем более это МиП а не Паскаль.

Роман, ЛОВУШКА!!!

Роман, ЛОВУШКА!!!

Отлично, Дима!

Решение задачи 3 закрыто, поздравляю!

Только вот что опять за лепет " будет программа работать, не будет, можно делить на ноль, нельзя... ". Нет никакой программы, нет никаких действий (работать, делить и т.п). Есть только ТЕКСТ, построенный по определённым законам. И будьте любезны эти законы выполнять!

Кстати, теперь надеюсь, понятно, откуда берётся и почему не считается ошибкой вообще говоря не нужная запятая перед end.

Насколько я понял пробелы и

Насколько я понял пробелы и строки не имеют значения, зато так красивее выглядит:)
Насчет оператора. Писал что думал, а не просто переписывал дословно,а думал я пустой оператор:) Возможно это и ошибка, но вроде БНФ довольно произвольный язык и называть можно символы нетерминальные как угодно, суть остается та же. Другой вопрос что в МиП описан именно как <пустой_оп> и применять <пустой_оператор> нельзя. Это уже вопрос к Валерию Шахамболетовичу.
Ну и наконец это не программа а анализ кода)

И да:) в моем имени 2 бувы Л

Кириллу...

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

  1. writeln                  (1            
  2. div 0)

А теперь Кирилл и Дима,

А теперь Кирилл и Дима, СПАТЬ!!!

Ес, сэр:)

Ждем завтра еще задачек:)

Задача 2

В мип 2 рядом ";;" недолжны стоять, даказывать не буду.

Можно узнать что значит "не

Можно узнать что значит "не должны"... то что они не могут стоять рядом? могут, между ними находится пустой оператор

Задача 4

  1. <объявление_константы> ::= <имя_константы> = <константа> =>
  2. <идентификатор> = <константа> =>
  3. <буква> = <константа> =>
  4. a = <константа> =>
  5. a = <целая_константа> =>
  6. a = <цел_без_знака> =>
  7. a = <цифра> =>
  8. a = 5

и
  1. <объявление_константы> ::= <имя_константы> = <константа> =>
  2. <идентификатор> = <константа> =>
  3. <буква> | <идентификатор> <буква> = <константа> =>
  4. abc = <константа> =>
  5. abc = <текст_константа> =>
  6. abc = '<ascii-последовательность>' =>
  7. abc = <ascii-символ> =>
  8. abc = n

Кажется, имелось ввиду это.

<объявление_константы> ::=

  1. <объявление_константы> ::= <имя_константы> = <константа> =>
  2. <идентификатор> = <константа> =>
  3. <буква> = <константа> =>
  4. a = <константа> =>
  5. a = <целая_константа> =>
  6. a = <цел_без_знака> =>
  7. a = <цифра> =>
  8. a = 5

и
  1. <объявление_константы> ::= <имя_константы> = <константа> =>
  2. <идентификатор> = <константа> =>
  3. <буква> | <идентификатор> <буква> = <константа> =>
  4. abc = <константа> =>
  5. abc = <текст_константа> =>
  6. abc = '<ascii-последовательность>' =>
  7. abc = <ascii-символ> =>
  8. abc = n

Кажется, так.

Не в этом суть...

Меринов Виталий. Не в этом суть, знак ";" насколько я понял может стоять рядом с таким же знаком в МиП. Просто между двумя такими знаками будет пустой оператор и все. Фишка в том что там, как сказал Валерий Шахамболетович, стоят не существующие терминалы write, read. Вот именно поэтому такая запись не верна. Да и бросать столь опрометчивые выводы без док-ва, думаю, тут не приемлемо, если делаете заявление имейте доказательную базу. Не важно правильной она будет или нет, факт в том что вы не просто бросили слова на ветер, а проработали вашу версию. А даже если вы ошиблись то отрицательный результат, тоже результат ;)

Цуканову Антону.

ОК. Но во втором примере ошибочка (кстати, зачем дубль решений?)

Меринову Виталию

Обиды неуместны, ошибки надо исправлять и бездоказательность - не наш метод!
Ребята правы.
Кирилл привёл контрпример, Дима все правильно объяснил про ";" (и не только). Ну ничего не поделать c тем,
что и в МиП, и в ТП допустимы последовательности рядом стоящих знаков ";". Язык диктует правила, а не мы!

Какая-то ошибка была. После

Какая-то ошибка была. После обновления странички не видел своего поста. Интернет еще медленно работал... Поэтому отправил два раза.
Вроде бы все перепроверил, но ошибку так и не нашел. Может, у кого-нибудь есть мысли на этот счет?

На ум приходит только одна

На ум приходит только одна возможная ошибка, но я не уверен. Возможно второй пример Антона должен выглядеть так.

  1. <объявление_константы> ::= <имя_константы> = <константа> =>
  2. <идентификатор> = <константа> =>
  3. <идентификатор> <буква> = <константа> =>
  4. <идентификатор> <буква><буква> = <константа> =>
  5. <буква><буква><буква>= <константа> =>
  6. abc = <константа> =>
  7. abc = <текст_константа> =>
  8. abc = '<ascii-последовательность>' =>
  9. abc = <ascii-символ> =>
  10. abc = n

Ошибка Антона-Дмитрия

В 9-й стоке Дмитрия (а соответственно, и у Антона) потеряны кавычки.

Валерий Шахамболетович. А у

Валерий Шахамболетович. А у вас тут они не стоят...

Барышников Д.

А если очень внимательно посмотреть ...

А причем тут абиды?

А причем тут абиды?

Валерий Шахамболетович, но

Валерий Шахамболетович, но ведь действительно в кавычках здесь у вас только '< ascii-последовательность>':

  1. <текст_константа> ::= '<ascii-последовательность>'
  2. <ascii-последовательность> ::= <пусто> | <ascii-символ> |
  3.                      <ascii-последовательность> <ascii-символ>

Или все же следует заключать в кавычки все нетерминальные и терминальные символы, которые выводятся из '< ascii-последовательность>'? И тогда соответствующие строки должны выглядеть так:
  1. abc = '<ascii-последовательность>' =>
  2. abc = '<ascii-символ>' =>
  3. abc = 'n'

Или же только терминальные символы?

И еще поясните, пожалуйста, принципиальна такая детализированная форма записи, как у Димы:

  1. <идентификатор> = <константа> =>
  2. <идентификатор> <буква> = <константа> =>
  3. <идентификатор> <буква><буква> = <константа> =>
  4. <буква><буква><буква>= <константа> =>
  5. abc = <константа> =>

Или вполне достаточно
  1. <идентификатор> = <константа> =>
  2. <буква> | <идентификатор> <буква> = <константа> =>
  3. abc = <константа> =>

О выводе текст_константы

Дима, Антон.
БНФ - описания задают все возможные в процессе вывода интересующего нас слова, правильные способы замены нетерминалов ( левой части правил) на последовательности символов (правой части правил).
Помимо таких замен, из уже полученного текста ничего исчезнуть не может. . В частности, появившись в строке, одинарные кавычки (как терминалы, которые в процессе дальнейшего вывода не могут ничем не заменяются - на то они и терминальные, т.е. окончательные!) конечно же должны были в ней остаться!

Вернёмся к нашему описанию:

  1.  <текст_константа> ::= '<ascii-последовательность>'
  2. <ascii-последовательность> ::= <пусто> | <ascii-символ> | <ascii-последовательность> <ascii-символ>

В результате применения правила (1) нетерминал <текст_константа> (он заключён в угловые скобки!) ЗАМЕНЯЕТСЯ на слово ' < ascii-последовательность > ' . В этом слове три символа, только один из которых нетерминал. И только его мы можем заменить в соответствии с правилами (2). Кавычки не входят в угловые скобки - они терминальны, а потому остаются!
Применив теперь к слову ' < ascii-последовательность > ' правило (замену внутри кавычек!) < ascii-последовательность > ::= < ascii-символ >, мы получим '< ascii-символ > '. Потом заменим < ascii-символ > и т.д. пока не окажется, что в результирующей строке одни терминалы, т.е. заменять больше нечего.

Заметьте, на каждом шаге вывода срабатывает только одно правило,т.е. заменяется только один нетерминал. И это ответ на второй Ваш вопрос, Антон. Кстати, у того же Димы между строками 4 и 5 (в Вашем воспроизведении его вывода) должны были стоять ещё три строки (какие?). А в конце - точка (не =>), т.к. получена полностью терминальная строка и вывод завершён.
Интересно отметить, при решении задачи 3 Дима все эти трудности преодолел с честью и кавычек не потерял!

Разобрался

Кажется, теперь разобрался. Спасибо.
И правильно второй пример должен выглядеть так:

  1. <объявление_константы> ::= <имя_константы> = <константа> =>
  2. <идентификатор> = <константа> =>
  3. <идентификатор><буква> = <константа> =>
  4. <идентификатор><буква><буква> = <константа> =>
  5. <буква><буква><буква> = <константа> =>
  6. a<буква><буква> = <константа> =>
  7. ab<буква>= <константа> =>
  8. abc = <константа> =>
  9. abc = <текст_константа> =>
  10. abc = '<ascii-последовательность>' =>
  11. abc = '<ascii-символ>' =>
  12. abc = 'n'