Итак. согласно
спецификации точка с запятой в Го обязательна и вставляется в конце строки после:
Цитата:
- an identifier
- an integer, floating-point, imaginary, rune, or string literal
- one of the keywords break, continue, fallthrough, or return
- one of the operators and punctuation ++, --, ), ], or }
А что остаётся от лексем?
Цитата:
identifiers, keywords, operators and punctuation, and literals
Какие есть литералы, кроме тех, после которых вставляется? Composite Literal и Function Literal.
Код:
CompositeLit = LiteralType LiteralValue .
LiteralType = StructType | ArrayType | "[" "..." "]" ElementType |
SliceType | MapType | TypeName .
LiteralValue = "{" [ ElementList [ "," ] ] "}" .
Код:
FunctionLit = "func" Signature FunctionBody .
FunctionBody = Block .
Block = "{" StatementList "}"
Оба литерала завершаются фигурной скобкой. Значит, после любых литералов вставляется.
Ключевые слова какие остались?
Код:
-break default func interface select
case defer go map struct
chan else goto package switch
const -fallthrough if range type
-continue for import -return var
Минусом я пометил ключевые слова, после которых вставляется точка с запятой.
Как видим, здесь получается сложное правило, которое было мнемонически сформулировано как "если ключевое слово может завершать предписание (я называю statement-ы предписаниями, чтобы не путать операторы с операциями - такая путаница пришла к нам из английского) , то за ним вставляется точка с запятой". И тут мы приходим к неприятному для меня моменту:
по моему правилу нельзя написать на отдельной строчке слово var, type или const а в go это можно. Кажется, получается, что сложность правила в голанге оправдана в этом моменте.
Теперь операции:
Код:
Expression = UnaryExpr | Expression binary_op Expression .
UnaryExpr = PrimaryExpr | unary_op UnaryExpr .
binary_op = "||" | "&&" | rel_op | add_op | mul_op .
rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" .
add_op = "+" | "-" | "|" | "^" .
mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" | "&^" .
unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" .
Ребята из го, у вас странная спецификация, ++ и -- - это не операции, а предписания. Но лексемы ++ и -- находятся в категории "операции и знаков препинания", забавно.
Код:
+ & += &= && == != ( )
- | -= |= || < <= [ ]
* ^ *= ^= <- > >= { }
/ << /= <<= ++ = := , ;
% >> %= >>= -- ! ... . :
&^ &^=
Раз у вас ++ и -- - не операции, значит они знаки препинания, что ли? Несмотря на этот терминологический косяк, вот определение предписаний инкремента и декремента.
Код:
IncDecStmt = Expression ( "++" | "--" ) .
Знаки ++ и -- могут стоять только после выражения, а не до (вот кстати типичный путь Оберона). Тоже вроде логично - если у нас есть бинарная операция, то мы ставим её в конце строчки и это означает, что „продолжение следует“. Поскольку создатели языка стремились к тому, чтобы язык читался слева направо (молодцы), у них все унарные операции являются префиксными, а ++ и -- они огородили, сделав их предписаниями.
А теперь, соответственно, домашнее задание: можно ли моё правило починить так, чтобы оно было не хуже голанга. Цель тут - сделать правило более простое и понятное. Моё правило в последней редакции звучит как-то так:
Код:
- точка с запятой обязательна даже перед end
- пустой оператор запрещён
- точка с запятой вставляется в конце строки, кроме случая открывающих скобок
- вместо продолжения строки строка делается длинной, а среда разработки должна её переносить
В общем, сразу видны проблемы:
Код:
PROCEDURE P()
BEGIN m := a + b + c + d + e
END P
Из-за слишком интенсивной вставки точек с запятой весь код норовит
залезть на одну строчку. Чтобы это поправить, придётся вводить список ключевых слов,
приравненных к открывающим скобкам, и включить туда хотя бы BEGIN.
Скорее получается, что нужно ввести понятие "открывающего слова", которое как бы скобка, а закрывается оно
точкой с запятой. И сказать, что после открывающих слов точка с запятой не вставляется. Получится то же, что в go,
но вместо перечисления большого списка ключевых слов, которые непонятно по какому принципу отобраны, мы
назовём одно понятие.
Кстати, о птичках - голанг - это не очень сильно переделанный активный оберон (и плюс заимствования из языков, о которых я ничего не знаю, поэтому и не могу увидеть этих заимствований). Но там ради моды приделали фигурные скобочки. Это к вопросу о моде.