But how do we get
— From: The compiler found an incorrect keyword
— To: Therefore it must expect a keyword (just a different keyword)?
I didn’t say it must expect a keyword. What I said is, if it finds a keyword that does not start a new statement, as in the case with «else», then the keyword must be «end». The reason for that is because the compiler is parsing a compound statement, therefore, it must expect a keyword to terminate the compound statement and, the _only_ keyword that does not start another statement that fulfills the requirement is «end».
If the keyword «else» is wrong, we can conclude something else must be expected. But that something else can be anything: A new none-empty statement, an empty statement followed by a «;», an «end».
No, it cannot be anything. What the compiler (Delphi) is saying, if you want a keyword that does not start another statement (as is the case with «else») there then it _must_ be «end». There is no other choice.
FPC stating that it expected a semicolon, in addition to being incorrect, it is also utterly useless because semicolons separate empty statements. The compiler could ask for 200 semicolons there and achieve just as much. It’s asking for a semicolon is the same (in that case) as asking for a space characters. Utterly useless.
Following your argument, that the compiler should treat an unexpected keyword as a special error, then it should simply state
«incorrect keyword»
It’s not a special error. A compound statement is terminated with «end». There is no reason for the compiler to go «generic» and state «incorrect keyword» when it knows that the only acceptable keyword that does not start another statement is «end». Since «else» does not start another statement then the only acceptable keyword that does not start another statement (as «else» is) is «end».
Yet, point in your favour:
repeat
while true do else
gives: Fatal: Syntax error, «UNTIL» expected but «ELSE» found
So it uses the knowledge about the outer block.
It’s not so much that it uses knowledge of the outer block, once the «while» is parsed, execution returns to the «repeat» production to finish parsing it, at that time, it finds an «else». The only keyword that does not start another statement that «repeat» is going to accept is «until». Since, «else» does not start another statement, the production demands an «until» keyword, as it should.
Personally, I would like to see the «; expected» error in the last case too. Just for consistency. (As both errors are equally good)
It really shouldn’t do that because, at some point the «repeat» production has to ask/demand the «until» it needs. It can’t just go asking for another semicolon every time it needs an «until».
Of course, one has to ask why change the error at all.
Purely technically it is correct. (It is not complete, but it is one correct possibility, and neither would «end expected» be complete).
No, technically, it is incorrect. That’s the problem, a compound statement is not ended with a semicolon, it’s ended with an «end» keyword. It can’t keep asking for semicolons endlessly. It really has to ask for the «end» and it has to ask for it whenever it see a symbol that does not start a new statement, whatever it may be.
The reasons to change an error message are:
1- It is plain wrong (but this is a subset of the next point)
2- The message can be improved to give the user a better idea what is wrong.The first does not apply.
On the contrary, the first applies in full. The compound statement is not asking for its terminating symbol, that’s incorrect/wrong/bad/no good/trump.
Given that «;» is statistically more likely, the «; expected» error is actually ever so slightly more helpful.
Not if the programmer wants to eventually have a program that compiles because all the semicolons in the universe put before the else aren’t going to do it.
It is basically a summary of the state of the parser, not a correction advise.
Error messages are not correction advise ? … if doing what they state isn’t going to lead to a correct statement then why does the compiler bother emitting them ?… ascii visual entertainment ?…
Example: Delphi gives the exact same error for this code:
But, here is the thing you are attempting to avoid. If you follow Delphi’s corrective «suggestions» (not advice, of course) you will eventually end up with a program that compiles.
Attempting to use FPC’s «ascii visual entertainment» yields a request for more and more semicolons and never a program that compiles successfully.
That applies to the example you showed. I used your example. Followed Delphi’s «suggestions» and after a few compiles had a syntactically correct program. If I were still following FPC’s suggestion (not advice!) this entire post would be semicolons and the program would still not compile (and not ever compile.)
I think the Delphi solution is inferior.
Interesting that the solution that leads to a syntactically correct program is «inferior» while the «solution» that has the programmer adding semicolons for infinity is not inferior.
Anyway, I just wanted to know if there was interest in having correct error message. I have the answer and, have no doubt about what it is.
Содержание
- Fatal: Syntax error, «.» expected but «;» found
- 1 Answer 1
- Pascal fatal error «;» expected but else founded
- 2 Answers 2
- Pascal fatal error «;» expected but else founded
- 2 Answers 2
- [Паскалъ] Need Help
- Почему выдаёт ошибку? Где я накосячила? Ошибка: unit1.pas(120,5) Fatal: Syntax error, «;» expected but «ELSE» found
Fatal: Syntax error, «.» expected but «;» found
1 Answer 1
The reason for this is that your begin s and end s are not balanced; disregarding the opening begin and closing end. for the program’s syntax to be correct, you should have equal numbers of each, but you have 4 begin s and 8 end s.
Obviously, your code is to compute the solutions of a quadratic equation. What I think you should do is to adjust the layout of your code so that it reflects that and then correctly the begin s and end s. In particular, your program is trying to detect whether any of a, b and d is zero and, if so, write a diagnostic message, otherwise calculate the roots by the usual formula.
Unfortunately, your begin s and end s do not reflect that. Either the whole of the block starting d := . needs to be executed or none of it does, so the else on the line before needs to be followed by a begin , as in
(You don’t say which Pascal compiler you are using, but the above fixes two points which are flagged as errors in FreePascal.
If you need more help than that, please ask in a comment.
Btw, there are some grammatical constructs in Pascal implementations where an end can appear without a matching preceding begin such as case . of . end .
Источник
Pascal fatal error «;» expected but else founded
What is causing the fatal error «;» expected but else founded message?
2 Answers 2
Unlike C, in Pascal a semicolon ; separates statements, it does not terminate them, and the then clause requires a single statement. then WriteLn(. ); else is two statements; you want then WriteLn(. ) else .
Let’s take this opportunity to learn how to read and use error messages to your advantage.
The compiler tells you exactly what the error is (it’s a ; before an else , because both of those are mentioned in the error message). It also gives you the exact line number where it’s reporting the error; that’s the number (usually in parentheses right before the error message, like (from Delphi):
[DCC Error] Project2.dpr(14): E2153 ‘;’ not allowed before ‘ELSE’
So the error is happening on line 14 (in my code — your number will be different). Let’s look at that line and a few before and after:
So look at the error message:
That clearly tells you that the ; in the line before the else is the problem (that’s very clear, because it says not allowed), so remove it.
BTW, now you’re going to get another error:
[DCC Error] Project2.dpr(15): E2003 Undeclared identifier: ‘wrtieln’
I think you should be able to figure that one out; again, the compiler gives you the exact line number.
You’re going to get another one, if you’ve posted your entire code:
[DCC Error] Project2.dpr(18): E2029 Statement expected but end of file found
This is because you’ve left out the end. that marks the end of a program file in Pascal. If you’ve not posted your entire code, you may not get it.
It’s important to learn to actually read the words when you get an error message from the compiler. In most languages, the messages are clearly worded, and they all have information you can use to try to figure out (or at least narrow down) the problems in your code.
Источник
Pascal fatal error «;» expected but else founded
What is causing the fatal error «;» expected but else founded message?
2 Answers 2
Unlike C, in Pascal a semicolon ; separates statements, it does not terminate them, and the then clause requires a single statement. then WriteLn(. ); else is two statements; you want then WriteLn(. ) else .
Let’s take this opportunity to learn how to read and use error messages to your advantage.
The compiler tells you exactly what the error is (it’s a ; before an else , because both of those are mentioned in the error message). It also gives you the exact line number where it’s reporting the error; that’s the number (usually in parentheses right before the error message, like (from Delphi):
[DCC Error] Project2.dpr(14): E2153 ‘;’ not allowed before ‘ELSE’
So the error is happening on line 14 (in my code — your number will be different). Let’s look at that line and a few before and after:
So look at the error message:
That clearly tells you that the ; in the line before the else is the problem (that’s very clear, because it says not allowed), so remove it.
BTW, now you’re going to get another error:
[DCC Error] Project2.dpr(15): E2003 Undeclared identifier: ‘wrtieln’
I think you should be able to figure that one out; again, the compiler gives you the exact line number.
You’re going to get another one, if you’ve posted your entire code:
[DCC Error] Project2.dpr(18): E2029 Statement expected but end of file found
This is because you’ve left out the end. that marks the end of a program file in Pascal. If you’ve not posted your entire code, you may not get it.
It’s important to learn to actually read the words when you get an error message from the compiler. In most languages, the messages are clearly worded, and they all have information you can use to try to figure out (or at least narrow down) the problems in your code.
Источник
[Паскалъ] Need Help
Что программа должна делать(на пхп)
ЕМНИП перед else там точка с запятой не ставится.
Не, ругается на другое, и спасибо это пофиксил.
> перед else там точка с запятой не ставится.
> ругается на другое
Условия в скобки попробуй.
Перед else ; не ставится.
У readln точно такой синтаксис? (я уже запамятовал)
Условия в скобки не надо?
Операции сравнения в скобки возьми.
А теперь, дружище, запомни, что вот этот выхлоп
untitled.pas(26,7) Error: Incompatible types: got «Boolean» expected «LongInt»
untitled.pas(28,2) Fatal: Syntax error, «;» expected but «ELSE» found
должен читать ТЫ сам, а не ЛОР.
Свободно говорю на Русском, Литовском, Английском.
Свободно говорю на Английском
Error: Incompatible types: got «Boolean» expected «LongInt»
Fatal: Syntax error, «;» expected but «ELSE» found
Источник
Почему выдаёт ошибку? Где я накосячила? Ошибка: unit1.pas(120,5) Fatal: Syntax error, «;» expected but «ELSE» found
procedure TForm1.RadioButton1Change(Sender: TObject);
begin
if radiobutton1.checked then
begin
edit1.text := IntToStr(Bin2Dec(edit1.text));
CS := 10;
s:=edit1.text
end;
else begin
edit1.text := IntToStr(Oct2Dec(edit1.text));
CS := 10;
s:=edit1.text;
Button1.Enabled:=True;
Button2.Enabled:=True;
Button3.Enabled:=True;
Button4.Enabled:=True;
Button5.Enabled:=True;
Button6.Enabled:=True;
Button7.Enabled:=True;
Button8.Enabled:=True;
Button9.Enabled:=True;
Button10.Enabled:=True;
Button11.Enabled:=True;
Button12.Enabled:=True;
Button13.Enabled:=True;
Button15.Enabled:=True;
Button16.Enabled:=True;
Button17.Enabled:=True;
Button18.Enabled:=True;
Button14.Enabled:=True;
Button19.Enabled:=True;
Button20.Enabled:=True;
Button21.Enabled:=True;
Button22.Enabled:=True;
Button23.Enabled:=True;
end;
—-исходный кусок ————
CS := 10;
s:=edit1.text
end;
else begin
————неправильно, д. б. так ——————-
CS := 10;
s:=edit1.text;
end
else begin
З. Ы. внимательнее с синтаксисом. лучше код форматировать отступами, вроде так:
begin
begin
.
end;
end;
сразу ясно какой энд какому бегину принадлежит )))
Источник
Заменить первые 3 символа слов, имеющих выбранную длину, на символ * .
Длинна слов 6-8
Количество слов 10
По найденным урокам не особо смог ориентироваться, нужен наглядный пример
Буду признателен за помощь… Спасибо заранее.
Цитата(Grief @ 11.03.2010 17:14)
нужен наглядный пример
Сделать такую замену в слове w можно примерно так:
Delete(w,3,1);
Insert('*',w,1)
Если у тебя массив из 10 слов — пройдись по нему в цикле for. Если слова в тексте — нужна функция для их поиска.
У меня вот такое получилось, но это не правильно и слишком замудренно, может кто-то по другому, более проще что ли представить может?
uses crt;
const razd:set of char=[' ','.',',',':',';','!'];
var st,buf:string;
l:integer;
begin
clrscr;
write('Длина -> ');
readln(l);
write('Строка -> ');
readln(st);repeat
if (st[1] in razd) or (length(st)=0) then while st[1] in razd do delete(st,1,1)
else
begin
while (not (st[1] in razd)) and (length(st)>0) do
begin
buf:=buf+st[1];
delete(st,1,1);
end;if length(buf)=l then
begin
buf[1]:='*';
buf[2]:='*';
buf[3]:='*';
write(buf,' ');
end;
buf:='';end;
until (length(st)=0) and (length(buf)=0);
readln;
end.
Ну, твой код должен вылетать с ошибкой, если я не ошибаюсь. По крайней мере на компиляторе, который проверяет вылет за конец строки. Смотри (сразу говорю, набираю прямо здесь, так что тестируй и еще раз тестируй, но основная идея вот такая):
const razd: set of char=[' ','.',',',':',';','!'];
var
st, buf:string;
L: integer;
begin
write('длина -> '); readln(L);
write('строка -> '); readln(st);repeat
{ для начала проверяем, первый символ - разделитель или нет? }
if (length(st)=0) or (st[1] in razd) then { СНАЧАЛА проверяем длину, только потом - st[1] !!! }
while (length(st) > 0) and (st[1] in razd) do
begin
write(st[1]); delete(st,1,1); { не теряем символы - разделители, выводим из перед удалением }
end
else begin
{ нет, не разделитель, составляем слово: }
while (length(st)>0) and (not (st[1] in razd)) do { Еще раз - СНАЧАЛА длина, потом первый символ }
begin
buf:=buf+st[1]; delete(st,1,1);
end;if length(buf) = L then
begin
delete(buf, 1, 3); insert('*', buf, 1); { <--- Удалили три символа, вставили один }
end;
write(buf); { слово печатается в любом случае, не только при каком-то условии }
buf:='';
end; { else закончился }
until (length(st)=0) and (length(buf)=0);
readln;
end.
Теперь — зачем все это делается: а затем, что если ты ввел строку, и тебя попросили заменить в ней первые символы четырех(например)-буквенных слов на звездочку, это не значит, что тебе надо вывести измененные огрызки этих самых четырехбуквенных слов. Тебе надо получить строку, полную, в которой части слов нужной длины заменены звездочками, а все остальное — сохранено (другие слова, разделители, это не должно пострадать).
Кстати, я бы еще добавил условие, проверяющее, а больше ли введенная пользователем «длина», чем 3. Потому что удалять из двухбуквенного слова три первых символа — это по меньшей мере странно. Какая-то защита от дурака должна быть…
Основа у тебя есть. Дорабатывай…
P.S. Объяснение, почему я поменял порядок следования условий, и какое вообще это имеет значение — будет, если тебе это интересно. Будут еще какие вопросы по коду — задавай.
Цитата(volvo @ 14.03.2010 20:34)
Будут еще какие вопросы по коду — задавай.
Мало надежды, что автор темы будет задавать вопросы. Скорее всего, он проигнорирует твой мессадж, volvo, как он проигнорировал мой.
Терпеть не могу спрашивающих, не обращающих внимания на ответы. Ничего не может быть хуже
Цитата(Lapp @ 15.03.2010 4:48)
Мало надежды, что автор темы будет задавать вопросы. Скорее всего, он проигнорирует твой мессадж, volvo, как он проигнорировал мой.
Терпеть не могу спрашивающих, не обращающих внимания на ответы. Ничего не может быть хуже
Извиняюсь, что не уделил должного внимания вашему сообщению, просто я не совсем понял, как такое можно реализовать, мне это тема со строками и заменой к сожалению крайне не понятна, по-этому как-то так.
Добавлено через 17 мин.
Цитата(volvo @ 14.03.2010 20:34)
Ну, твой код должен вылетать с ошибкой, если я не ошибаюсь. По крайней мере на компиляторе, который проверяет вылет за конец строки. Смотри (сразу говорю, набираю прямо здесь, так что тестируй и еще раз тестируй, но основная идея вот такая):
const razd: set of char=[' ','.',',',':',';','!'];
var
st, buf:string;
L: integer;
begin
write('длина -> '); readln(L);
write('строка -> '); readln(st);repeat
{ для начала проверяем, первый символ - разделитель или нет? }
if (length(st)=0) or (st[1] in razd) then { СНАЧАЛА проверяем длину, только потом - st[1] !!! }
while (length(st) > 0) and (st[1] in razd) do
begin
write(st[1]); delete(st,1,1); { не теряем символы - разделители, выводим из перед удалением }
end
else begin
{ нет, не разделитель, составляем слово: }
while (length(st)>0) and (not (st[1] in razd)) do { Еще раз - СНАЧАЛА длина, потом первый символ }
begin
buf:=buf+st[1]; delete(st,1,1);
end;if length(buf) = L then
begin
delete(buf, 1, 3); insert('*', buf, 1); { <--- Удалили три символа, вставили один }
end;
write(buf); { слово печатается в любом случае, не только при каком-то условии }
buf:='';
end; { else закончился }
until (length(st)=0) and (length(buf)=0);
readln;
end.
Теперь — зачем все это делается: а затем, что если ты ввел строку, и тебя попросили заменить в ней первые символы четырех(например)-буквенных слов на звездочку, это не значит, что тебе надо вывести измененные огрызки этих самых четырехбуквенных слов. Тебе надо получить строку, полную, в которой части слов нужной длины заменены звездочками, а все остальное — сохранено (другие слова, разделители, это не должно пострадать).
Кстати, я бы еще добавил условие, проверяющее, а больше ли введенная пользователем «длина», чем 3. Потому что удалять из двухбуквенного слова три первых символа — это по меньшей мере странно. Какая-то защита от дурака должна быть…
Основа у тебя есть. Дорабатывай…
P.S. Объяснение, почему я поменял порядок следования условий, и какое вообще это имеет значение — будет, если тебе это интересно. Будут еще какие вопросы по коду — задавай.
Спасибо большое, что помогаете)
Только не пойму с чем связано, выдает две ошибки:
Fatal: Syntax error, "UNTIL" expected but "ELSE" found
Fatal: Compilation aborted
Первая я так понимаю что-то с циклом, только ошибки не вижу…
А вот вторая вообще без понятия, что такое с компилятором О.о
Мне в общем эту программу нужно на лабораторной сдать, я пробовал уже именно в таком виде сдать, точнее попросил для начала, чтобы проверили, препод похвалил за оригинальность программы, но сказал сделать лучше так, как было дано в примере. А в примерах у нас черте что, pdf файл на 10 страниц по одной лабе, и там вода какая-то не по теме, конкретно моего примера нет, как делать, но там она пишется каким-то другим образом, без перечисления символов как у меня и т.д., и вообще она порядком меньше если я не ошибаюсь.
Я постараюсь сегодня скачать его и выложить сдесь пример того, как она решают эту программу там, если не сложно будет, объясните мне, буду очень благодарен)
Цитата
Только не пойму с чем связано, выдает две ошибки:
Это может быть только в случае, если ты в 15 строке поставил перед Else (а точнее — после End) точку с запятой. Обрати внимание, у меня в посте этой точки с запятой нет…
Больше не вижу способов получить такую ошибку.
Цитата
А вот вторая вообще без понятия, что такое с компилятором О.о
А ты сначала первую исправь, вторая сама собой уйдет. Просто компилятор предупреждает, что свою работу выполнить не смог, и выдает еще одно сообщение, «Компиляция прервана».
Цитата(volvo @ 15.03.2010 11:28)
Это может быть только в случае, если ты в 15 строке поставил перед Else (а точнее — после End) точку с запятой. Обрати внимание, у меня в посте этой точки с запятой нет…
Больше не вижу способов получить такую ошибку.
А ты сначала первую исправь, вторая сама собой уйдет. Просто компилятор предупреждает, что свою работу выполнить не смог, и выдает еще одно сообщение, «Компиляция прервана».
Угу, точно) Поправил, все работает.
И теперь не совсем понятно как данная программа работает.
Я ввожу длину, например 5. Ввожу строку, например 7 строка.
Дальше он мне выдает номер строки и все. Я же должен указать 10 слов, входящих по символам в указанный промежуток, а такого что-то не наблюдаю О.о
Никто ничего не должен указывать. Ты вводишь желаемую длину слова и саму строку. Все… Больше ничего делать не надо. Разбиение введенной строки на слова и «отсечение лишнего» — это забота программы:
Running "f:programspascaltest.exe"
длина -> 4
строка -> this is a test of string. some words...
*s is a *t of string. *e words...
Что не так?
Цитата(volvo @ 15.03.2010 12:33)
Никто ничего не должен указывать. Ты вводишь желаемую длину слова и саму строку. Все… Больше ничего делать не надо. Разбиение введенной строки на слова и «отсечение лишнего» — это забота программы:
Running "f:programspascaltest.exe"
длина -> 4
строка -> this is a test of string. some words...
*s is a *t of string. *e words...
Что не так?
Точно, извиняюсь)
Все идеально работает)
Осталось ещё подучить теорию получше, а то к каждой переменной и символу придираются, что-то забудешь, уже не сам делал типа) Надо будет теперь хороший мануал поискать)
Спасибо за помощь, очень благодарен) Надеюсь на дальнейшее сотрудничество
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.