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

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

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

(ответы строго обосновывать!):
МиП. Задача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'