Изменение грамматики - запрет условной операции как тела лямбды (во избежание конфликтов с условным оператором)

This commit is contained in:
Mikhalkovich Stanislav 2020-01-13 02:01:52 +03:00
parent ecbdc6e1a2
commit da4406700f
12 changed files with 3041 additions and 2871 deletions

View file

@ -15,7 +15,7 @@ internal static class RevisionClass
public const string Major = "3";
public const string Minor = "5";
public const string Build = "1";
public const string Revision = "2300";
public const string Revision = "2310";
public const string MainVersion = Major + "." + Minor;
public const string FullVersion = Major + "." + Minor + "." + Build + "." + Revision;

View file

@ -1,4 +1,4 @@
%COREVERSION%=1
%REVISION%=2300
%REVISION%=2310
%MINOR%=5
%MAJOR%=3

View file

@ -2,7 +2,7 @@
// This CSharp output file generated by Gardens Point LEX
// Version: 1.1.3.301
// Machine: DESKTOP-G8V08V4
// DateTime: 12.01.2020 19:05:36
// DateTime: 13.01.2020 1:44:39
// UserName: ?????????
// GPLEX input file <ABCPascal.lex>
// GPLEX frame file <embedded resource>

View file

@ -82,8 +82,8 @@
%type <stn> typed_const_list1 typed_const_list optional_expr_list elem_list optional_expr_list_with_bracket expr_list const_elem_list1 /*const_func_expr_list*/ case_label_list const_elem_list optional_const_func_expr_list elem_list1
%type <stn> enumeration_id expr_l1_list
%type <stn> enumeration_id_list
%type <ex> const_simple_expr term term1 simple_term typed_const typed_const_plus typed_var_init_expression expr expr_with_func_decl_lambda const_expr elem range_expr const_elem array_const factor relop_expr expr_dq expr_l1 expr_l1_func_decl_lambda simple_expr range_term range_factor
%type <ex> external_directive_ident init_const_expr case_label variable var_reference /*optional_write_expr*/ optional_read_expr simple_expr_or_nothing var_question_point
%type <ex> const_simple_expr term term1 simple_term typed_const typed_const_plus typed_var_init_expression expr expr_with_func_decl_lambda const_expr elem range_expr const_elem array_const factor relop_expr expr_dq expr_l1 expr_l1_func_decl_lambda expr_l1_for_lambda simple_expr range_term range_factor
%type <ex> external_directive_ident init_const_expr case_label variable var_reference /*optional_write_expr*/ optional_read_expr simple_expr_or_nothing var_question_point expr_l1_for_question_expr expr_l1_for_new_question_expr
%type <ob> for_cycle_type
%type <ex> format_expr format_const_expr const_expr_or_nothing
%type <stn> foreach_stmt
@ -134,7 +134,7 @@
%type <stn> parameter_decl
%type <stn> parameter_decl_list property_parameter_list
%type <ex> const_set
%type <ex> question_expr question_constexpr
%type <ex> question_expr question_constexpr new_question_expr
%type <ex> record_const const_field_list_1 const_field_list
%type <stn> const_field
%type <stn> repeat_stmt
@ -3124,14 +3124,39 @@ expr_l1
{ $$ = $1; }
| question_expr
{ $$ = $1; }
| new_question_expr
{ $$ = $1; }
;
expr_l1_for_question_expr
: expr_dq
{ $$ = $1; }
| question_expr
{ $$ = $1; }
;
expr_l1_for_new_question_expr
: expr_dq
{ $$ = $1; }
| new_question_expr
{ $$ = $1; }
;
expr_l1_func_decl_lambda
: expr_l1
{ $$ = $1; }
| func_decl_lambda
{ $$ = $1; }
;
expr_l1_for_lambda
: expr_dq
{ $$ = $1; }
| question_expr
{ $$ = $1; }
| func_decl_lambda
{ $$ = $1; }
;
expr_dq
: relop_expr
@ -3160,13 +3185,16 @@ typeof_expr
;
question_expr
: expr_l1 tkQuestion expr_l1 tkColon expr_l1
: expr_l1_for_question_expr tkQuestion expr_l1_for_question_expr tkColon expr_l1_for_question_expr
{
if ($3 is nil_const && $5 is nil_const)
parsertools.AddErrorFromResource("TWO_NILS_IN_QUESTION_EXPR",@3);
$$ = new question_colon_expression($1, $3, $5, @$);
}
| tkIf expr_dq tkThen expr_l1 tkElse expr_l1
;
new_question_expr
: tkIf expr_l1_for_new_question_expr tkThen expr_l1_for_new_question_expr tkElse expr_l1_for_new_question_expr
{
if (parsertools.build_tree_for_formatter)
{
@ -3179,7 +3207,8 @@ question_expr
$$ = new question_colon_expression($2, $4, $6, @$);
}
}
;
;
empty_template_type_reference
: simple_type_identifier template_type_empty_params
@ -4684,7 +4713,7 @@ common_lambda_body
lambda_function_body
: expr_l1_func_decl_lambda
: expr_l1_for_lambda
{
var id = SyntaxVisitors.ExprHasNameVisitor.HasName($1, "Result");
if (id != null)

File diff suppressed because it is too large Load diff

View file

@ -255,6 +255,10 @@ script=

View file

@ -1 +1 @@
3.5.1.2300
3.5.1.2310

View file

@ -1 +1 @@
!define VERSION '3.5.1.2300'
!define VERSION '3.5.1.2310'

View file

@ -1,5 +1,5 @@
begin
begin
var p: procedure(x: integer);
p := x -> if True then Print(x);
p := procedure(x) -> if True then Print(x);
p(666);
end.

View file

@ -1,3 +1,3 @@
begin
Arr(1,2,3).ForEach(x -> if x>1 then Print(x));
begin
Arr(1,2,3).ForEach(procedure(x) -> if x>1 then Print(x));
end.

View file

@ -628,6 +628,8 @@ function TryRead(var x: single): boolean;
/// Возвращает значение типа integer, введенное с клавиатуры
function ReadInteger: integer;
/// Возвращает значение типа int64, введенное с клавиатуры
function ReadInt64: int64;
/// Возвращает значение типа real, введенное с клавиатуры
function ReadReal: real;
/// Возвращает значение типа char, введенное с клавиатуры
@ -639,6 +641,8 @@ function ReadBoolean: boolean;
/// Возвращает значение типа integer, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnInteger: integer;
/// Возвращает значение типа int64, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnInt64: int64;
/// Возвращает значение типа real, введенное с клавиатуры, и переходит на следующую строку ввода
function ReadlnReal: real;
/// Возвращает значение типа char, введенное с клавиатуры, и переходит на следующую строку ввода
@ -752,6 +756,8 @@ function ReadlnString4(prompt: string): (string, string, string, string);
/// Выводит приглашение к вводу и возвращает значение типа integer, введенное с клавиатуры
function ReadInteger(prompt: string): integer;
/// Выводит приглашение к вводу и возвращает значение типа int64, введенное с клавиатуры
function ReadInt64(prompt: string): int64;
/// Выводит приглашение к вводу и возвращает значение типа real, введенное с клавиатуры
function ReadReal(prompt: string): real;
/// Выводит приглашение к вводу и возвращает значение типа char, введенное с клавиатуры
@ -764,6 +770,9 @@ function ReadBoolean(prompt: string): boolean;
/// Выводит приглашение к вводу и возвращает значение типа integer, введенное с клавиатуры,
///и осуществляет переход на следующую строку ввода
function ReadlnInteger(prompt: string): integer;
/// Выводит приглашение к вводу и возвращает значение типа int64, введенное с клавиатуры,
///и осуществляет переход на следующую строку ввода
function ReadlnInt64(prompt: string): int64;
/// Выводит приглашение к вводу и возвращает значение типа real, введенное с клавиатуры,
///и осуществляет переход на следующую строку ввода
function ReadlnReal(prompt: string): real;
@ -821,6 +830,8 @@ procedure Readln(f: Text; var x: string);
/// Возвращает значение типа integer, введенное из текстового файла f
function ReadInteger(f: Text): integer;
/// Возвращает значение типа int64, введенное из текстового файла f
function ReadInt64(f: Text): int64;
/// Возвращает значение типа real, введенное из текстового файла f
function ReadReal(f: Text): real;
/// Возвращает значение типа char, введенное из текстового файла f
@ -833,6 +844,9 @@ function ReadBoolean(f: Text): boolean;
/// Возвращает значение типа integer, введенное из текстового файла f,
///и осуществляет переход на следующую строку
function ReadlnInteger(f: Text): integer;
/// Возвращает значение типа int64, введенное из текстового файла f,
///и осуществляет переход на следующую строку
function ReadlnInt64(f: Text): int64;
/// Возвращает значение типа real, введенное из текстового файла f,
///и осуществляет переход на следующую строку
function ReadlnReal(f: Text): real;
@ -1913,6 +1927,13 @@ function ReadArrInteger(n: integer): array of integer;
function ReadArrReal(n: integer): array of real;
/// Возвращает массив из n строк, введенных с клавиатуры
function ReadArrString(n: integer): array of string;
///--
function ReadArrInteger: array of integer;
///--
function ReadArrReal: array of real;
///--
function ReadArrString: array of string;
/// Выводит приглашение к вводу и возвращает массив из n целых, введенных с клавиатуры
function ReadArrInteger(prompt: string; n: integer): array of integer;
@ -2035,6 +2056,13 @@ function __WildCardsTupleEqual<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12
elemsToCompare: sequence of integer): boolean;
// Вспомогательные функции для a..b
///--
function InRangeInternal(x: integer; a,b: integer): boolean;
///--
function InRangeInternal(x: char; a,b: char): boolean;
// -----------------------------------------------------
// Стандартные классы исключений
// -----------------------------------------------------
@ -4392,6 +4420,26 @@ begin
Result := ReadArrString(n);
end;
///--
function ReadArrInteger: array of integer;
begin
Result := nil;
raise new System.ArgumentException('Функцию ReadArrInteger запрещено вызывать без параметров')
end;
///--
function ReadArrReal: array of real;
begin
Result := nil;
raise new System.ArgumentException('Функцию ReadArrReal запрещено вызывать без параметров')
end;
///--
function ReadArrString: array of string;
begin
Result := nil;
raise new System.ArgumentException('Функцию ReadArrString запрещено вызывать без параметров')
end;
function ReadSeqInteger(n: integer): sequence of integer;
begin
Result := Range(1, n).Select(i -> ReadInteger());
@ -5213,59 +5261,59 @@ begin
end
end;
function ReadInteger: integer;
begin
var x: integer;
read(x);
Result := x;
Read(Result);
end;
function ReadInt64: int64;
begin
Read(Result);
end;
function ReadReal: real;
begin
var x: real;
read(x);
Result := x;
Read(Result);
end;
function ReadChar: char;
begin
var x: char;
read(x);
Result := x;
Read(Result);
end;
function ReadString: string;
begin
var x: string;
read(x);
Read(Result);
readln();
Result := x;
end;
function ReadBoolean: boolean;
begin
var x: boolean;
read(x);
Result := x;
Read(Result);
end;
function ReadlnInteger: integer;
begin
Result := ReadInteger;
readln();
Readln();
end;
function ReadlnInt64: int64;
begin
Result := ReadInt64;
Readln();
end;
function ReadlnReal: real;
begin
Result := ReadReal;
readln();
Readln();
end;
function ReadlnChar: char;
begin
Result := ReadChar;
readln();
Readln();
end;
function ReadlnString: string;
@ -5276,7 +5324,7 @@ end;
function ReadlnBoolean: boolean;
begin
Result := ReadBoolean;
readln();
Readln();
end;
function ReadInteger2 := (ReadInteger, ReadInteger);
@ -5388,6 +5436,12 @@ begin
Result := ReadInteger;
end;
function ReadInt64(prompt: string): int64;
begin
Print(prompt);
Result := ReadInt64;
end;
function ReadReal(prompt: string): real;
begin
Print(prompt);
@ -5418,6 +5472,12 @@ begin
Result := ReadlnInteger;
end;
function ReadlnInt64(prompt: string): int64;
begin
Print(prompt);
Result := ReadlnInt64;
end;
function ReadlnReal(prompt: string): real;
begin
Print(prompt);
@ -5674,56 +5734,57 @@ end;
function ReadInteger(f: Text): integer;
begin
var x: integer;
read(f, x);
Result := x;
Read(f, Result);
end;
function ReadInt64(f: Text): int64;
begin
Read(f, Result);
end;
function ReadReal(f: Text): real;
begin
var x: real;
read(f, x);
Result := x;
Read(f, Result);
end;
function ReadChar(f: Text): char;
begin
var x: char;
read(f, x);
Result := x;
Read(f, Result);
end;
function ReadString(f: Text): string;
begin
var x: string;
read(f, x);
readln(f);
Result := x;
Read(f, Result);
Readln(f);
end;
function ReadBoolean(f: Text): boolean;
begin
var x: boolean;
read(f, x);
Result := x;
Read(f, Result);
end;
function ReadlnInteger(f: Text): integer;
begin
Result := ReadInteger(f);
readln(f);
Readln(f);
end;
function ReadlnInt64(f: Text): int64;
begin
Result := ReadInt64(f);
Readln(f);
end;
function ReadlnReal(f: Text): real;
begin
Result := ReadReal(f);
readln(f);
Readln(f);
end;
function ReadlnChar(f: Text): char;
begin
Result := ReadChar(f);
readln(f);
Readln(f);
end;
function ReadlnString(f: Text): string;
@ -5734,7 +5795,7 @@ end;
function ReadlnBoolean(f: Text): boolean;
begin
Result := ReadBoolean(f);
readln(f);
Readln(f);
end;
// -----------------------------------------------------
// TextFile methods
@ -9347,6 +9408,26 @@ end;
//>> Методы расширения списков # Extension methods for List T
// -----------------------------------------------------
/// Возвращает последовательность индексов списка
function Indices<T>(Self: List<T>): sequence of integer; extensionmethod := Range(0, Self.Count - 1);
/// Возвращает последовательность индексов элементов списка, удовлетворяющих условию
function Indices<T>(Self: List<T>; cond: T->boolean): sequence of integer; extensionmethod;
begin
for var i := 0 to Self.Count - 1 do
if cond(Self[i]) then
yield i;
end;
/// Возвращает последовательность индексов элементов списка, удовлетворяющих условию
function Indices<T>(Self: List<T>; cond: (T,integer) ->boolean): sequence of integer; extensionmethod;
begin
for var i := 0 to Self.Count - 1 do
if cond(Self[i], i) then
yield i;
end;
/// Перемешивает элементы списка случайным образом
function Shuffle<T>(Self: List<T>): List<T>; extensionmethod;
begin
@ -9725,8 +9806,11 @@ end;
function SystemSliceListImpl<T>(Self: List<T>; situation: integer; from, &to: integer; step: integer := 1): List<T>;
begin
var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, Self.Count, from, &to, step);
Result := CreateSliceFromListInternal(Self, from, step, count);
{if (step=1) and (count>32) then // 32 - empirical
begin
Result := Self.GetRange(from,count);
end
else} Result := CreateSliceFromListInternal(Self, from, step, count);
end;
///--
@ -10518,8 +10602,12 @@ end;
function SystemSliceArrayImpl<T>(Self: array of T; situation: integer; from, &to: integer; step: integer := 1): array of T;
begin
var count := CheckAndCorrectFromToAndCalcCountForSystemSlice(situation, Self.Length, from, &to, step);
Result := CreateSliceFromArrayInternal(Self, from, step, count)
{if (step = 1) and (count>32) then // 32 - empirical
begin
Result := new T[count];
System.Array.Copy(Self,from,Result,0,count);
end
else} Result := CreateSliceFromArrayInternal(Self, from, step, count)
end;
///--
@ -10582,11 +10670,16 @@ begin
end;
///--
function InRangeInternal(Self: integer; a,b: integer): boolean; extensionmethod;
function InRangeInternal(x: integer; a,b: integer): boolean;
begin
Result := (a <= Self) and (Self <= b)
Result := (a <= x) and (x <= b)
end;
///--
function InRangeInternal(x: char; a,b: char): boolean;
begin
Result := (a <= x) and (x <= b)
end;
// Дополнения февраль 2016: IsEven, IsOdd

View file

@ -16,8 +16,9 @@ namespace PascalABCCompiler.TreeConverter
// SSM 24.12.19 lambda_capture_foreach_counter.pas не проходит если откомментировать эти 2 строки
// Причина - лямбда уже начала разбираться
// Пробую сделать так: если foreach в лямбде, то оптимизация не делается, а если нет, то делается
syntax_tree_node p = _foreach_stmt;
// Пока не получилось - ошибка err0157.pas начинает быть правильной программой
// Надо как-то переменную x в стек context.loop_var_stack.Push(foreachVariable); помещать !!! Но не сейчас... (SSM 12.01.20)
/*syntax_tree_node p = _foreach_stmt;
do
{
p = p.Parent;
@ -27,7 +28,7 @@ namespace PascalABCCompiler.TreeConverter
{
var feWhat = convert_strong(_foreach_stmt.in_what);
if (OptimizeForeachInCase1DArray(_foreach_stmt, feWhat)) return;
}
}*/
statements_list sl2 = new statements_list(get_location(_foreach_stmt));
convertion_data_and_alghoritms.statement_list_stack_push(sl2);