* Change syntax tree language field to be string Тип LanguageId заменен на string * Fix unit language name assigning * Update lexer and parser * Add checks to avoid NullReferenceException Проверки на null для SyntaxTree. (К падению компилятора они не приводили, т.к. они связаны с другими ошибками, например синтаксическими), но мешали отладке. * Return initial lexer and parser versions * Revert language name assigning
5319 lines
144 KiB
Plaintext
5319 lines
144 KiB
Plaintext
// Copyright (c) Ivan Bondarev, Stanislav Mikhalkovich (for details please see \doc\copyright.txt)
|
||
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
|
||
// SSM 21/11/16 Лямбда выражения вынесены на верхний уровень (п.ч. присваивания и параметры)
|
||
|
||
%{
|
||
// Эти объявления добавляются в класс GPPGParser, представляющий собой парсер, генерируемый системой gppg
|
||
public syntax_tree_node root; // Корневой узел синтаксического дерева
|
||
|
||
public int maxErrors = 10;
|
||
public PascalParserTools parserTools;
|
||
public ParserLambdaHelper lambdaHelper = new ParserLambdaHelper();
|
||
|
||
public GPPGParser(AbstractScanner<PascalABCCompiler.ParserTools.Union, LexLocation> scanner) : base(scanner) { }
|
||
%}
|
||
|
||
%output=ABCPascalYacc.cs
|
||
%partial
|
||
%parsertype GPPGParser
|
||
|
||
%using PascalABCCompiler.SyntaxTree;
|
||
%using Languages.Pascal.Frontend.Errors;
|
||
%using PascalABCCompiler.ParserTools;
|
||
%using System.Linq;
|
||
|
||
%namespace Languages.Pascal.Frontend.Core
|
||
|
||
%YYSTYPE PascalABCCompiler.ParserTools.Union
|
||
|
||
%start parse_goal
|
||
|
||
%token <ti> tkDirectiveName tkAmpersend tkColon tkDotDot tkPoint tkRoundOpen tkRoundClose tkSemiColon tkSquareOpen tkSquareClose tkQuestion tkUnderscore tkQuestionPoint tkDoubleQuestion tkQuestionSquareOpen
|
||
%token <ti> tkBackSlashRoundOpen tkAsync tkAwait
|
||
%token <ti> tkSizeOf tkTypeOf tkWhere tkArray tkCase tkClass tkAuto tkStatic tkConst tkConstructor tkDestructor tkElse tkExcept tkFile tkFor tkForeach tkFunction tkMatch tkWhen
|
||
%token <ti> tkIf tkImplementation tkInherited tkInterface tkProcedure tkOperator tkProperty tkRaise tkRecord tkSet tkType tkThen tkUses tkVar tkWhile tkWith tkNil
|
||
%token <ti> tkGoto tkOf tkLabel tkLock tkProgram tkEvent tkDefault tkTemplate tkExports tkResourceString tkThreadvar tkSealed tkPartial tkTo tkDownto
|
||
%token <ti> tkLoop
|
||
%token <ti> tkSequence tkYield tkShortProgram tkVertParen tkShortSFProgram
|
||
%token <id> tkNew
|
||
%token <id> tkOn
|
||
%token <id> tkName tkPrivate tkProtected tkPublic tkInternal tkRead tkWrite
|
||
%token <id> tkIndex
|
||
%token <ti> tkParseModeExpression tkParseModeStatement tkParseModeType tkBegin tkEnd
|
||
%token <ti> tkAsmBody tkILCode tkError INVISIBLE
|
||
%token <ti> tkRepeat tkUntil tkDo tkComma tkFinally tkTry
|
||
%token <ti> tkInitialization tkFinalization tkUnit tkLibrary tkExternal tkParams tkNamespace
|
||
%token <op> tkAssign tkPlusEqual tkMinusEqual tkMultEqual tkDivEqual tkMinus tkPlus tkSlash tkStar tkStarStar tkEqual tkGreater tkGreaterEqual tkLower tkLowerEqual
|
||
%token <op> tkNotEqual tkCSharpStyleOr tkArrow tkOr tkXor tkAnd tkDiv tkMod tkShl tkShr tkNot tkAs tkIn tkIs tkImplicit tkExplicit tkAddressOf tkDeref
|
||
%token <id> tkDirectiveName tkIdentifier
|
||
%token <stn> tkStringLiteral tkFormatStringLiteral tkMultilineStringLiteral tkAsciiChar
|
||
%token <id> tkAbstract tkForward tkOverload tkReintroduce tkOverride tkVirtual tkExtensionMethod
|
||
%token <ex> tkInteger tkBigInteger tkFloat tkHex
|
||
%token <id> tkUnknown
|
||
%token <ti> tkStep
|
||
|
||
%type <ti> unit_key_word class_or_static
|
||
%type <stn> assignment
|
||
%type <stn> optional_array_initializer
|
||
%type <stn> attribute_declarations
|
||
%type <stn> ot_visibility_specifier
|
||
%type <stn> one_attribute attribute_variable
|
||
%type <ex> const_factor const_factor_without_unary_op const_variable_2 const_term const_variable literal_or_number unsigned_number variable_or_literal_or_number
|
||
%type <stn> program_block
|
||
%type <ob> optional_var class_attribute class_attributes class_attributes1
|
||
%type <ob> lambda_unpacked_params_or_id lambda_list_of_unpacked_params_or_id
|
||
%type <stn> member_list_section optional_component_list_seq_end
|
||
%type <stn> const_decl only_const_decl
|
||
%type <stn> const_decl_sect
|
||
%type <td> object_type record_type
|
||
%type <stn> member_list method_decl_list field_or_const_definition_list
|
||
%type <stn> case_stmt
|
||
%type <stn> case_list
|
||
%type <stn> program_decl_sect_list int_decl_sect_list1 inclass_decl_sect_list1 interface_decl_sect_list decl_sect_list decl_sect_list1 inclass_decl_sect_list
|
||
%type <stn> decl_sect_list_proc_func_only
|
||
%type <stn> field_or_const_definition abc_decl_sect decl_sect int_decl_sect type_decl simple_type_decl simple_field_or_const_definition res_str_decl_sect
|
||
%type <stn> method_decl_withattr method_or_property_decl property_definition fp_sect
|
||
%type <ex> default_expr tuple
|
||
%type <stn> expr_as_stmt
|
||
%type <stn> exception_block
|
||
%type <stn> external_block
|
||
%type <stn> exception_handler
|
||
%type <stn> exception_handler_list
|
||
%type <stn> exception_identifier
|
||
%type <stn> typed_const_list1 typed_const_list optional_expr_list optional_expr_list_func_param elem_list optional_expr_list_with_bracket expr_list expr_list_func_param const_elem_list1 /*const_expr_list*/ case_label_list const_elem_list optional_const_func_expr_list elem_list1
|
||
%type <stn> enumeration_id expr_l1_or_unpacked_list
|
||
// %type <stn> expr_l1_list
|
||
%type <stn> enumeration_id_list
|
||
%type <ex> const_simple_expr term term1 typed_const typed_const_plus typed_var_init_expression expr expr_with_func_decl_lambda expr_with_func_decl_lambda_ass const_expr const_relop_expr elem range_expr const_elem array_const factor factor_without_unary_op relop_expr expr_dq
|
||
%type <ex> lambda_unpacked_params expr_l1 expr_l1_or_unpacked 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 proc_func_call 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 /* simple_expr_with_deref_or_nothing simple_expr_with_deref expr_l1_for_indexer*/
|
||
%type <stn> foreach_stmt
|
||
%type <stn> for_stmt loop_stmt yield_stmt yield_sequence_stmt
|
||
%type <stn> fp_list fp_sect_list
|
||
%type <td> file_type sequence_type
|
||
%type <stn> var_address
|
||
%type <stn> goto_stmt
|
||
%type <id> func_name_ident param_name const_field_name func_name_with_template_args identifier_or_keyword unit_name exception_variable const_name func_meth_name_ident label_name type_decl_identifier template_identifier_with_equal
|
||
%type <id> program_param identifier identifier_keyword_operatorname func_class_name_ident /*optional_identifier*/ visibility_specifier
|
||
%type <id> property_specifier_directives non_reserved
|
||
%type <stn> if_stmt
|
||
%type <stn> initialization_part
|
||
%type <stn> template_arguments label_list ident_or_keyword_pointseparator_list ident_list param_name_list
|
||
%type <stn> inherited_message
|
||
%type <stn> implementation_part
|
||
%type <stn> interface_part abc_interface_part
|
||
%type <stn> simple_type_list
|
||
%type <ex> literal one_literal
|
||
%type <stn> literal_list
|
||
%type <stn> label_decl_sect
|
||
%type <stn> lock_stmt
|
||
%type <stn> func_name proc_name optional_proc_name
|
||
%type <ex> new_expr allowable_expr_as_stmt
|
||
%type <stn> parse_goal parts inclass_block block proc_func_external_block
|
||
%type <td> exception_class_type_identifier simple_type_identifier //idp
|
||
%type <stn> base_class_name
|
||
%type <stn> base_classes_names_list optional_base_classes
|
||
%type <ob> one_compiler_directive optional_head_compiler_directives head_compiler_directives program_heading_2 optional_tk_point program_param_list optional_semicolon
|
||
%type <ex> operator_name_ident
|
||
%type <op> const_relop const_addop assign_operator const_mulop relop addop mulop sign overload_operator
|
||
%type <ob> typecast_op
|
||
%type <stn> property_specifiers
|
||
%type <stn> write_property_specifiers
|
||
%type <stn> read_property_specifiers
|
||
%type <stn> array_defaultproperty
|
||
%type <stn> meth_modificators optional_method_modificators optional_method_modificators1
|
||
%type <id> meth_modificator property_modificator
|
||
%type <ex> optional_property_initialization
|
||
%type <stn> proc_call
|
||
%type <stn> proc_func_constr_destr_decl proc_func_decl inclass_proc_func_decl inclass_proc_func_decl_noclass constr_destr_decl inclass_constr_destr_decl
|
||
%type <stn> method_decl proc_func_constr_destr_decl_with_attr proc_func_decl_noclass
|
||
%type <td> method_header proc_type_decl procedural_type_kind proc_header procedural_type constr_destr_header proc_func_header
|
||
%type <td> func_header method_procfunc_header int_func_header int_proc_header
|
||
%type <stn> property_interface
|
||
%type <stn> program_file
|
||
%type <stn> program_header
|
||
%type <stn> parameter_decl
|
||
%type <stn> parameter_decl_list property_parameter_list
|
||
%type <ex> const_set
|
||
%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
|
||
%type <stn> raise_stmt
|
||
%type <td> pointer_type
|
||
%type <stn> attribute_declaration one_or_some_attribute
|
||
%type <stn> stmt_list else_case exception_block_else_branch compound_stmt
|
||
%type <td> string_type
|
||
%type <ex> sizeof_expr
|
||
%type <stn> simple_property_definition
|
||
%type <stn> stmt_or_expression unlabelled_stmt stmt case_item
|
||
%type <td> set_type
|
||
%type <ex> as_is_expr as_is_constexpr is_type_expr as_expr power_expr power_constexpr
|
||
%type <td> unsized_array_type simple_type_or_ simple_type simple_type_question/*array_name_for_new_expr*/ optional_type_specification fptype type_ref fptype_noproctype array_type
|
||
%type <td> template_param template_empty_param structured_type empty_template_type_reference simple_or_template_type_reference simple_or_template_or_question_type_reference type_ref_or_secific type_decl_type
|
||
%type <stn> type_ref_and_secific_list
|
||
%type <stn> type_decl_sect
|
||
%type <stn> try_handler
|
||
%type <ti> class_or_interface_keyword optional_tk_do keyword reserved_keyword
|
||
%type <ex> typeof_expr
|
||
%type <stn> simple_fp_sect
|
||
%type <stn> template_param_list template_empty_param_list template_type_params template_type_empty_params
|
||
%type <td> template_type
|
||
%type <stn> try_stmt
|
||
%type <stn> uses_clause used_units_list uses_clause_one uses_clause_one_or_empty
|
||
%type <stn> unit_file
|
||
%type <stn> used_unit_name
|
||
%type <stn> unit_header
|
||
%type <stn> var_decl_sect
|
||
%type <stn> var_decl var_decl_part /*var_decl_internal*/ field_definition var_decl_with_assign_var_tuple
|
||
%type <stn> var_stmt
|
||
%type <stn> where_part
|
||
%type <stn> where_part_list optional_where_section
|
||
%type <stn> while_stmt
|
||
%type <stn> with_stmt
|
||
%type <ex> variable_as_type dotted_identifier
|
||
%type <ex> func_decl_lambda expl_func_decl_lambda
|
||
%type <td> lambda_type_ref lambda_type_ref_noproctype
|
||
%type <stn> full_lambda_fp_list lambda_simple_fp_sect lambda_function_body lambda_procedure_body common_lambda_body optional_full_lambda_fp_list
|
||
%type <ob> field_in_unnamed_object list_fields_in_unnamed_object func_class_name_ident_list rem_lambda variable_list var_ident_list
|
||
%type <ti> tkAssignOrEqual
|
||
%type <stn> const_pattern_expression pattern deconstruction_or_const_pattern pattern_optional_var collection_pattern tuple_pattern collection_pattern_list_item tuple_pattern_item collection_pattern_var_item match_with pattern_case pattern_cases pattern_out_param pattern_out_param_optional_var
|
||
%type <ob> pattern_out_param_list pattern_out_param_list_optional_var collection_pattern_expr_list tuple_pattern_item_list const_pattern_expr_list
|
||
%type <stn> var_with_init_for_expr_with_let var_with_init_for_expr_with_let_list
|
||
%type <id> index_or_nothing
|
||
|
||
%%
|
||
|
||
parse_goal
|
||
: program_file
|
||
{ root = $1; }
|
||
| unit_file
|
||
{ root = $1; }
|
||
| parts
|
||
{ root = $1; }
|
||
| tkShortProgram uses_clause_one_or_empty decl_sect_list_proc_func_only stmt_list
|
||
{
|
||
var stl = $4 as statement_list;
|
||
stl.left_logical_bracket = new token_info("");
|
||
stl.right_logical_bracket = new token_info("");
|
||
var ul = $2 as uses_list;
|
||
root = $$ = NewProgramModule(null, null, ul, new block($3 as declarations, stl, @4), new token_info(""), LexLocation.MergeAll(@2,@3,@4));
|
||
}
|
||
| tkShortSFProgram uses_clause_one_or_empty decl_sect_list_proc_func_only stmt_list
|
||
{
|
||
var stl = $4 as statement_list;
|
||
stl.left_logical_bracket = new token_info("");
|
||
stl.right_logical_bracket = new token_info("");
|
||
var un = new unit_or_namespace(new ident_list("SF"),null);
|
||
var ul = $2 as uses_list;
|
||
if (ul == null)
|
||
//var un1 = new unit_or_namespace(new ident_list("School"),null);
|
||
ul = new uses_list(un,null);
|
||
else ul.Insert(0,un);
|
||
//ul.Add(un1);
|
||
root = $$ = NewProgramModule(null, null, ul, new block($3 as declarations, stl, @$), new token_info(""), LexLocation.MergeAll(@2,@3,@4));
|
||
}
|
||
;
|
||
|
||
parts
|
||
: tkParseModeExpression expr
|
||
{ $$ = $2; }
|
||
| tkParseModeExpression tkType type_decl_identifier
|
||
{ $$ = $3; }
|
||
| tkParseModeType variable_as_type
|
||
{ $$ = $2; }
|
||
| tkParseModeStatement stmt_or_expression
|
||
{ $$ = $2; }
|
||
|
||
;
|
||
|
||
stmt_or_expression
|
||
: expr
|
||
{ $$ = new expression_as_statement($1,@$);}
|
||
| assignment
|
||
{ $$ = $1; }
|
||
| var_stmt
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
optional_head_compiler_directives
|
||
:
|
||
{ $$ = null; }
|
||
| head_compiler_directives
|
||
{ $$ = null; }
|
||
;
|
||
|
||
head_compiler_directives
|
||
: one_compiler_directive
|
||
{ $$ = null; }
|
||
| head_compiler_directives one_compiler_directive
|
||
{ $$ = null; }
|
||
;
|
||
|
||
one_compiler_directive
|
||
: tkDirectiveName tkIdentifier
|
||
{
|
||
parserTools.AddErrorFromResource("UNSUPPORTED_OLD_DIRECTIVES",@$);
|
||
$$ = null;
|
||
}
|
||
| tkDirectiveName tkStringLiteral
|
||
{
|
||
parserTools.AddErrorFromResource("UNSUPPORTED_OLD_DIRECTIVES",@$);
|
||
$$ = null;
|
||
}
|
||
;
|
||
|
||
program_file
|
||
: program_header optional_head_compiler_directives uses_clause program_block optional_tk_point
|
||
{
|
||
$$ = NewProgramModule($1 as program_name, $2, $3 as uses_list, $4, $5, @$);
|
||
}
|
||
;
|
||
|
||
/* это нужно для intellisensа чтобы строилось дерево при отсутствии точки в конце */
|
||
optional_tk_point
|
||
: tkPoint
|
||
{ $$ = $1; }
|
||
| tkSemiColon
|
||
{ $$ = null; }
|
||
| tkColon
|
||
{ $$ = null; }
|
||
| tkComma
|
||
{ $$ = null; }
|
||
| tkDotDot
|
||
{ $$ = null; }
|
||
|
|
||
;
|
||
|
||
program_header
|
||
:
|
||
{ $$ = null; }
|
||
| tkProgram identifier program_heading_2
|
||
{ $$ = new program_name($2,@$); }
|
||
;
|
||
|
||
program_heading_2
|
||
: tkSemiColon
|
||
{ $$ = null; }
|
||
| tkRoundOpen program_param_list tkRoundClose tkSemiColon
|
||
{ $$ = null; }
|
||
;
|
||
|
||
program_param_list
|
||
: program_param
|
||
{ $$ = null; }
|
||
| program_param_list tkComma program_param
|
||
{ $$ = null; }
|
||
;
|
||
|
||
program_param
|
||
: identifier
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
program_block
|
||
: program_decl_sect_list compound_stmt
|
||
{
|
||
$$ = new block($1 as declarations, $2 as statement_list, @$);
|
||
}
|
||
;
|
||
|
||
program_decl_sect_list
|
||
: decl_sect_list
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
ident_or_keyword_pointseparator_list
|
||
: identifier_or_keyword
|
||
{
|
||
$$ = new ident_list($1, @$);
|
||
}
|
||
| ident_or_keyword_pointseparator_list tkPoint identifier_or_keyword
|
||
{
|
||
$$ = ($1 as ident_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
|
||
uses_clause_one
|
||
: tkUses used_units_list tkSemiColon
|
||
{
|
||
$$ = $2;
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
uses_clause_one_or_empty
|
||
:
|
||
{
|
||
$$ = null;
|
||
}
|
||
| uses_clause_one
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new uses_closure($1 as uses_list,@$);
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
uses_clause
|
||
:
|
||
{
|
||
$$ = null;
|
||
}
|
||
| uses_clause uses_clause_one
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
{
|
||
if ($1 == null)
|
||
{
|
||
$$ = new uses_closure($2 as uses_list,@$);
|
||
}
|
||
else {
|
||
($1 as uses_closure).AddUsesList($2 as uses_list,@$);
|
||
$$ = $1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if ($1 == null)
|
||
{
|
||
$$ = $2;
|
||
$$.source_context = @$;
|
||
}
|
||
else
|
||
{
|
||
($1 as uses_list).AddUsesList($2 as uses_list,@$);
|
||
$$ = $1;
|
||
$$.source_context = @$;
|
||
}
|
||
}
|
||
}
|
||
;
|
||
|
||
used_units_list
|
||
: used_unit_name
|
||
{
|
||
$$ = new uses_list($1 as unit_or_namespace,@$);
|
||
}
|
||
| used_units_list tkComma used_unit_name
|
||
{
|
||
$$ = ($1 as uses_list).Add($3 as unit_or_namespace, @$);
|
||
}
|
||
;
|
||
|
||
used_unit_name
|
||
: ident_or_keyword_pointseparator_list
|
||
{
|
||
$$ = new unit_or_namespace($1 as ident_list,@$);
|
||
}
|
||
| ident_or_keyword_pointseparator_list tkIn tkStringLiteral
|
||
{
|
||
if ($3 is char_const _cc)
|
||
$3 = new string_const(_cc.cconst.ToString());
|
||
$$ = new uses_unit_in($1 as ident_list, $3 as string_const, @$);
|
||
}
|
||
;
|
||
|
||
unit_file
|
||
:
|
||
//attribute_declarations
|
||
unit_header interface_part implementation_part initialization_part tkPoint
|
||
{
|
||
$$ = new unit_module($1 as unit_name, $2 as interface_node, $3 as implementation_node,
|
||
($4 as initfinal_part).initialization_sect, ($4 as initfinal_part).finalization_sect, /*$1 as attribute_list*/ null, @$);
|
||
($$ as compilation_unit).Language = PascalABCCompiler.StringConstants.pascalLanguageName;
|
||
}
|
||
|
|
||
//attribute_declarations
|
||
unit_header abc_interface_part initialization_part tkPoint
|
||
{
|
||
$$ = new unit_module($1 as unit_name, $2 as interface_node, null,
|
||
($3 as initfinal_part).initialization_sect, ($3 as initfinal_part).finalization_sect, /*$1 as attribute_list*/ null, @$);
|
||
($$ as compilation_unit).Language = PascalABCCompiler.StringConstants.pascalLanguageName;
|
||
}
|
||
;
|
||
|
||
unit_header
|
||
: unit_key_word unit_name tkSemiColon optional_head_compiler_directives
|
||
{
|
||
$$ = NewUnitHeading(new ident($1.text, @1), $2, @$);
|
||
}
|
||
| tkNamespace ident_or_keyword_pointseparator_list tkSemiColon optional_head_compiler_directives
|
||
{
|
||
$$ = NewNamespaceHeading(new ident($1.text, @1), $2 as ident_list, @$);
|
||
}
|
||
;
|
||
|
||
unit_key_word
|
||
: tkUnit
|
||
{ $$ = $1; }
|
||
| tkLibrary
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
unit_name
|
||
: identifier
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
interface_part
|
||
: tkInterface uses_clause interface_decl_sect_list
|
||
{
|
||
$$ = new interface_node($3 as declarations, $2 as uses_list, null, LexLocation.MergeAll(@1,@2,@3));
|
||
}
|
||
;
|
||
|
||
implementation_part
|
||
: tkImplementation uses_clause decl_sect_list
|
||
{
|
||
$$ = new implementation_node($2 as uses_list, $3 as declarations, null, LexLocation.MergeAll(@1,@2,@3));
|
||
}
|
||
;
|
||
|
||
abc_interface_part
|
||
: uses_clause decl_sect_list
|
||
{
|
||
$$ = new interface_node($2 as declarations, $1 as uses_list, null, null);
|
||
}
|
||
;
|
||
|
||
initialization_part
|
||
: tkEnd
|
||
{
|
||
$$ = new initfinal_part();
|
||
$$.source_context = @$;
|
||
}
|
||
| tkInitialization stmt_list tkEnd
|
||
{
|
||
$$ = new initfinal_part($1, $2 as statement_list, $3, null, null, @$);
|
||
}
|
||
| tkInitialization stmt_list tkFinalization stmt_list tkEnd
|
||
{
|
||
$$ = new initfinal_part($1, $2 as statement_list, $3, $4 as statement_list, $5, @$);
|
||
}
|
||
| tkBegin stmt_list tkEnd
|
||
{
|
||
$$ = new initfinal_part($1, $2 as statement_list, $3, null, null, @$);
|
||
}
|
||
;
|
||
|
||
interface_decl_sect_list
|
||
: int_decl_sect_list1
|
||
{
|
||
if (($1 as declarations).Count > 0)
|
||
$$ = $1;
|
||
else
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
int_decl_sect_list1
|
||
:
|
||
{
|
||
$$ = new declarations();
|
||
if (GlobalDecls==null)
|
||
GlobalDecls = $$ as declarations;
|
||
}
|
||
| int_decl_sect_list1 int_decl_sect
|
||
{
|
||
$$ = ($1 as declarations).Add($2 as declaration, @$);
|
||
}
|
||
;
|
||
|
||
decl_sect_list
|
||
: decl_sect_list1
|
||
{
|
||
if (($1 as declarations).Count > 0)
|
||
$$ = $1;
|
||
else
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
decl_sect_list_proc_func_only
|
||
:
|
||
{
|
||
$$ = new declarations();
|
||
if (GlobalDecls==null)
|
||
GlobalDecls = $$ as declarations;
|
||
}
|
||
| decl_sect_list_proc_func_only attribute_declarations proc_func_decl_noclass
|
||
{
|
||
var dcl = $1 as declarations;
|
||
($3 as procedure_definition).AssignAttrList($2 as attribute_list);
|
||
if (dcl.Count == 0)
|
||
$$ = dcl.Add($3 as declaration, @3);
|
||
else
|
||
{
|
||
var sc = dcl.source_context;
|
||
sc = sc.Merge($3.source_context);
|
||
$$ = dcl.Add($3 as declaration, @3);
|
||
$$.source_context = sc;
|
||
}
|
||
}
|
||
;
|
||
|
||
decl_sect_list1
|
||
:
|
||
{
|
||
$$ = new declarations();
|
||
if (GlobalDecls==null)
|
||
GlobalDecls = $$ as declarations;
|
||
}
|
||
| decl_sect_list1 decl_sect
|
||
{
|
||
$$ = ($1 as declarations).Add($2 as declaration, @$);
|
||
}
|
||
;
|
||
|
||
inclass_decl_sect_list
|
||
: inclass_decl_sect_list1
|
||
{
|
||
if (($1 as declarations).Count > 0)
|
||
$$ = $1;
|
||
else
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
inclass_decl_sect_list1
|
||
:
|
||
{
|
||
$$ = new declarations();
|
||
}
|
||
| inclass_decl_sect_list1 abc_decl_sect
|
||
{
|
||
$$ = ($1 as declarations).Add($2 as declaration, @$);
|
||
}
|
||
;
|
||
|
||
int_decl_sect
|
||
: const_decl_sect
|
||
{ $$ = $1; }
|
||
| res_str_decl_sect
|
||
{ $$ = $1; }
|
||
| type_decl_sect
|
||
{ $$ = $1; }
|
||
| var_decl_sect
|
||
{ $$ = $1; }
|
||
| int_proc_header
|
||
{ $$ = $1; }
|
||
| int_func_header
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
decl_sect
|
||
: label_decl_sect
|
||
{ $$ = $1; }
|
||
| const_decl_sect
|
||
{ $$ = $1; }
|
||
| res_str_decl_sect
|
||
{ $$ = $1; }
|
||
| type_decl_sect
|
||
{ $$ = $1; }
|
||
| var_decl_sect
|
||
{ $$ = $1; }
|
||
| proc_func_constr_destr_decl_with_attr
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
/* SSM 2.1.13 упрощение грамматики */
|
||
proc_func_constr_destr_decl
|
||
: proc_func_decl
|
||
{ $$ = $1; }
|
||
| constr_destr_decl
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
proc_func_constr_destr_decl_with_attr
|
||
: attribute_declarations proc_func_constr_destr_decl
|
||
{
|
||
($2 as procedure_definition).AssignAttrList($1 as attribute_list);
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
abc_decl_sect
|
||
: label_decl_sect
|
||
{ $$ = $1; }
|
||
| const_decl_sect
|
||
{ $$ = $1; }
|
||
| res_str_decl_sect
|
||
{ $$ = $1; }
|
||
| type_decl_sect
|
||
{ $$ = $1; }
|
||
| var_decl_sect
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
int_proc_header
|
||
: attribute_declarations proc_header
|
||
{
|
||
$$ = $2;
|
||
($$ as procedure_header).attributes = $1 as attribute_list;
|
||
}
|
||
| attribute_declarations proc_header tkForward tkSemiColon
|
||
{
|
||
$$ = NewProcedureHeader($1 as attribute_list, $2 as procedure_header, $3 as procedure_attribute, @$);
|
||
}
|
||
;
|
||
|
||
int_func_header
|
||
: attribute_declarations func_header
|
||
{
|
||
$$ = $2;
|
||
($$ as procedure_header).attributes = $1 as attribute_list;
|
||
}
|
||
| attribute_declarations func_header tkForward tkSemiColon
|
||
{
|
||
$$ = NewProcedureHeader($1 as attribute_list, $2 as procedure_header, $3 as procedure_attribute, @$);
|
||
}
|
||
;
|
||
|
||
label_decl_sect
|
||
: tkLabel label_list tkSemiColon
|
||
{
|
||
$$ = new label_definitions($2 as ident_list, @$);
|
||
}
|
||
;
|
||
|
||
label_list
|
||
: label_name
|
||
{
|
||
$$ = new ident_list($1, @$);
|
||
}
|
||
| label_list tkComma label_name
|
||
{
|
||
$$ = ($1 as ident_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
label_name
|
||
: tkInteger
|
||
{
|
||
$$ = new ident($1.ToString(), @$);
|
||
}
|
||
| identifier
|
||
{
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
const_decl_sect
|
||
: tkConst const_decl
|
||
{
|
||
$$ = new consts_definitions_list($2 as const_definition, @$);
|
||
}
|
||
| const_decl_sect const_decl
|
||
{
|
||
$$ = ($1 as consts_definitions_list).Add($2 as const_definition, @$);
|
||
}
|
||
;
|
||
|
||
res_str_decl_sect
|
||
: tkResourceString const_decl
|
||
{
|
||
$$ = $2;
|
||
}
|
||
| res_str_decl_sect const_decl
|
||
{
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
type_decl_sect
|
||
: tkType type_decl
|
||
{
|
||
$$ = new type_declarations($2 as type_declaration, @$);
|
||
}
|
||
| type_decl_sect type_decl
|
||
{
|
||
$$ = ($1 as type_declarations).Add($2 as type_declaration, @$);
|
||
}
|
||
;
|
||
|
||
var_decl_with_assign_var_tuple
|
||
: var_decl
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1 tkSemiColon
|
||
{
|
||
($4 as ident_list).Insert(0,$2);
|
||
$4.source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5);
|
||
$$ = new var_tuple_def_statement($4 as ident_list, $7, @$);
|
||
}
|
||
;
|
||
|
||
var_decl_sect
|
||
: tkVar var_decl_with_assign_var_tuple
|
||
{
|
||
$$ = new variable_definitions($2 as var_def_statement, @$);
|
||
}
|
||
| tkEvent var_decl_with_assign_var_tuple
|
||
{
|
||
$$ = new variable_definitions($2 as var_def_statement, @$);
|
||
($2 as var_def_statement).is_event = true;
|
||
}
|
||
| var_decl_sect var_decl_with_assign_var_tuple
|
||
{
|
||
$$ = ($1 as variable_definitions).Add($2 as var_def_statement, @$);
|
||
}
|
||
/*| tkVar tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr_l1 tkSemiColon
|
||
{
|
||
($5 as ident_list).Insert(0,$3);
|
||
$5.source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5,@6);
|
||
$$ = new assign_var_tuple($5 as ident_list, $8, @$);
|
||
}*/
|
||
;
|
||
|
||
const_decl
|
||
: only_const_decl tkSemiColon
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
only_const_decl
|
||
: const_name tkEqual init_const_expr
|
||
{
|
||
$$ = new simple_const_definition($1, $3, @$);
|
||
}
|
||
| const_name tkColon type_ref tkEqual typed_const
|
||
{
|
||
$$ = new typed_const_definition($1, $5, $3, @$);
|
||
}
|
||
;
|
||
|
||
init_const_expr
|
||
: const_expr
|
||
{ $$ = $1; }
|
||
| array_const
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
const_name
|
||
: identifier
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
//expr_l1_list
|
||
// : expr_l1
|
||
// {
|
||
// $$ = new expression_list($1, @$);
|
||
// }
|
||
// | expr_l1_list tkComma expr_l1
|
||
// {
|
||
// $$ = ($1 as expression_list).Add($3, @$);
|
||
// }
|
||
// ;
|
||
|
||
const_relop_expr
|
||
: const_simple_expr
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| const_relop_expr const_relop const_simple_expr
|
||
{
|
||
$$ = new bin_expr($1, $3, $2.type, @$);
|
||
}
|
||
;
|
||
|
||
const_expr
|
||
: const_relop_expr
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| question_constexpr
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| const_expr tkDoubleQuestion const_relop_expr
|
||
{ $$ = new double_question_node($1 as expression, $3 as expression, @$);}
|
||
;
|
||
|
||
question_constexpr
|
||
: const_expr tkQuestion const_expr tkColon const_expr
|
||
{ $$ = new question_colon_expression($1, $3, $5, @$); }
|
||
;
|
||
|
||
const_relop
|
||
: tkEqual
|
||
{ $$ = $1; }
|
||
| tkNotEqual
|
||
{ $$ = $1; }
|
||
| tkLower
|
||
{ $$ = $1; }
|
||
| tkGreater
|
||
{ $$ = $1; }
|
||
| tkLowerEqual
|
||
{ $$ = $1; }
|
||
| tkGreaterEqual
|
||
{ $$ = $1; }
|
||
| tkIn
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
const_simple_expr
|
||
: const_term
|
||
{ $$ = $1; }
|
||
| const_simple_expr const_addop const_term
|
||
{ $$ = new bin_expr($1, $3, $2.type, @$); }
|
||
;
|
||
|
||
const_addop
|
||
: tkPlus
|
||
{ $$ = $1; }
|
||
| tkMinus
|
||
{ $$ = $1; }
|
||
| tkOr
|
||
{ $$ = $1; }
|
||
| tkXor
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
as_is_constexpr
|
||
: const_term typecast_op simple_or_template_type_reference
|
||
{
|
||
$$ = NewAsIsConstexpr($1, (op_typecast)$2, $3, @$);
|
||
}
|
||
;
|
||
|
||
power_constexpr
|
||
: const_factor_without_unary_op tkStarStar const_factor
|
||
{ $$ = new bin_expr($1, $3, $2.type, @$); }
|
||
| const_factor_without_unary_op tkStarStar power_constexpr
|
||
{ $$ = new bin_expr($1,$3,($2).type, @$); }
|
||
| sign power_constexpr
|
||
{ $$ = new un_expr($2, $1.type, @$); }
|
||
;
|
||
|
||
const_term
|
||
: const_factor
|
||
{ $$ = $1; }
|
||
| as_is_constexpr
|
||
{ $$ = $1; }
|
||
| power_constexpr
|
||
{ $$ = $1; }
|
||
| const_term const_mulop const_factor
|
||
{ $$ = new bin_expr($1, $3, $2.type, @$); }
|
||
| const_term const_mulop power_constexpr
|
||
{ $$ = new bin_expr($1,$3,($2).type, @$); }
|
||
;
|
||
|
||
const_mulop
|
||
: tkStar
|
||
{ $$ = $1; }
|
||
| tkSlash
|
||
{ $$ = $1; }
|
||
| tkDiv
|
||
{ $$ = $1; }
|
||
| tkMod
|
||
{ $$ = $1; }
|
||
| tkShl
|
||
{ $$ = $1; }
|
||
| tkShr
|
||
{ $$ = $1; }
|
||
| tkAnd
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
const_factor_without_unary_op
|
||
: const_variable
|
||
{ $$ = $1; }
|
||
| tkRoundOpen const_expr tkRoundClose
|
||
{ $$ = $2; }
|
||
;
|
||
|
||
const_factor
|
||
: const_variable
|
||
{ $$ = $1; }
|
||
| const_set
|
||
{ $$ = $1; }
|
||
| tkNil
|
||
{
|
||
$$ = new nil_const();
|
||
$$.source_context = @$;
|
||
}
|
||
| tkAddressOf const_factor
|
||
{
|
||
$$ = new get_address($2 as addressed_value, @$);
|
||
}
|
||
| tkRoundOpen const_expr tkRoundClose
|
||
{
|
||
$$ = new bracket_expr($2, @$);
|
||
}
|
||
| tkNot const_factor
|
||
{
|
||
$$ = new un_expr($2, $1.type, @$);
|
||
}
|
||
| sign const_factor
|
||
{
|
||
// ручнаЯ коррекциЯ целых констант
|
||
if ($1.type == Operators.Minus)
|
||
{
|
||
var i64 = $2 as int64_const;
|
||
if (i64 != null && i64.val == (Int64)Int32.MaxValue + 1)
|
||
{
|
||
$$ = new int32_const(Int32.MinValue,@$);
|
||
break;
|
||
}
|
||
var ui64 = $2 as uint64_const;
|
||
if (ui64 != null && ui64.val == (UInt64)Int64.MaxValue + 1)
|
||
{
|
||
$$ = new int64_const(Int64.MinValue,@$);
|
||
break;
|
||
}
|
||
if (ui64 != null && ui64.val > (UInt64)Int64.MaxValue + 1)
|
||
{
|
||
parserTools.AddErrorFromResource("BAD_INT2",@$);
|
||
break;
|
||
}
|
||
// можно сделать вычисление константы с вмонтированным минусом
|
||
}
|
||
$$ = new un_expr($2, $1.type, @$);
|
||
}
|
||
| new_expr
|
||
{ $$ = $1; }
|
||
| default_expr
|
||
{ $$ = $1; }
|
||
// | tkDeref const_factor
|
||
// {
|
||
// $$ = new roof_dereference($2 as addressed_value, @$);
|
||
// }
|
||
;
|
||
|
||
const_set
|
||
: tkSquareOpen elem_list tkSquareClose
|
||
{
|
||
$$ = new pascal_set_constant($2 as expression_list, @$);
|
||
}
|
||
| tkVertParen elem_list tkVertParen
|
||
{
|
||
$$ = new array_const_new($2 as expression_list, @$);
|
||
}
|
||
;
|
||
|
||
sign
|
||
: tkPlus
|
||
{ $$ = $1; }
|
||
| tkMinus
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
const_variable
|
||
: identifier
|
||
{ $$ = $1; }
|
||
| literal // SSM 02.10.18 для '123'.Length при инициализации констант
|
||
{ $$ = $1; }
|
||
| unsigned_number
|
||
{ $$ = $1; }
|
||
| tkInherited identifier
|
||
{
|
||
$$ = new inherited_ident($2.name, @$);
|
||
}
|
||
| sizeof_expr
|
||
{ $$ = $1; }
|
||
| typeof_expr
|
||
{ $$ = $1; }
|
||
/* | tkRoundOpen const_expr tkRoundClose
|
||
{
|
||
if (!parserTools.buildTreeForFormatter)
|
||
{
|
||
$2.source_context = @$;
|
||
$$ = $2;
|
||
}
|
||
else $$ = new bracket_expr($2, @$);
|
||
}*/
|
||
| const_variable const_variable_2
|
||
{
|
||
$$ = NewConstVariable($1, $2, @$);
|
||
}
|
||
| const_variable tkAmpersend template_type_params
|
||
{
|
||
$$ = new ident_with_templateparams($1 as addressed_value, $3 as template_param_list, @$);
|
||
}
|
||
| const_variable tkSquareOpen format_const_expr tkSquareClose
|
||
{
|
||
var fe = $3 as format_expr;
|
||
if (!parserTools.buildTreeForFormatter)
|
||
{
|
||
if (fe.expr == null)
|
||
fe.expr = new int32_const(int.MaxValue,@3);
|
||
if (fe.format1 == null)
|
||
fe.format1 = new int32_const(int.MaxValue,@3);
|
||
}
|
||
$$ = new slice_expr($1 as addressed_value,fe.expr,fe.format1,fe.format2,@$);
|
||
}
|
||
;
|
||
|
||
const_variable_2
|
||
: tkPoint identifier_or_keyword
|
||
{
|
||
$$ = new dot_node(null, $2 as addressed_value, @$);
|
||
}
|
||
| tkDeref
|
||
{
|
||
$$ = new roof_dereference();
|
||
$$.source_context = @$;
|
||
}
|
||
| tkRoundOpen optional_const_func_expr_list tkRoundClose
|
||
{
|
||
$$ = new method_call($2 as expression_list, @$);
|
||
}
|
||
| tkSquareOpen const_elem_list tkSquareClose
|
||
{
|
||
$$ = new indexer($2 as expression_list, @$);
|
||
}
|
||
;
|
||
|
||
optional_const_func_expr_list
|
||
: expr_list
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
/*const_expr_list
|
||
: const_expr
|
||
{
|
||
$$ = new expression_list($1, @$);
|
||
}
|
||
| const_expr_list tkComma const_expr
|
||
{
|
||
$$ = ($1 as expression_list).Add($3, @$);
|
||
}
|
||
;*/
|
||
|
||
const_elem_list
|
||
: const_elem_list1
|
||
{ $$ = $1; }
|
||
|
|
||
;
|
||
|
||
const_elem_list1
|
||
: const_elem
|
||
{
|
||
$$ = new expression_list($1, @$);
|
||
}
|
||
| const_elem_list1 tkComma const_elem
|
||
{
|
||
$$ = ($1 as expression_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
const_elem
|
||
: const_expr
|
||
{ $$ = $1; }
|
||
| const_expr tkDotDot const_expr
|
||
{
|
||
$$ = new diapason_expr($1, $3, @$);
|
||
}
|
||
;
|
||
|
||
unsigned_number
|
||
: tkInteger
|
||
{ $$ = $1; }
|
||
| tkHex
|
||
{ $$ = $1; }
|
||
| tkFloat
|
||
{ $$ = $1; }
|
||
| tkBigInteger
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
typed_const
|
||
: const_expr
|
||
{ $$ = $1; }
|
||
| array_const
|
||
{ $$ = $1; }
|
||
| record_const
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
array_const
|
||
: tkRoundOpen typed_const_list tkRoundClose
|
||
{
|
||
$$ = new array_const($2 as expression_list, @$);
|
||
}
|
||
// | tkRoundOpen record_const tkRoundClose
|
||
// { $$ = $2; }
|
||
// | tkRoundOpen array_const tkRoundClose
|
||
// { $$ = $2; }
|
||
;
|
||
|
||
typed_const_list
|
||
:
|
||
| typed_const_list1
|
||
{
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
typed_const_list1
|
||
: typed_const_plus
|
||
{
|
||
$$ = new expression_list($1, @$);
|
||
}
|
||
| typed_const_list1 tkComma typed_const_plus
|
||
{
|
||
$$ = ($1 as expression_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
record_const
|
||
: tkRoundOpen const_field_list tkRoundClose
|
||
{
|
||
$$ = $2;
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
const_field_list
|
||
: const_field_list_1
|
||
{ $$ = $1; }
|
||
| const_field_list_1 tkSemiColon
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
const_field_list_1
|
||
: const_field
|
||
{
|
||
$$ = new record_const($1 as record_const_definition, @$);
|
||
}
|
||
| const_field_list_1 tkSemiColon const_field
|
||
{
|
||
$$ = ($1 as record_const).Add($3 as record_const_definition, @$);
|
||
}
|
||
;
|
||
|
||
const_field
|
||
: const_field_name tkColon typed_const
|
||
{
|
||
$$ = new record_const_definition($1, $3, @$);
|
||
}
|
||
;
|
||
|
||
const_field_name
|
||
: identifier
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
type_decl
|
||
: attribute_declarations simple_type_decl
|
||
{
|
||
($2 as declaration).attributes = $1 as attribute_list;
|
||
$$ = $2;
|
||
$$.source_context = @2;
|
||
}
|
||
;
|
||
|
||
attribute_declarations
|
||
: attribute_declaration
|
||
{
|
||
$$ = new attribute_list($1 as simple_attribute_list, @$);
|
||
}
|
||
| attribute_declarations attribute_declaration
|
||
{
|
||
$$ = ($1 as attribute_list).Add($2 as simple_attribute_list, @$);
|
||
}
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
attribute_declaration
|
||
: tkSquareOpen one_or_some_attribute tkSquareClose
|
||
{ $$ = $2; }
|
||
;
|
||
|
||
one_or_some_attribute
|
||
: one_attribute
|
||
{
|
||
$$ = new simple_attribute_list($1 as attribute, @$);
|
||
}
|
||
| one_or_some_attribute tkComma one_attribute
|
||
{
|
||
$$ = ($1 as simple_attribute_list).Add($3 as attribute, @$);
|
||
}
|
||
;
|
||
|
||
one_attribute
|
||
: attribute_variable
|
||
{ $$ = $1; }
|
||
| identifier tkColon attribute_variable
|
||
{
|
||
($3 as attribute).qualifier = $1;
|
||
$$ = $3;
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
simple_type_decl
|
||
: type_decl_identifier tkEqual type_decl_type tkSemiColon
|
||
{
|
||
$$ = new type_declaration($1, $3, @$);
|
||
}
|
||
| template_identifier_with_equal type_decl_type tkSemiColon
|
||
{
|
||
$$ = new type_declaration($1, $2, @$);
|
||
}
|
||
;
|
||
|
||
type_decl_identifier
|
||
: identifier
|
||
{ $$ = $1; }
|
||
| identifier template_arguments
|
||
{
|
||
$$ = new template_type_name($1.name, $2 as ident_list, @$);
|
||
}
|
||
;
|
||
|
||
template_identifier_with_equal
|
||
: identifier tkLower ident_list tkGreaterEqual
|
||
{
|
||
$$ = new template_type_name($1.name, $3 as ident_list, @$);
|
||
}
|
||
;
|
||
|
||
type_decl_type
|
||
: type_ref
|
||
{ $$ = $1; }
|
||
| object_type
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
simple_type_question
|
||
: simple_type tkQuestion
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
{
|
||
$$ = $1;
|
||
}
|
||
else
|
||
{
|
||
var l = new List<ident>();
|
||
l.Add(new ident("System"));
|
||
l.Add(new ident("Nullable"));
|
||
$$ = new template_type_reference(new named_type_reference(l), new template_param_list($1), @$);
|
||
}
|
||
}
|
||
| template_type tkQuestion
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
{
|
||
$$ = $1;
|
||
}
|
||
else
|
||
{
|
||
var l = new List<ident>();
|
||
l.Add(new ident("System"));
|
||
l.Add(new ident("Nullable"));
|
||
$$ = new template_type_reference(new named_type_reference(l), new template_param_list($1), @$);
|
||
}
|
||
}
|
||
;
|
||
|
||
type_ref
|
||
: simple_type
|
||
{ $$ = $1; }
|
||
| simple_type_question
|
||
{ $$ = $1; }
|
||
| string_type
|
||
{ $$ = $1; }
|
||
| pointer_type
|
||
{ $$ = $1; }
|
||
| structured_type
|
||
{ $$ = $1; }
|
||
| procedural_type
|
||
{ $$ = $1; }
|
||
| template_type
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
template_type
|
||
: simple_type_identifier template_type_params
|
||
{
|
||
$$ = new template_type_reference($1 as named_type_reference, $2 as template_param_list, @$);
|
||
}
|
||
;
|
||
|
||
template_type_params
|
||
: tkLower template_param_list tkGreater
|
||
{
|
||
$$ = $2;
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
template_type_empty_params
|
||
: tkNotEqual
|
||
{
|
||
var ntr = new named_type_reference(new ident(""), @$);
|
||
|
||
$$ = new template_param_list(ntr, @$);
|
||
ntr.source_context = new SourceContext($$.source_context.end_position.line_num, $$.source_context.end_position.column_num, $$.source_context.begin_position.line_num, $$.source_context.begin_position.column_num);
|
||
}
|
||
| tkLower template_empty_param_list tkGreater
|
||
{
|
||
$$ = $2;
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
template_param_list
|
||
: template_param
|
||
{
|
||
$$ = new template_param_list($1, @$);
|
||
}
|
||
| template_param_list tkComma template_param
|
||
{
|
||
$$ = ($1 as template_param_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
template_empty_param_list
|
||
: template_empty_param
|
||
{
|
||
$$ = new template_param_list($1, @$);
|
||
}
|
||
| template_empty_param_list tkComma template_empty_param
|
||
{
|
||
$$ = ($1 as template_param_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
template_empty_param
|
||
:
|
||
{
|
||
$$ = new named_type_reference(new ident(""), @$);
|
||
}
|
||
;
|
||
|
||
template_param
|
||
: simple_type
|
||
{ $$ = $1; }
|
||
| simple_type tkQuestion
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
{
|
||
$$ = $1;
|
||
}
|
||
else
|
||
{
|
||
var l = new List<ident>();
|
||
l.Add(new ident("System"));
|
||
l.Add(new ident("Nullable"));
|
||
$$ = new template_type_reference(new named_type_reference(l), new template_param_list($1), @$);
|
||
}
|
||
}
|
||
| structured_type
|
||
{ $$ = $1; }
|
||
| procedural_type
|
||
{ $$ = $1; }
|
||
| template_type
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
simple_type
|
||
: range_expr
|
||
{
|
||
$$ = parserTools.ConvertDotNodeOrIdentToNamedTypeReference($1);
|
||
}
|
||
| range_expr tkDotDot range_expr
|
||
{
|
||
$$ = new diapason($1, $3, @$);
|
||
}
|
||
| tkRoundOpen enumeration_id_list tkRoundClose
|
||
{
|
||
$$ = new enum_type_definition($2 as enumerator_list, @$);
|
||
}
|
||
;
|
||
|
||
range_expr
|
||
: range_term
|
||
{ $$ = $1; }
|
||
| range_expr const_addop range_term
|
||
{
|
||
$$ = new bin_expr($1, $3, $2.type, @$);
|
||
}
|
||
;
|
||
|
||
range_term
|
||
: range_factor
|
||
{ $$ = $1; }
|
||
| range_term const_mulop range_factor
|
||
{
|
||
$$ = new bin_expr($1, $3, $2.type, @$);
|
||
}
|
||
;
|
||
|
||
range_factor
|
||
: simple_type_identifier
|
||
{
|
||
$$ = parserTools.ConvertNamedTypeReferenceToDotNodeOrIdent($1 as named_type_reference);
|
||
}
|
||
| unsigned_number
|
||
{ $$ = $1; }
|
||
| sign range_factor
|
||
{
|
||
$$ = new un_expr($2, $1.type, @$);
|
||
}
|
||
| literal
|
||
{ $$ = $1; }
|
||
| range_factor tkRoundOpen const_elem_list tkRoundClose // f(1)..f(2) - странно - вызовы функций тут вроде запрещены
|
||
{
|
||
$$ = new method_call($1 as addressed_value, $3 as expression_list, @$);
|
||
}
|
||
;
|
||
|
||
simple_type_identifier
|
||
: identifier
|
||
{
|
||
$$ = new named_type_reference($1, @$);
|
||
}
|
||
| simple_type_identifier tkPoint identifier_or_keyword
|
||
{
|
||
$$ = ($1 as named_type_reference).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
enumeration_id_list
|
||
: enumeration_id
|
||
{
|
||
$$ = new enumerator_list($1 as enumerator, @$);
|
||
}
|
||
| enumeration_id_list tkComma enumeration_id
|
||
{
|
||
$$ = ($1 as enumerator_list).Add($3 as enumerator, @$);
|
||
}
|
||
;
|
||
|
||
enumeration_id
|
||
: type_ref
|
||
{
|
||
$$ = new enumerator($1, null, @$);
|
||
}
|
||
| type_ref tkEqual expr
|
||
{
|
||
$$ = new enumerator($1, $3, @$);
|
||
}
|
||
;
|
||
|
||
pointer_type
|
||
: tkDeref fptype
|
||
{
|
||
$$ = new ref_type($2,@$);
|
||
}
|
||
;
|
||
|
||
structured_type
|
||
: array_type
|
||
{ $$ = $1; }
|
||
| record_type
|
||
{ $$ = $1; }
|
||
| set_type
|
||
{ $$ = $1; }
|
||
| file_type
|
||
{ $$ = $1; }
|
||
| sequence_type
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
sequence_type
|
||
: tkSequence tkOf type_ref
|
||
{
|
||
$$ = new sequence_type($3,@$);
|
||
}
|
||
;
|
||
|
||
array_type
|
||
: tkArray tkSquareOpen simple_type_list tkSquareClose tkOf type_ref
|
||
{
|
||
$$ = new array_type($3 as indexers_types, $6, @$);
|
||
}
|
||
| unsized_array_type
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
unsized_array_type
|
||
: tkArray tkOf type_ref
|
||
{
|
||
$$ = new array_type(null, $3, @$);
|
||
}
|
||
;
|
||
|
||
simple_type_list
|
||
: simple_type_or_
|
||
{
|
||
$$ = new indexers_types($1, @$);
|
||
}
|
||
| simple_type_list tkComma simple_type_or_
|
||
{
|
||
$$ = ($1 as indexers_types).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
simple_type_or_
|
||
: simple_type
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
set_type
|
||
: tkSet tkOf type_ref
|
||
{
|
||
$$ = new set_type_definition($3, @$);
|
||
}
|
||
;
|
||
|
||
file_type
|
||
: tkFile tkOf type_ref
|
||
{
|
||
$$ = new file_type($3, @$);
|
||
}
|
||
| tkFile
|
||
{
|
||
$$ = new file_type();
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
string_type
|
||
: tkIdentifier tkSquareOpen const_expr tkSquareClose
|
||
{
|
||
$$ = new string_num_definition($3, $1, @$);
|
||
}
|
||
;
|
||
|
||
procedural_type
|
||
: procedural_type_kind
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
procedural_type_kind
|
||
: proc_type_decl
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
proc_type_decl
|
||
: tkProcedure fp_list
|
||
{
|
||
$$ = new procedure_header($2 as formal_parameters,null,null,false,false,null,null,@$);
|
||
}
|
||
/* | tkFunction fp_list
|
||
{
|
||
$$ = new function_header($2 as formal_parameters, null, null, null, null, @$);
|
||
}*/
|
||
| tkFunction fp_list tkColon fptype
|
||
{
|
||
$$ = new function_header($2 as formal_parameters, null, null, null, $4 as type_definition, @$);
|
||
}
|
||
| simple_type_identifier tkArrow template_param // эти 2 правила нельзя объединять в одно template_param - будет конфликт
|
||
{
|
||
$$ = new modern_proc_type($1,null,$3,@$);
|
||
}
|
||
| template_type tkArrow template_param
|
||
{
|
||
$$ = new modern_proc_type($1,null,$3,@$);
|
||
}
|
||
| tkRoundOpen tkRoundClose tkArrow template_param
|
||
{
|
||
$$ = new modern_proc_type(null,null,$4,@$);
|
||
}
|
||
| tkRoundOpen enumeration_id_list tkRoundClose tkArrow template_param
|
||
{
|
||
$$ = new modern_proc_type(null,$2 as enumerator_list,$5,@$);
|
||
}
|
||
| simple_type_identifier tkArrow tkRoundOpen tkRoundClose // эти 2 правила нельзя объединять в одно template_param - будет конфликт
|
||
{
|
||
$$ = new modern_proc_type($1,null,null,@$);
|
||
}
|
||
| template_type tkArrow tkRoundOpen tkRoundClose
|
||
{
|
||
$$ = new modern_proc_type($1,null,null,@$);
|
||
}
|
||
| tkRoundOpen tkRoundClose tkArrow tkRoundOpen tkRoundClose
|
||
{
|
||
$$ = new modern_proc_type(null,null,null,@$);
|
||
}
|
||
| tkRoundOpen enumeration_id_list tkRoundClose tkArrow tkRoundOpen tkRoundClose
|
||
{
|
||
$$ = new modern_proc_type(null,$2 as enumerator_list,null,@$);
|
||
}
|
||
;
|
||
|
||
object_type
|
||
: class_attributes class_or_interface_keyword optional_base_classes optional_where_section optional_component_list_seq_end
|
||
{
|
||
var cd = NewObjectType((class_attribute)$1, $2, $3 as named_type_reference_list, $4 as where_definition_list, $5 as class_body_list, @$);
|
||
$$ = cd;
|
||
}
|
||
;
|
||
|
||
record_type
|
||
: tkRecord optional_base_classes optional_where_section member_list_section tkEnd
|
||
{
|
||
var nnrt = new class_definition($2 as named_type_reference_list, $4 as class_body_list, class_keyword.Record, null, $3 as where_definition_list, class_attribute.None, false, @$);
|
||
if (/*nnrt.body!=null && nnrt.body.class_def_blocks!=null &&
|
||
nnrt.body.class_def_blocks.Count>0 &&*/
|
||
nnrt.body.class_def_blocks[0].access_mod==null)
|
||
{
|
||
nnrt.body.class_def_blocks[0].access_mod = new access_modifer_node(access_modifer.public_modifer);
|
||
}
|
||
$$ = nnrt;
|
||
}
|
||
;
|
||
|
||
class_attribute
|
||
: tkSealed
|
||
{ $$ = class_attribute.Sealed; }
|
||
| tkPartial
|
||
{ $$ = class_attribute.Partial; }
|
||
| tkAbstract
|
||
{ $$ = class_attribute.Abstract; }
|
||
| tkAuto
|
||
{ $$ = class_attribute.Auto; }
|
||
| tkStatic
|
||
{ $$ = class_attribute.Static; }
|
||
;
|
||
|
||
class_attributes
|
||
:
|
||
{
|
||
$$ = class_attribute.None;
|
||
}
|
||
| class_attributes1
|
||
{
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
class_attributes1
|
||
: class_attribute
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| class_attributes1 class_attribute
|
||
{
|
||
if (((class_attribute)$1 & (class_attribute)$2) == (class_attribute)$2)
|
||
parserTools.AddErrorFromResource("ATTRIBUTE_REDECLARED",@2);
|
||
$$ = ((class_attribute)$1) | ((class_attribute)$2);
|
||
//$$ = $1;
|
||
}
|
||
;
|
||
|
||
class_or_interface_keyword
|
||
: tkClass
|
||
{ $$ = $1; }
|
||
| tkInterface
|
||
{ $$ = $1; }
|
||
| tkTemplate
|
||
{
|
||
$$ = NewClassOrInterfaceKeyword($1);
|
||
}
|
||
| tkTemplate tkClass
|
||
{
|
||
$$ = NewClassOrInterfaceKeyword($1, "c", @$);
|
||
}
|
||
| tkTemplate tkRecord
|
||
{
|
||
$$ = NewClassOrInterfaceKeyword($1, "r", @$);
|
||
}
|
||
| tkTemplate tkInterface
|
||
{
|
||
$$ = NewClassOrInterfaceKeyword($1, "i", @$);
|
||
}
|
||
;
|
||
|
||
optional_component_list_seq_end
|
||
:
|
||
{ $$ = null; }
|
||
| member_list_section tkEnd
|
||
{
|
||
$$ = $1;
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
optional_base_classes
|
||
:
|
||
| tkRoundOpen base_classes_names_list tkRoundClose
|
||
{ $$ = $2; }
|
||
;
|
||
|
||
base_classes_names_list
|
||
: base_class_name
|
||
{
|
||
$$ = new named_type_reference_list($1 as named_type_reference, @$);
|
||
}
|
||
| base_classes_names_list tkComma base_class_name
|
||
{
|
||
$$ = ($1 as named_type_reference_list).Add($3 as named_type_reference, @$);
|
||
}
|
||
;
|
||
|
||
base_class_name
|
||
: simple_type_identifier
|
||
{ $$ = $1; }
|
||
| template_type
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
template_arguments
|
||
: tkLower ident_list tkGreater
|
||
{
|
||
$$ = $2;
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
optional_where_section
|
||
:
|
||
{ $$ = null; }
|
||
| where_part_list
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
where_part_list
|
||
: where_part
|
||
{
|
||
$$ = new where_definition_list($1 as where_definition, @$);
|
||
}
|
||
| where_part_list where_part
|
||
{
|
||
$$ = ($1 as where_definition_list).Add($2 as where_definition, @$);
|
||
}
|
||
;
|
||
|
||
where_part
|
||
: tkWhere ident_list tkColon type_ref_and_secific_list tkSemiColon
|
||
{
|
||
$$ = new where_definition($2 as ident_list, $4 as where_type_specificator_list, @$);
|
||
}
|
||
;
|
||
|
||
type_ref_and_secific_list
|
||
: type_ref_or_secific
|
||
{
|
||
$$ = new where_type_specificator_list($1, @$);
|
||
}
|
||
| type_ref_and_secific_list tkComma type_ref_or_secific
|
||
{
|
||
$$ = ($1 as where_type_specificator_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
type_ref_or_secific
|
||
: type_ref
|
||
{ $$ = $1; }
|
||
| tkClass
|
||
{
|
||
$$ = new declaration_specificator(DeclarationSpecificator.WhereDefClass, $1.text, @$);
|
||
}
|
||
| tkRecord
|
||
{
|
||
$$ = new declaration_specificator(DeclarationSpecificator.WhereDefValueType, $1.text, @$);
|
||
}
|
||
| tkConstructor
|
||
{
|
||
$$ = new declaration_specificator(DeclarationSpecificator.WhereDefConstructor, $1.text, @$);
|
||
}
|
||
;
|
||
|
||
member_list_section
|
||
: member_list
|
||
{
|
||
$$ = new class_body_list($1 as class_members, @$);
|
||
}
|
||
| member_list_section ot_visibility_specifier member_list
|
||
{
|
||
($3 as class_members).access_mod = $2 as access_modifer_node;
|
||
($1 as class_body_list).Add($3 as class_members,@$);
|
||
|
||
if (($1 as class_body_list).class_def_blocks[0].Count == 0)
|
||
($1 as class_body_list).class_def_blocks.RemoveAt(0);
|
||
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
ot_visibility_specifier
|
||
: tkInternal
|
||
{ $$ = new access_modifer_node(access_modifer.internal_modifer, @$); }
|
||
| tkPublic
|
||
{ $$ = new access_modifer_node(access_modifer.public_modifer, @$); }
|
||
| tkProtected
|
||
{ $$ = new access_modifer_node(access_modifer.protected_modifer, @$); }
|
||
| tkPrivate
|
||
{ $$ = new access_modifer_node(access_modifer.private_modifer, @$); }
|
||
;
|
||
|
||
member_list
|
||
:
|
||
{ $$ = new class_members(); }
|
||
| field_or_const_definition_list optional_semicolon
|
||
{ $$ = $1; }
|
||
| method_decl_list
|
||
{ $$ = $1; }
|
||
| field_or_const_definition_list tkSemiColon method_decl_list
|
||
{
|
||
($1 as class_members).members.AddRange(($3 as class_members).members);
|
||
($1 as class_members).source_context = @$;
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
ident_list
|
||
: identifier
|
||
{
|
||
$$ = new ident_list($1, @$);
|
||
}
|
||
| ident_list tkComma identifier
|
||
{
|
||
$$ = ($1 as ident_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
optional_semicolon
|
||
:
|
||
{ $$ = null; }
|
||
| tkSemiColon
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
field_or_const_definition_list
|
||
: field_or_const_definition
|
||
{
|
||
$$ = new class_members($1 as declaration, @$);
|
||
}
|
||
| field_or_const_definition_list tkSemiColon field_or_const_definition
|
||
{
|
||
$$ = ($1 as class_members).Add($3 as declaration, @$);
|
||
}
|
||
;
|
||
|
||
field_or_const_definition
|
||
: attribute_declarations simple_field_or_const_definition
|
||
{
|
||
($2 as declaration).attributes = $1 as attribute_list;
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
method_decl_list
|
||
: method_or_property_decl
|
||
{
|
||
$$ = new class_members($1 as declaration, @$);
|
||
}
|
||
| method_decl_list method_or_property_decl
|
||
{
|
||
$$ = ($1 as class_members).Add($2 as declaration, @$);
|
||
}
|
||
;
|
||
|
||
method_or_property_decl
|
||
: method_decl_withattr
|
||
{ $$ = $1; }
|
||
| property_definition
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
simple_field_or_const_definition
|
||
: tkConst only_const_decl
|
||
{
|
||
$$ = $2;
|
||
$$.source_context = @$;
|
||
}
|
||
| field_definition
|
||
{ $$ = $1; }
|
||
| class_or_static field_definition
|
||
{
|
||
($2 as var_def_statement).var_attr = definition_attribute.Static;
|
||
($2 as var_def_statement).source_context = @$;
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
class_or_static
|
||
: tkStatic
|
||
{ $$ = $1; }
|
||
| tkClass
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
field_definition
|
||
: var_decl_part
|
||
{ $$ = $1; }
|
||
| tkEvent ident_list tkColon type_ref
|
||
{
|
||
$$ = new var_def_statement($2 as ident_list, $4, null, definition_attribute.None, true, @$);
|
||
}
|
||
;
|
||
|
||
method_decl_withattr
|
||
: attribute_declarations method_header
|
||
{
|
||
($2 as declaration).attributes = $1 as attribute_list;
|
||
$$ = $2;
|
||
}
|
||
| attribute_declarations method_decl
|
||
{
|
||
($2 as declaration).attributes = $1 as attribute_list;
|
||
if ($2 is procedure_definition && ($2 as procedure_definition).proc_header != null)
|
||
($2 as procedure_definition).proc_header.attributes = $1 as attribute_list;
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
method_decl
|
||
: inclass_proc_func_decl
|
||
{ $$ = $1; }
|
||
| inclass_constr_destr_decl
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
method_header
|
||
: class_or_static method_procfunc_header
|
||
{
|
||
($2 as procedure_header).class_keyword = true;
|
||
$$ = $2;
|
||
}
|
||
| method_procfunc_header
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| tkAsync class_or_static method_procfunc_header
|
||
{
|
||
($3 as procedure_header).class_keyword = true;
|
||
($3 as procedure_header).IsAsync = true;
|
||
$$ = $3;
|
||
}
|
||
| tkAsync method_procfunc_header
|
||
{
|
||
($2 as procedure_header).IsAsync = true;
|
||
$$ = $2;
|
||
}
|
||
| constr_destr_header
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
method_procfunc_header
|
||
: proc_func_header
|
||
{
|
||
$$ = NewProcfuncHeading($1 as procedure_header);
|
||
}
|
||
;
|
||
|
||
proc_func_header
|
||
: proc_header
|
||
{ $$ = $1; }
|
||
| func_header
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
constr_destr_header
|
||
: tkConstructor optional_proc_name fp_list optional_method_modificators
|
||
{
|
||
$$ = new constructor(null,$3 as formal_parameters,$4 as procedure_attributes_list,$2 as method_name,false,false,null,null,@$);
|
||
}
|
||
| class_or_static tkConstructor optional_proc_name fp_list optional_method_modificators
|
||
{
|
||
$$ = new constructor(null,$4 as formal_parameters,$5 as procedure_attributes_list,$3 as method_name,false,true,null,null,@$);
|
||
}
|
||
| tkDestructor optional_proc_name fp_list optional_method_modificators
|
||
{
|
||
$$ = new destructor(null,$3 as formal_parameters,$4 as procedure_attributes_list,$2 as method_name, false,false,null,null,@$);
|
||
}
|
||
;
|
||
|
||
optional_proc_name
|
||
: proc_name
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
property_definition
|
||
: attribute_declarations simple_property_definition
|
||
{
|
||
$$ = NewPropertyDefinition($1 as attribute_list, $2 as declaration, @2);
|
||
}
|
||
;
|
||
|
||
simple_property_definition
|
||
: tkProperty func_name property_interface property_specifiers tkSemiColon array_defaultproperty
|
||
{
|
||
$$ = NewSimplePropertyDefinition($2 as method_name, $3 as property_interface, $4 as property_accessors, proc_attribute.attr_none, $6 as property_array_default, @$);
|
||
}
|
||
| tkProperty func_name property_interface property_specifiers tkSemiColon property_modificator tkSemiColon array_defaultproperty
|
||
{
|
||
proc_attribute pa = proc_attribute.attr_none;
|
||
if ($6.name.ToLower() == "virtual")
|
||
pa = proc_attribute.attr_virtual;
|
||
else if ($6.name.ToLower() == "override")
|
||
pa = proc_attribute.attr_override;
|
||
else if ($6.name.ToLower() == "abstract")
|
||
pa = proc_attribute.attr_abstract;
|
||
$$ = NewSimplePropertyDefinition($2 as method_name, $3 as property_interface, $4 as property_accessors, pa, $8 as property_array_default, @$);
|
||
}
|
||
| class_or_static tkProperty func_name property_interface property_specifiers tkSemiColon array_defaultproperty
|
||
{
|
||
$$ = NewSimplePropertyDefinition($3 as method_name, $4 as property_interface, $5 as property_accessors, proc_attribute.attr_none, $7 as property_array_default, @$);
|
||
($$ as simple_property).attr = definition_attribute.Static;
|
||
}
|
||
| class_or_static tkProperty func_name property_interface property_specifiers tkSemiColon property_modificator tkSemiColon array_defaultproperty
|
||
{
|
||
parserTools.AddErrorFromResource("STATIC_PROPERTIES_CANNOT_HAVE_ATTRBUTE_{0}",@7,$7.name);
|
||
}
|
||
| tkAuto tkProperty func_name property_interface optional_property_initialization tkSemiColon
|
||
{
|
||
$$ = NewSimplePropertyDefinition($3 as method_name, $4 as property_interface, null, proc_attribute.attr_none, null, @$);
|
||
($$ as simple_property).is_auto = true;
|
||
($$ as simple_property).initial_value = $5;
|
||
}
|
||
| class_or_static tkAuto tkProperty func_name property_interface optional_property_initialization tkSemiColon
|
||
{
|
||
$$ = NewSimplePropertyDefinition($4 as method_name, $5 as property_interface, null, proc_attribute.attr_none, null, @$);
|
||
($$ as simple_property).is_auto = true;
|
||
($$ as simple_property).attr = definition_attribute.Static;
|
||
($$ as simple_property).initial_value = $6;
|
||
}
|
||
;
|
||
|
||
optional_property_initialization
|
||
: tkAssign expr { $$ = $2; }
|
||
| { $$ = null; }
|
||
;
|
||
|
||
array_defaultproperty
|
||
:
|
||
{ $$ = null; }
|
||
| tkDefault tkSemiColon
|
||
{
|
||
$$ = new property_array_default();
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
property_interface
|
||
:/*
|
||
{ $$ = null; }
|
||
|*/ property_parameter_list tkColon fptype
|
||
{
|
||
$$ = new property_interface($1 as property_parameter_list, $3, null, @$);
|
||
}
|
||
;
|
||
|
||
property_parameter_list
|
||
:
|
||
{ $$ = null; }
|
||
| tkSquareOpen parameter_decl_list tkSquareClose
|
||
{ $$ = $2; }
|
||
;
|
||
|
||
parameter_decl_list
|
||
: parameter_decl
|
||
{
|
||
$$ = new property_parameter_list($1 as property_parameter, @$);
|
||
}
|
||
| parameter_decl_list tkSemiColon parameter_decl
|
||
{
|
||
$$ = ($1 as property_parameter_list).Add($3 as property_parameter, @$);
|
||
}
|
||
;
|
||
|
||
parameter_decl
|
||
: ident_list tkColon fptype
|
||
{
|
||
$$ = new property_parameter($1 as ident_list, $3, @$);
|
||
}
|
||
;
|
||
|
||
/*optional_identifier
|
||
: identifier
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
optional_write_expr
|
||
: var_reference
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;*/
|
||
|
||
optional_read_expr
|
||
: expr_with_func_decl_lambda
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
property_specifiers
|
||
:
|
||
| tkRead optional_read_expr write_property_specifiers
|
||
{
|
||
if ($2 == null || $2 is ident) // стандартные свойства
|
||
{
|
||
$$ = NewPropertySpecifiersRead($1, $2 as ident, null, null, $3 as property_accessors, @$);
|
||
}
|
||
else // расширенные свойства
|
||
{
|
||
var id = NewId("#GetGen", @2);
|
||
procedure_definition pr = null;
|
||
if (!parserTools.buildTreeForFormatter)
|
||
pr = CreateAndAddToClassReadFunc($2, id, @2);
|
||
$$ = NewPropertySpecifiersRead($1, id, pr, $2, $3 as property_accessors, @$); // $2 передаётся для форматирования
|
||
}
|
||
}
|
||
| tkWrite unlabelled_stmt read_property_specifiers
|
||
{
|
||
if ($2 is empty_statement)
|
||
{
|
||
|
||
$$ = NewPropertySpecifiersWrite($1, null, null, null, $3 as property_accessors, @$);
|
||
}
|
||
else if ($2 is procedure_call && ($2 as procedure_call).is_ident) // стандартные свойства
|
||
{
|
||
|
||
$$ = NewPropertySpecifiersWrite($1, ($2 as procedure_call).func_name as ident, null, null, $3 as property_accessors, @$); // старые свойства - с идентификатором
|
||
}
|
||
else // расширенные свойства
|
||
{
|
||
var id = NewId("#SetGen", @2);
|
||
procedure_definition pr = null;
|
||
if (!parserTools.buildTreeForFormatter)
|
||
pr = CreateAndAddToClassWriteProc($2 as statement,id,@2);
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, $3 as property_accessors, @$); // $2 передаётся для форматирования
|
||
else $$ = NewPropertySpecifiersWrite($1, id, pr, null, $3 as property_accessors, @$);
|
||
}
|
||
}
|
||
;
|
||
write_property_specifiers
|
||
:
|
||
| tkWrite unlabelled_stmt
|
||
{
|
||
if ($2 is empty_statement)
|
||
{
|
||
|
||
$$ = NewPropertySpecifiersWrite($1, null, null, null, null, @$);
|
||
}
|
||
else if ($2 is procedure_call && ($2 as procedure_call).is_ident)
|
||
{
|
||
$$ = NewPropertySpecifiersWrite($1, ($2 as procedure_call).func_name as ident, null, null, null, @$); // старые свойства - с идентификатором
|
||
}
|
||
else
|
||
{
|
||
var id = NewId("#SetGen", @2);
|
||
procedure_definition pr = null;
|
||
if (!parserTools.buildTreeForFormatter)
|
||
pr = CreateAndAddToClassWriteProc($2 as statement,id,@2);
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = NewPropertySpecifiersWrite($1, id, pr, $2 as statement, null, @$);
|
||
else $$ = NewPropertySpecifiersWrite($1, id, pr, null, null, @$);
|
||
}
|
||
}
|
||
;
|
||
|
||
read_property_specifiers
|
||
:
|
||
| tkRead optional_read_expr
|
||
{
|
||
if ($2 == null || $2 is ident)
|
||
{
|
||
$$ = NewPropertySpecifiersRead($1, $2 as ident, null, null, null, @$);
|
||
}
|
||
else
|
||
{
|
||
var id = NewId("#GetGen", @2);
|
||
procedure_definition pr = null;
|
||
if (!parserTools.buildTreeForFormatter)
|
||
pr = CreateAndAddToClassReadFunc($2,id,@2);
|
||
$$ = NewPropertySpecifiersRead($1, id, pr, $2, null, @$);
|
||
}
|
||
}
|
||
;
|
||
|
||
var_decl
|
||
: var_decl_part tkSemiColon
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
/*var_decl_internal
|
||
: ident_list tkColon type_ref
|
||
{
|
||
$$ = new var_def_statement($1 as ident_list, $3, null, definition_attribute.None, false, @$);
|
||
}
|
||
| ident_list tkAssign expr
|
||
{
|
||
$$ = new var_def_statement($1 as ident_list, null, $3, definition_attribute.None, false, @$);
|
||
}
|
||
| ident_list tkColon type_ref tkAssign expr
|
||
{
|
||
$$ = new var_def_statement($1 as ident_list, $3, $5, definition_attribute.None, false, @$);
|
||
}
|
||
;*/
|
||
|
||
tkAssignOrEqual
|
||
: tkAssign
|
||
| tkEqual
|
||
;
|
||
|
||
var_decl_part
|
||
: ident_list tkColon type_ref
|
||
{
|
||
$$ = new var_def_statement($1 as ident_list, $3, null, definition_attribute.None, false, @$);
|
||
}
|
||
| ident_list tkAssign expr_with_func_decl_lambda
|
||
{
|
||
$$ = new var_def_statement($1 as ident_list, null, $3, definition_attribute.None, false, @$);
|
||
}
|
||
/*| ident_list tkAssign expl_func_decl_lambda
|
||
{
|
||
$$ = new var_def_statement($1 as ident_list, null, $3, definition_attribute.None, false, @$);
|
||
}*/
|
||
| ident_list tkColon type_ref tkAssignOrEqual typed_var_init_expression // typed_const_plus уже давно не константа :) Но сюда не попали Tuples, поскольку они конкурируют с дурацкими старыми инициализаторами массивов
|
||
{
|
||
$$ = new var_def_statement($1 as ident_list, $3, $5, definition_attribute.None, false, @$);
|
||
}
|
||
;
|
||
|
||
typed_var_init_expression
|
||
: typed_const_plus
|
||
{ $$ = $1; }
|
||
| const_simple_expr tkDotDot const_term // SSM 18/01/20
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new diapason_expr($1,$3,@$);
|
||
else
|
||
$$ = new diapason_expr_new($1,$3,@$);
|
||
}
|
||
| expl_func_decl_lambda
|
||
{ $$ = $1; }
|
||
| identifier tkArrow lambda_function_body
|
||
{
|
||
var idList = new ident_list($1, @1);
|
||
var formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new lambda_any_type_node_syntax(), @1), parametr_kind.none, null, @1), @1);
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, new lambda_inferred_type(new lambda_any_type_node_syntax(), @1), $3 as statement_list, @$);
|
||
}
|
||
| tkRoundOpen tkRoundClose lambda_type_ref tkArrow lambda_function_body
|
||
{
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $3, $5 as statement_list, @$);
|
||
}
|
||
| tkRoundOpen typed_const_list tkRoundClose tkArrow lambda_function_body
|
||
{
|
||
var el = $2 as expression_list;
|
||
var cnt = el.Count;
|
||
|
||
var idList = new ident_list();
|
||
idList.source_context = @2;
|
||
|
||
for (int j = 0; j < cnt; j++)
|
||
{
|
||
if (!(el.expressions[j] is ident))
|
||
parserTools.AddErrorFromResource("ONE_TKIDENTIFIER",el.expressions[j].source_context);
|
||
idList.idents.Add(el.expressions[j] as ident);
|
||
}
|
||
|
||
var any = new lambda_inferred_type(new lambda_any_type_node_syntax(), @2);
|
||
|
||
var formalPars = new formal_parameters(new typed_parameters(idList, any, parametr_kind.none, null, @2), @2);
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, any, $5 as statement_list, @$);
|
||
}
|
||
| new_question_expr
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
typed_const_plus
|
||
: typed_const
|
||
{ $$ = $1; }
|
||
/*| new_expr
|
||
{ $$ = $1; }*/
|
||
;
|
||
|
||
constr_destr_decl
|
||
: constr_destr_header block
|
||
{
|
||
$$ = new procedure_definition($1 as procedure_header, $2 as block, @$);
|
||
}
|
||
| tkConstructor optional_proc_name fp_list tkAssign unlabelled_stmt tkSemiColon
|
||
{
|
||
if ($5 is empty_statement)
|
||
parserTools.AddErrorFromResource("EMPTY_STATEMENT_IN_SHORT_PROC_DEFINITION",@6);
|
||
var tmp = new constructor(null,$3 as formal_parameters,new procedure_attributes_list(new List<procedure_attribute>(),@$),$2 as method_name,false,false,null,null,LexLocation.MergeAll(@1,@2,@3));
|
||
$$ = new procedure_definition(tmp as procedure_header, new block(null,new statement_list($5 as statement,@5),@5), @1.Merge(@5));
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new short_func_definition($$ as procedure_definition);
|
||
}
|
||
| class_or_static tkConstructor optional_proc_name fp_list tkAssign unlabelled_stmt tkSemiColon
|
||
{
|
||
if ($6 is empty_statement)
|
||
parserTools.AddErrorFromResource("EMPTY_STATEMENT_IN_SHORT_PROC_DEFINITION",@7);
|
||
var tmp = new constructor(null,$4 as formal_parameters,new procedure_attributes_list(new List<procedure_attribute>(),@$),$3 as method_name,false,true,null,null,LexLocation.MergeAll(@1,@2,@3,@4));
|
||
$$ = new procedure_definition(tmp as procedure_header, new block(null,new statement_list($6 as statement,@6),@6), @1.Merge(@6));
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new short_func_definition($$ as procedure_definition);
|
||
}
|
||
;
|
||
|
||
inclass_constr_destr_decl
|
||
: constr_destr_header inclass_block
|
||
{
|
||
$$ = new procedure_definition($1 as procedure_header, $2 as block, @$);
|
||
}
|
||
| tkConstructor optional_proc_name fp_list tkAssign unlabelled_stmt tkSemiColon
|
||
{
|
||
if ($5 is empty_statement)
|
||
parserTools.AddErrorFromResource("EMPTY_STATEMENT_IN_SHORT_PROC_DEFINITION",@6);
|
||
var tmp = new constructor(null,$3 as formal_parameters,new procedure_attributes_list(new List<procedure_attribute>(),@$),$2 as method_name,false,false,null,null,LexLocation.MergeAll(@1,@2,@3));
|
||
$$ = new procedure_definition(tmp as procedure_header, new block(null,new statement_list($5 as statement,@5),@5), @1.Merge(@5));
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new short_func_definition($$ as procedure_definition);
|
||
}
|
||
| class_or_static tkConstructor optional_proc_name fp_list tkAssign unlabelled_stmt tkSemiColon
|
||
{
|
||
if ($6 is empty_statement)
|
||
parserTools.AddErrorFromResource("EMPTY_STATEMENT_IN_SHORT_PROC_DEFINITION",@7);
|
||
var tmp = new constructor(null,$4 as formal_parameters,new procedure_attributes_list(new List<procedure_attribute>(),@$),$3 as method_name,false,true,null,null,LexLocation.MergeAll(@1,@2,@3,@4));
|
||
$$ = new procedure_definition(tmp as procedure_header, new block(null,new statement_list($6 as statement,@6),@6), @1.Merge(@6));
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new short_func_definition($$ as procedure_definition);
|
||
}
|
||
;
|
||
|
||
proc_func_decl
|
||
: proc_func_decl_noclass
|
||
{ $$ = $1; }
|
||
| class_or_static proc_func_decl_noclass
|
||
{
|
||
($2 as procedure_definition).proc_header.class_keyword = true;
|
||
$$ = $2;
|
||
}
|
||
| tkAsync proc_func_decl_noclass
|
||
{
|
||
($2 as procedure_definition).proc_header.IsAsync = true;
|
||
$$ = $2;
|
||
}
|
||
| tkAsync class_or_static proc_func_decl_noclass
|
||
{
|
||
($3 as procedure_definition).proc_header.IsAsync = true;
|
||
($3 as procedure_definition).proc_header.class_keyword = true;
|
||
$$ = $3;
|
||
}
|
||
| class_or_static tkAsync proc_func_decl_noclass
|
||
{
|
||
($3 as procedure_definition).proc_header.IsAsync = true;
|
||
($3 as procedure_definition).proc_header.class_keyword = true;
|
||
$$ = $3;
|
||
}
|
||
;
|
||
|
||
proc_func_decl_noclass
|
||
: proc_func_header proc_func_external_block
|
||
{
|
||
$$ = new procedure_definition($1 as procedure_header, $2 as proc_block, @$);
|
||
}
|
||
| tkFunction func_name fp_list tkColon fptype optional_method_modificators1 tkAssign expr_l1 tkSemiColon
|
||
{
|
||
$$ = SyntaxTreeBuilder.BuildShortFuncDefinition($3 as formal_parameters, $6 as procedure_attributes_list, $2 as method_name, $5 as type_definition, $8, @1.Merge(@6));
|
||
}
|
||
| tkFunction func_name fp_list optional_method_modificators1 tkAssign expr_l1 tkSemiColon
|
||
{
|
||
if ($6 is dot_question_node)
|
||
parserTools.AddErrorFromResource("DOT_QUECTION_IN_SHORT_FUN",@6);
|
||
|
||
$$ = SyntaxTreeBuilder.BuildShortFuncDefinition($3 as formal_parameters, $4 as procedure_attributes_list, $2 as method_name, null, $6, @1.Merge(@4));
|
||
}
|
||
| tkFunction func_name fp_list tkColon fptype optional_method_modificators1 tkAssign func_decl_lambda tkSemiColon
|
||
{
|
||
$$ = SyntaxTreeBuilder.BuildShortFuncDefinition($3 as formal_parameters, $6 as procedure_attributes_list, $2 as method_name, $5 as type_definition, $8, @1.Merge(@6));
|
||
}
|
||
| tkFunction func_name fp_list optional_method_modificators1 tkAssign func_decl_lambda tkSemiColon
|
||
{
|
||
$$ = SyntaxTreeBuilder.BuildShortFuncDefinition($3 as formal_parameters, $4 as procedure_attributes_list, $2 as method_name, null, $6, @1.Merge(@4));
|
||
}
|
||
| tkProcedure proc_name fp_list optional_method_modificators1 tkAssign unlabelled_stmt tkSemiColon
|
||
{
|
||
if ($6 is empty_statement)
|
||
parserTools.AddErrorFromResource("EMPTY_STATEMENT_IN_SHORT_PROC_DEFINITION",@6);
|
||
$$ = SyntaxTreeBuilder.BuildShortProcDefinition($3 as formal_parameters, $4 as procedure_attributes_list, $2 as method_name, $6 as statement, @1.Merge(@4));
|
||
}
|
||
| proc_func_header tkForward tkSemiColon
|
||
{
|
||
$$ = new procedure_definition($1 as procedure_header, null, @$);
|
||
($$ as procedure_definition).proc_header.proc_attributes.Add((procedure_attribute)$2, $2.source_context);
|
||
}
|
||
//| tkConst const_decl
|
||
// {
|
||
// $$ = new consts_definitions_list($2 as const_definition, @$);
|
||
// }
|
||
;
|
||
|
||
inclass_proc_func_decl
|
||
: inclass_proc_func_decl_noclass
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| tkAsync inclass_proc_func_decl_noclass
|
||
{
|
||
($2 as procedure_definition).proc_header.IsAsync = true;
|
||
$$ = $2;
|
||
}
|
||
| class_or_static inclass_proc_func_decl_noclass
|
||
{
|
||
if (($2 as procedure_definition).proc_header != null)
|
||
{
|
||
($2 as procedure_definition).proc_header.class_keyword = true;
|
||
}
|
||
$$ = $2;
|
||
}
|
||
| tkAsync class_or_static inclass_proc_func_decl_noclass
|
||
{
|
||
if (($3 as procedure_definition).proc_header != null)
|
||
{
|
||
($3 as procedure_definition).proc_header.IsAsync = true;
|
||
($3 as procedure_definition).proc_header.class_keyword = true;
|
||
}
|
||
$$ = $3;
|
||
}
|
||
| class_or_static tkAsync inclass_proc_func_decl_noclass
|
||
{
|
||
if (($3 as procedure_definition).proc_header != null)
|
||
{
|
||
($3 as procedure_definition).proc_header.IsAsync = true;
|
||
($3 as procedure_definition).proc_header.class_keyword = true;
|
||
}
|
||
$$ = $3;
|
||
}
|
||
;
|
||
|
||
inclass_proc_func_decl_noclass
|
||
: proc_func_header inclass_block
|
||
{
|
||
$$ = new procedure_definition($1 as procedure_header, $2 as proc_block, @$);
|
||
}
|
||
| tkFunction func_name fp_list tkColon fptype optional_method_modificators1 tkAssign expr_l1_func_decl_lambda tkSemiColon
|
||
{
|
||
$$ = SyntaxTreeBuilder.BuildShortFuncDefinition($3 as formal_parameters, $6 as procedure_attributes_list, $2 as method_name, $5 as type_definition, $8, @1.Merge(@6));
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new short_func_definition($$ as procedure_definition);
|
||
}
|
||
| tkFunction func_name fp_list optional_method_modificators1 tkAssign expr_l1_func_decl_lambda tkSemiColon
|
||
{
|
||
$$ = SyntaxTreeBuilder.BuildShortFuncDefinition($3 as formal_parameters, $4 as procedure_attributes_list, $2 as method_name, null, $6, @1.Merge(@4));
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new short_func_definition($$ as procedure_definition);
|
||
}
|
||
| tkProcedure proc_name fp_list optional_method_modificators1 tkAssign unlabelled_stmt tkSemiColon
|
||
{
|
||
$$ = SyntaxTreeBuilder.BuildShortProcDefinition($3 as formal_parameters, $4 as procedure_attributes_list, $2 as method_name, $6 as statement, @1.Merge(@4));
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new short_func_definition($$ as procedure_definition);
|
||
}
|
||
;
|
||
|
||
proc_func_external_block
|
||
: block
|
||
{ $$ = $1; }
|
||
| external_block
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
proc_name
|
||
: func_name
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
func_name
|
||
: func_meth_name_ident
|
||
{
|
||
$$ = new method_name(null,null, $1, null, @$);
|
||
}
|
||
| func_class_name_ident_list tkPoint func_meth_name_ident
|
||
{
|
||
var ln = $1 as List<ident>;
|
||
var cnt = ln.Count;
|
||
if (cnt == 1)
|
||
$$ = new method_name(null, ln[cnt-1], $3, null, @$);
|
||
else
|
||
$$ = new method_name(ln, ln[cnt-1], $3, null, @$);
|
||
}
|
||
;
|
||
|
||
func_class_name_ident
|
||
: func_name_with_template_args
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
func_class_name_ident_list
|
||
: func_class_name_ident
|
||
{
|
||
$$ = new List<ident>();
|
||
($$ as List<ident>).Add($1);
|
||
}
|
||
| func_class_name_ident_list tkPoint func_class_name_ident
|
||
{
|
||
($1 as List<ident>).Add($3);
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
func_meth_name_ident
|
||
: func_name_with_template_args
|
||
{ $$ = $1; }
|
||
| operator_name_ident
|
||
{ $$ = (ident)$1; }
|
||
| operator_name_ident template_arguments
|
||
{ $$ = new template_operator_name(null, $2 as ident_list, $1 as operator_name_ident, @$); }
|
||
;
|
||
|
||
func_name_with_template_args
|
||
: func_name_ident
|
||
{ $$ = $1; }
|
||
| func_name_ident template_arguments
|
||
{
|
||
$$ = new template_type_name($1.name, $2 as ident_list, @$);
|
||
}
|
||
;
|
||
|
||
func_name_ident
|
||
: identifier
|
||
{ $$ = $1; }
|
||
// | func_name_ident tkPoint identifier
|
||
// { $$ = $3; }
|
||
;
|
||
|
||
proc_header
|
||
: tkProcedure proc_name fp_list optional_method_modificators optional_where_section
|
||
{
|
||
$$ = new procedure_header($3 as formal_parameters, $4 as procedure_attributes_list, $2 as method_name, $5 as where_definition_list, @$);
|
||
}
|
||
;
|
||
|
||
func_header
|
||
: tkFunction func_name fp_list optional_method_modificators optional_where_section
|
||
{
|
||
$$ = new function_header($3 as formal_parameters, $4 as procedure_attributes_list, $2 as method_name, $5 as where_definition_list, null, @$);
|
||
}
|
||
| tkFunction func_name fp_list tkColon fptype optional_method_modificators optional_where_section
|
||
{
|
||
$$ = new function_header($3 as formal_parameters, $6 as procedure_attributes_list, $2 as method_name, $7 as where_definition_list, $5 as type_definition, @$);
|
||
}
|
||
;
|
||
|
||
external_block
|
||
: tkExternal external_directive_ident tkName external_directive_ident tkSemiColon
|
||
{
|
||
$$ = new external_directive($2, $4, @$);
|
||
}
|
||
| tkExternal external_directive_ident tkSemiColon
|
||
{
|
||
$$ = new external_directive($2, null, @$);
|
||
}
|
||
| tkExternal tkSemiColon
|
||
{
|
||
$$ = new external_directive(null, null, @$);
|
||
}
|
||
;
|
||
|
||
external_directive_ident
|
||
: identifier
|
||
{ $$ = $1; }
|
||
| literal
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
block
|
||
: decl_sect_list compound_stmt tkSemiColon
|
||
{
|
||
$$ = new block($1 as declarations, $2 as statement_list, @$);
|
||
}
|
||
;
|
||
|
||
inclass_block
|
||
: inclass_decl_sect_list compound_stmt tkSemiColon
|
||
{
|
||
$$ = new block($1 as declarations, $2 as statement_list, @$);
|
||
}
|
||
| external_block
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
fp_list
|
||
:
|
||
{ $$ = null; }
|
||
| tkRoundOpen tkRoundClose
|
||
{
|
||
$$ = null;
|
||
}
|
||
| tkRoundOpen fp_sect_list tkRoundClose
|
||
{
|
||
$$ = $2;
|
||
if ($$ != null)
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
fp_sect_list
|
||
: fp_sect
|
||
{
|
||
$$ = new formal_parameters($1 as typed_parameters, @$);
|
||
}
|
||
| fp_sect_list tkSemiColon fp_sect
|
||
{
|
||
$$ = ($1 as formal_parameters).Add($3 as typed_parameters, @$);
|
||
}
|
||
;
|
||
|
||
fp_sect
|
||
: attribute_declarations simple_fp_sect
|
||
{
|
||
($2 as declaration).attributes = $1 as attribute_list;
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
simple_fp_sect
|
||
: param_name_list tkColon fptype
|
||
{
|
||
$$ = new typed_parameters($1 as ident_list, $3, parametr_kind.none, null, @$);
|
||
}
|
||
| tkVar param_name_list tkColon fptype
|
||
{
|
||
$$ = new typed_parameters($2 as ident_list, $4, parametr_kind.var_parametr, null, @$);
|
||
}
|
||
| tkConst param_name_list tkColon fptype
|
||
{
|
||
$$ = new typed_parameters($2 as ident_list, $4, parametr_kind.const_parametr, null, @$);
|
||
}
|
||
| tkParams param_name_list tkColon fptype
|
||
{
|
||
$$ = new typed_parameters($2 as ident_list, $4,parametr_kind.params_parametr,null, @$);
|
||
}
|
||
| param_name_list tkColon fptype tkAssign expr
|
||
{
|
||
$$ = new typed_parameters($1 as ident_list, $3, parametr_kind.none, $5, @$);
|
||
}
|
||
| tkVar param_name_list tkColon fptype tkAssign expr
|
||
{
|
||
$$ = new typed_parameters($2 as ident_list, $4, parametr_kind.var_parametr, $6, @$);
|
||
}
|
||
| tkConst param_name_list tkColon fptype tkAssign expr
|
||
{
|
||
$$ = new typed_parameters($2 as ident_list, $4, parametr_kind.const_parametr, $6, @$);
|
||
}
|
||
;
|
||
|
||
param_name_list
|
||
: param_name
|
||
{
|
||
$$ = new ident_list($1, @$);
|
||
}
|
||
| param_name_list tkComma param_name
|
||
{
|
||
$$ = ($1 as ident_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
param_name
|
||
: identifier
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
fptype
|
||
: type_ref
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
fptype_noproctype
|
||
: simple_type
|
||
{ $$ = $1; }
|
||
| string_type
|
||
{ $$ = $1; }
|
||
| pointer_type
|
||
{ $$ = $1; }
|
||
| structured_type
|
||
{ $$ = $1; }
|
||
| template_type
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
stmt
|
||
: unlabelled_stmt
|
||
{ $$ = $1; }
|
||
| label_name tkColon stmt
|
||
{
|
||
$$ = new labeled_statement($1, $3 as statement, @$);
|
||
}
|
||
;
|
||
|
||
unlabelled_stmt
|
||
:
|
||
{
|
||
$$ = new empty_statement();
|
||
$$.source_context = null;
|
||
}
|
||
| assignment
|
||
{ $$ = $1; }
|
||
| proc_call
|
||
{ $$ = $1; }
|
||
| goto_stmt
|
||
{ $$ = $1; }
|
||
| compound_stmt
|
||
{ $$ = $1; }
|
||
| if_stmt
|
||
{ $$ = $1; }
|
||
| case_stmt
|
||
{ $$ = $1; }
|
||
| repeat_stmt
|
||
{ $$ = $1; }
|
||
| while_stmt
|
||
{ $$ = $1; }
|
||
| for_stmt
|
||
{ $$ = $1; }
|
||
| with_stmt
|
||
{ $$ = $1; }
|
||
| inherited_message
|
||
{ $$ = $1; }
|
||
| try_stmt
|
||
{ $$ = $1; }
|
||
| raise_stmt
|
||
{ $$ = $1; }
|
||
| foreach_stmt
|
||
{ $$ = $1; }
|
||
| var_stmt
|
||
{ $$ = $1; }
|
||
| expr_as_stmt
|
||
{ $$ = $1; }
|
||
| lock_stmt
|
||
{ $$ = $1; }
|
||
| yield_stmt
|
||
{ $$ = $1; }
|
||
| yield_sequence_stmt
|
||
{ $$ = $1; }
|
||
| loop_stmt
|
||
{ $$ = $1; }
|
||
| match_with
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
loop_stmt
|
||
: tkLoop expr_l1 tkDo unlabelled_stmt
|
||
{
|
||
$$ = new loop_stmt($2,$4 as statement,@$);
|
||
}
|
||
;
|
||
|
||
yield_stmt
|
||
: tkYield expr_l1_func_decl_lambda
|
||
{
|
||
$$ = new yield_node($2,@$);
|
||
}
|
||
;
|
||
|
||
yield_sequence_stmt
|
||
: tkYield tkSequence expr_l1_func_decl_lambda
|
||
{
|
||
$$ = new yield_sequence_node($3,@$);
|
||
}
|
||
;
|
||
|
||
var_stmt
|
||
: tkVar var_decl_part
|
||
{
|
||
$$ = new var_statement($2 as var_def_statement, @$);
|
||
}
|
||
| tkRoundOpen tkVar identifier tkComma var_ident_list tkRoundClose tkAssign expr
|
||
{
|
||
($5 as ident_list).Insert(0,$3);
|
||
($5 as syntax_tree_node).source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5,@6);
|
||
$$ = new assign_var_tuple($5 as ident_list, $8, @$);
|
||
}
|
||
| tkVar tkRoundOpen identifier tkComma ident_list tkRoundClose tkAssign expr
|
||
{
|
||
($5 as ident_list).Insert(0,$3);
|
||
$5.source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5,@6);
|
||
$$ = new assign_var_tuple($5 as ident_list, $8, @$);
|
||
}
|
||
;
|
||
|
||
assignment
|
||
: var_reference assign_operator expr_with_func_decl_lambda
|
||
{
|
||
if (!($1 is addressed_value))
|
||
parserTools.AddErrorFromResource("LEFT_SIDE_CANNOT_BE_ASSIGNED_TO",@$);
|
||
$$ = new assign($1 as addressed_value, $3, $2.type, @$);
|
||
}
|
||
| tkRoundOpen variable tkComma variable_list tkRoundClose assign_operator expr
|
||
{
|
||
if ($6.type != Operators.Assignment)
|
||
parserTools.AddErrorFromResource("ONLY_BASE_ASSIGNMENT_FOR_TUPLE",@6);
|
||
($4 as addressed_value_list).Insert(0,$2 as addressed_value);
|
||
($4 as syntax_tree_node).source_context = LexLocation.MergeAll(@1,@2,@3,@4,@5);
|
||
$$ = new assign_tuple($4 as addressed_value_list, $7, @$);
|
||
}
|
||
/* | variable tkQuestionSquareOpen format_expr tkSquareClose assign_operator expr
|
||
{
|
||
var fe = $3 as format_expr;
|
||
if (!parserTools.buildTreeForFormatter)
|
||
{
|
||
if (fe.expr == null)
|
||
fe.expr = new int32_const(int.MaxValue,@3);
|
||
if (fe.format1 == null)
|
||
fe.format1 = new int32_const(int.MaxValue,@3);
|
||
}
|
||
var left = new slice_expr_question($1 as addressed_value,fe.expr,fe.format1,fe.format2,@$);
|
||
$$ = new assign(left, $6, $5.type, @$);
|
||
}*/
|
||
;
|
||
|
||
variable_list
|
||
: variable
|
||
{
|
||
$$ = new addressed_value_list($1 as addressed_value,@1);
|
||
}
|
||
| variable_list tkComma variable
|
||
{
|
||
($1 as addressed_value_list).Add($3 as addressed_value);
|
||
($1 as syntax_tree_node).source_context = LexLocation.MergeAll(@1,@2,@3);
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
var_ident_list
|
||
: tkVar identifier
|
||
{
|
||
$$ = new ident_list($2,@$);
|
||
}
|
||
| var_ident_list tkComma tkVar identifier
|
||
{
|
||
($1 as ident_list).Add($4);
|
||
($1 as ident_list).source_context = LexLocation.MergeAll(@1,@2,@3,@4);
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
proc_call
|
||
: var_reference
|
||
{
|
||
$$ = new procedure_call($1 as addressed_value, $1 is ident, @$);
|
||
}
|
||
;
|
||
|
||
goto_stmt
|
||
: tkGoto label_name
|
||
{
|
||
$$ = new goto_statement($2, @$);
|
||
}
|
||
;
|
||
|
||
compound_stmt
|
||
: tkBegin stmt_list tkEnd
|
||
{
|
||
$$ = $2;
|
||
($$ as statement_list).left_logical_bracket = $1;
|
||
($$ as statement_list).right_logical_bracket = $3;
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
stmt_list
|
||
: stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @1);
|
||
}
|
||
| stmt_list tkSemiColon stmt
|
||
{
|
||
$$ = ($1 as statement_list).Add($3 as statement, @$);
|
||
}
|
||
;
|
||
|
||
if_stmt
|
||
: tkIf expr_l1 tkThen unlabelled_stmt
|
||
{
|
||
$$ = new if_node($2, $4 as statement, null, @$);
|
||
}
|
||
| tkIf expr_l1 tkThen unlabelled_stmt tkElse unlabelled_stmt
|
||
{
|
||
$$ = new if_node($2, $4 as statement, $6 as statement, @$);
|
||
}
|
||
;
|
||
|
||
match_with
|
||
: tkMatch expr_l1 tkWith pattern_cases else_case tkEnd
|
||
{
|
||
$$ = new match_with($2, $4 as pattern_cases, $5 as statement, @$);
|
||
}
|
||
| tkMatch expr_l1 tkWith pattern_cases tkSemiColon else_case tkEnd
|
||
{
|
||
$$ = new match_with($2, $4 as pattern_cases, $6 as statement, @$);
|
||
}
|
||
;
|
||
|
||
pattern_cases
|
||
: pattern_case
|
||
{
|
||
$$ = new pattern_cases($1 as pattern_case);
|
||
}
|
||
| pattern_cases tkSemiColon pattern_case
|
||
{
|
||
$$ = ($1 as pattern_cases).Add($3 as pattern_case);
|
||
}
|
||
;
|
||
|
||
pattern_case
|
||
: pattern_optional_var tkWhen expr_l1 tkColon unlabelled_stmt
|
||
{
|
||
$$ = new pattern_case($1 as pattern_node, $5 as statement, $3, @$);
|
||
}
|
||
| deconstruction_or_const_pattern tkColon unlabelled_stmt
|
||
{
|
||
$$ = new pattern_case($1 as pattern_node, $3 as statement, null, @$);
|
||
}
|
||
| collection_pattern tkColon unlabelled_stmt
|
||
{
|
||
$$ = new pattern_case($1 as pattern_node, $3 as statement, null, @$);
|
||
}
|
||
| tuple_pattern tkWhen expr_l1 tkColon unlabelled_stmt
|
||
{
|
||
$$ = new pattern_case($1 as pattern_node, $5 as statement, $3, @$);
|
||
}
|
||
| tuple_pattern tkColon unlabelled_stmt
|
||
{
|
||
$$ = new pattern_case($1 as pattern_node, $3 as statement, null, @$);
|
||
}
|
||
;
|
||
|
||
case_stmt
|
||
: tkCase expr_l1 tkOf case_list else_case tkEnd
|
||
{
|
||
$$ = new case_node($2, $4 as case_variants, $5 as statement, @$);
|
||
}
|
||
| tkCase expr_l1 tkOf case_list tkSemiColon else_case tkEnd
|
||
{
|
||
$$ = new case_node($2, $4 as case_variants, $6 as statement, @$);
|
||
}
|
||
| tkCase expr_l1 tkOf else_case tkEnd
|
||
{
|
||
$$ = new case_node($2, NewCaseItem(new empty_statement(), null), $4 as statement, @$);
|
||
}
|
||
;
|
||
|
||
case_list
|
||
: case_item
|
||
{
|
||
if ($1 is empty_statement)
|
||
$$ = NewCaseItem($1, null);
|
||
else $$ = NewCaseItem($1, @$);
|
||
}
|
||
| case_list tkSemiColon case_item
|
||
{
|
||
$$ = AddCaseItem($1 as case_variants, $3, @$);
|
||
}
|
||
;
|
||
|
||
case_item
|
||
: case_label_list tkColon unlabelled_stmt
|
||
{
|
||
$$ = new case_variant($1 as expression_list, $3 as statement, @$);
|
||
}
|
||
;
|
||
|
||
case_label_list
|
||
: case_label
|
||
{
|
||
$$ = new expression_list($1, @$);
|
||
}
|
||
| case_label_list tkComma case_label
|
||
{
|
||
$$ = ($1 as expression_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
case_label
|
||
: const_elem
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
else_case
|
||
:
|
||
{ $$ = null;}
|
||
| tkElse stmt_list
|
||
{ $$ = $2; }
|
||
;
|
||
|
||
repeat_stmt
|
||
: tkRepeat stmt_list tkUntil expr
|
||
{
|
||
$$ = new repeat_node($2 as statement_list, $4, @$);
|
||
($2 as statement_list).left_logical_bracket = $1;
|
||
($2 as statement_list).right_logical_bracket = $3;
|
||
$2.source_context = @1.Merge(@3);
|
||
}
|
||
;
|
||
|
||
while_stmt
|
||
: tkWhile expr_l1 optional_tk_do unlabelled_stmt
|
||
{
|
||
$$ = NewWhileStmt($1, $2, $3, $4 as statement, @$);
|
||
}
|
||
;
|
||
|
||
optional_tk_do
|
||
: tkDo
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
lock_stmt
|
||
: tkLock expr_l1 tkDo unlabelled_stmt
|
||
{
|
||
$$ = new lock_stmt($2, $4 as statement, @$);
|
||
}
|
||
;
|
||
|
||
index_or_nothing
|
||
: tkIndex tkIdentifier
|
||
{ $$ = $2; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
optional_type_specification
|
||
: tkColon type_ref
|
||
{ $$ = $2; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
optional_var
|
||
: tkVar
|
||
{ $$ = true; }
|
||
|
|
||
{ $$ = false; }
|
||
;
|
||
|
||
for_cycle_type
|
||
: tkTo
|
||
{ $$ = for_cycle_type.to; }
|
||
| tkDownto
|
||
{ $$ = for_cycle_type.downto; }
|
||
;
|
||
|
||
foreach_stmt
|
||
: tkForeach identifier optional_type_specification tkIn expr_l1 index_or_nothing tkDo unlabelled_stmt
|
||
{
|
||
$$ = new foreach_stmt($2, $3, $5, $8 as statement, $6, @$);
|
||
if ($3 == null)
|
||
parserTools.AddWarningFromResource("USING_UNLOCAL_FOREACH_VARIABLE", $2.source_context);
|
||
}
|
||
| tkForeach tkVar identifier optional_type_specification tkIn expr_l1 index_or_nothing tkDo unlabelled_stmt
|
||
{
|
||
if ($4 == null)
|
||
$$ = new foreach_stmt($3, new no_type_foreach(), $6, $9 as statement, $7, @$);
|
||
else $$ = new foreach_stmt($3, $4, $6, $9 as statement, $7, @$);
|
||
}
|
||
| tkForeach tkVar tkRoundOpen ident_list tkRoundClose tkIn expr_l1 index_or_nothing tkDo unlabelled_stmt // сахарное правило
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
{
|
||
var il = $4 as ident_list;
|
||
il.source_context = LexLocation.MergeAll(@4,@5); // нужно для форматирования
|
||
$$ = new foreach_stmt_formatting(il,$7,$10 as statement,$8,@$);
|
||
}
|
||
else
|
||
{
|
||
// Есть проблема - непонятно, где здесь сделать семантческий узел для проверки
|
||
// Проверить можно и в foreach, но где-то должен быть маркер, что это сахарный узел
|
||
// Например, идентификатор #fe - но это плохая идея
|
||
var id = NewId("#fe",@4);
|
||
var tttt = new assign_var_tuple($4 as ident_list, id, @$);
|
||
statement_list nine = $10 is statement_list ? $10 as statement_list : new statement_list($10 as statement,@9);
|
||
nine.Insert(0,tttt);
|
||
var fe = new foreach_stmt(id, new no_type_foreach(), $7, nine, $8, @$);
|
||
fe.ext = $4 as ident_list;
|
||
$$ = fe;
|
||
}
|
||
}
|
||
;
|
||
|
||
for_stmt
|
||
: tkFor optional_var identifier optional_type_specification tkAssign expr_l1 for_cycle_type expr_l1 optional_tk_do unlabelled_stmt
|
||
{
|
||
$$ = NewForStmt((bool)$2, $3, $4, $6, (for_cycle_type)$7, $8, $9, $10 as statement, null, @$);
|
||
}
|
||
| tkFor optional_var identifier optional_type_specification tkAssign expr_l1 for_cycle_type expr_l1 tkStep expr_l1 tkDo unlabelled_stmt
|
||
{
|
||
$$ = NewForStmt((bool)$2, $3, $4, $6, (for_cycle_type)$7, $8, $9, $12 as statement, $10, @$);
|
||
}
|
||
;
|
||
|
||
with_stmt
|
||
: tkWith expr_list tkDo unlabelled_stmt
|
||
{
|
||
$$ = new with_statement($4 as statement, $2 as expression_list, @$);
|
||
}
|
||
;
|
||
|
||
inherited_message
|
||
: tkInherited
|
||
{
|
||
$$ = new inherited_message();
|
||
$$.source_context = @$;
|
||
}
|
||
;
|
||
|
||
try_stmt
|
||
: tkTry stmt_list try_handler
|
||
{
|
||
$$ = new try_stmt($2 as statement_list, $3 as try_handler, @$);
|
||
($2 as statement_list).left_logical_bracket = $1;
|
||
$2.source_context = @1.Merge(@2);
|
||
}
|
||
;
|
||
|
||
try_handler
|
||
: tkFinally stmt_list tkEnd
|
||
{
|
||
$$ = new try_handler_finally($2 as statement_list, @$);
|
||
($2 as statement_list).left_logical_bracket = $1;
|
||
($2 as statement_list).right_logical_bracket = $3;
|
||
}
|
||
| tkExcept exception_block tkEnd
|
||
{
|
||
$$ = new try_handler_except((exception_block)$2, @$);
|
||
if (($2 as exception_block).stmt_list != null)
|
||
{
|
||
($2 as exception_block).stmt_list.source_context = @$;
|
||
($2 as exception_block).source_context = @$;
|
||
}
|
||
}
|
||
;
|
||
|
||
exception_block
|
||
: exception_handler_list exception_block_else_branch
|
||
{
|
||
$$ = new exception_block(null, (exception_handler_list)$1, (statement_list)$2, @$);
|
||
}
|
||
| exception_handler_list tkSemiColon exception_block_else_branch
|
||
{
|
||
$$ = new exception_block(null, (exception_handler_list)$1, (statement_list)$3, @$);
|
||
}
|
||
| stmt_list
|
||
{
|
||
$$ = new exception_block($1 as statement_list, null, null, @1);
|
||
}
|
||
;
|
||
|
||
exception_handler_list
|
||
: exception_handler
|
||
{
|
||
$$ = new exception_handler_list($1 as exception_handler, @$);
|
||
}
|
||
| exception_handler_list tkSemiColon exception_handler
|
||
{
|
||
$$ = ($1 as exception_handler_list).Add($3 as exception_handler, @$);
|
||
}
|
||
;
|
||
|
||
exception_block_else_branch
|
||
:
|
||
{ $$ = null; }
|
||
| tkElse stmt_list
|
||
{ $$ = $2; }
|
||
;
|
||
|
||
exception_handler
|
||
: tkOn exception_identifier tkDo unlabelled_stmt
|
||
{
|
||
$$ = new exception_handler(($2 as exception_ident).variable, ($2 as exception_ident).type_name, $4 as statement, @$);
|
||
}
|
||
;
|
||
|
||
exception_identifier
|
||
: exception_class_type_identifier
|
||
{
|
||
$$ = new exception_ident(null, (named_type_reference)$1, @$);
|
||
}
|
||
| exception_variable tkColon exception_class_type_identifier
|
||
{
|
||
$$ = new exception_ident($1, (named_type_reference)$3, @$);
|
||
}
|
||
;
|
||
|
||
exception_class_type_identifier
|
||
: simple_type_identifier
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
exception_variable
|
||
: identifier
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
raise_stmt
|
||
: tkRaise
|
||
{
|
||
$$ = new raise_stmt();
|
||
$$.source_context = @$;
|
||
}
|
||
| tkRaise expr
|
||
{
|
||
$$ = new raise_stmt($2, null, @$);
|
||
}
|
||
;
|
||
|
||
expr_list
|
||
: expr_with_func_decl_lambda
|
||
{
|
||
$$ = new expression_list($1, @$);
|
||
}
|
||
| expr_list tkComma expr_with_func_decl_lambda
|
||
{
|
||
$$ = ($1 as expression_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
expr_list_func_param
|
||
: expr_with_func_decl_lambda_ass
|
||
{
|
||
$$ = new expression_list($1, @$);
|
||
}
|
||
| expr_list_func_param tkComma expr_with_func_decl_lambda_ass
|
||
{
|
||
$$ = ($1 as expression_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
expr_as_stmt
|
||
: allowable_expr_as_stmt
|
||
{
|
||
$$ = new expression_as_statement($1, @$);
|
||
}
|
||
;
|
||
|
||
allowable_expr_as_stmt
|
||
: new_expr
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
expr_with_func_decl_lambda
|
||
: expr
|
||
{ $$ = $1; }
|
||
| func_decl_lambda
|
||
{ $$ = $1; }
|
||
| tkInherited
|
||
{ $$ = new inherited_ident("", @$); }
|
||
;
|
||
|
||
expr_with_func_decl_lambda_ass
|
||
: expr
|
||
{ $$ = $1; }
|
||
| identifier tkAssign expr_l1
|
||
{ $$ = new name_assign_expr($1,$3,@$); }
|
||
| func_decl_lambda
|
||
{ $$ = $1; }
|
||
| tkInherited
|
||
{ $$ = new inherited_ident("", @$); }
|
||
;
|
||
|
||
expr
|
||
: expr_l1
|
||
{ $$ = $1; }
|
||
| format_expr
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
expr_l1
|
||
: expr_dq
|
||
{ $$ = $1; }
|
||
| question_expr
|
||
{ $$ = $1; }
|
||
| new_question_expr
|
||
{ $$ = $1; }
|
||
// | var_stmt tkComma expr_l1
|
||
// { $$ = $3; }
|
||
;
|
||
|
||
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
|
||
{ $$ = $1; }
|
||
| tkAwait relop_expr
|
||
{ $$ = $2; }
|
||
| expr_dq tkDoubleQuestion relop_expr
|
||
{ $$ = new double_question_node($1 as expression, $3 as expression, @$);}
|
||
;
|
||
|
||
sizeof_expr
|
||
: tkSizeOf tkRoundOpen simple_or_template_type_reference tkRoundClose
|
||
{
|
||
$$ = new sizeof_operator((named_type_reference)$3, null, @$);
|
||
}
|
||
;
|
||
|
||
typeof_expr
|
||
: tkTypeOf tkRoundOpen simple_or_template_type_reference tkRoundClose
|
||
{
|
||
$$ = new typeof_operator((named_type_reference)$3, @$);
|
||
}
|
||
|
|
||
tkTypeOf tkRoundOpen empty_template_type_reference tkRoundClose
|
||
{
|
||
$$ = new typeof_operator((named_type_reference)$3, @$);
|
||
}
|
||
;
|
||
|
||
question_expr
|
||
: 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, @$);
|
||
}
|
||
;
|
||
|
||
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.buildTreeForFormatter)
|
||
{
|
||
$$ = new if_expr_new($2, $4, $6, @$);
|
||
}
|
||
else
|
||
{
|
||
if ($4 is nil_const && $6 is nil_const)
|
||
parserTools.AddErrorFromResource("TWO_NILS_IN_QUESTION_EXPR",@4);
|
||
$$ = new question_colon_expression($2, $4, $6, @$);
|
||
}
|
||
}
|
||
;
|
||
|
||
|
||
empty_template_type_reference
|
||
: simple_type_identifier template_type_empty_params
|
||
{
|
||
$$ = new template_type_reference((named_type_reference)$1, (template_param_list)$2, @$);
|
||
}
|
||
| simple_type_identifier tkAmpersend template_type_empty_params
|
||
{
|
||
$$ = new template_type_reference((named_type_reference)$1, (template_param_list)$3, @$);
|
||
}
|
||
;
|
||
|
||
simple_or_template_type_reference
|
||
: simple_type_identifier
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| simple_type_identifier template_type_params
|
||
{
|
||
$$ = new template_type_reference((named_type_reference)$1, (template_param_list)$2, @$);
|
||
}
|
||
| simple_type_identifier tkAmpersend template_type_params
|
||
{
|
||
$$ = new template_type_reference((named_type_reference)$1, (template_param_list)$3, @$);
|
||
}
|
||
;
|
||
|
||
simple_or_template_or_question_type_reference
|
||
: simple_or_template_type_reference
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| simple_type_question
|
||
{
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
optional_array_initializer
|
||
: tkRoundOpen typed_const_list tkRoundClose
|
||
{
|
||
$$ = new array_const((expression_list)$2, @$);
|
||
}
|
||
|
|
||
;
|
||
|
||
new_expr
|
||
: tkNew simple_or_template_type_reference optional_expr_list_with_bracket
|
||
{
|
||
$$ = new new_expr($2, $3 as expression_list, false, null, @$);
|
||
}
|
||
| tkNew simple_or_template_type_reference tkSquareOpen optional_expr_list tkSquareClose optional_array_initializer
|
||
{
|
||
var el = $4 as expression_list;
|
||
if (el == null)
|
||
{
|
||
var cnt = 0;
|
||
var ac = $6 as array_const;
|
||
if (ac != null && ac.elements != null)
|
||
cnt = ac.elements.Count;
|
||
else parserTools.AddErrorFromResource("WITHOUT_INIT_AND_SIZE",@5);
|
||
el = new expression_list(new int32_const(cnt),@1);
|
||
}
|
||
$$ = new new_expr($2, el, true, $6 as array_const, @$);
|
||
}
|
||
| tkNew tkClass tkRoundOpen list_fields_in_unnamed_object tkRoundClose
|
||
{
|
||
// sugared node
|
||
var l = $4 as name_assign_expr_list;
|
||
var exprs = l.name_expr.Select(x=>x.expr.Clone() as expression).ToList();
|
||
var typename = "AnonymousType#"+Guid();
|
||
var type = new named_type_reference(typename,@1);
|
||
|
||
// node new_expr - for code generation of new node
|
||
var ne = new new_expr(type, new expression_list(exprs), @$);
|
||
// node unnamed_type_object - for formatting and code generation (new node and Anonymous class)
|
||
$$ = new unnamed_type_object(l, true, ne, @$);
|
||
}
|
||
;
|
||
|
||
field_in_unnamed_object
|
||
: identifier tkAssign expr_l1
|
||
{
|
||
if ($3 is nil_const)
|
||
parserTools.AddErrorFromResource("NIL_IN_UNNAMED_OBJECT",@$);
|
||
$$ = new name_assign_expr($1,$3,@$);
|
||
}
|
||
| expr_l1
|
||
{
|
||
ident name = null;
|
||
var id = $1 as ident;
|
||
dot_node dot;
|
||
if (id != null)
|
||
name = id;
|
||
else
|
||
{
|
||
dot = $1 as dot_node;
|
||
if (dot != null)
|
||
{
|
||
name = dot.right as ident;
|
||
}
|
||
}
|
||
if (name == null)
|
||
parserTools.errors.Add(new bad_anon_type(parserTools.currentFileName, @1, null));
|
||
$$ = new name_assign_expr(name,$1,@$);
|
||
}
|
||
;
|
||
|
||
list_fields_in_unnamed_object
|
||
: field_in_unnamed_object
|
||
{
|
||
var l = new name_assign_expr_list();
|
||
$$ = l.Add($1 as name_assign_expr);
|
||
}
|
||
| list_fields_in_unnamed_object tkComma field_in_unnamed_object
|
||
{
|
||
var nel = $1 as name_assign_expr_list;
|
||
var ss = nel.name_expr.Select(ne=>ne.name.name).FirstOrDefault(x=>string.Compare(x,($3 as name_assign_expr).name.name,true)==0);
|
||
if (ss != null)
|
||
parserTools.errors.Add(new anon_type_duplicate_name(parserTools.currentFileName, @3, null));
|
||
nel.Add($3 as name_assign_expr);
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
/*array_name_for_new_expr
|
||
: simple_type_identifier
|
||
{ $$ = $1; }
|
||
// | unsized_array_type - и кому такое приснилось
|
||
// { $$ = $1; }
|
||
;*/
|
||
|
||
optional_expr_list_with_bracket
|
||
:
|
||
{ $$ = null; }
|
||
| tkRoundOpen optional_expr_list tkRoundClose
|
||
{ $$ = $2; }
|
||
;
|
||
|
||
relop_expr
|
||
: simple_expr
|
||
{ $$ = $1; }
|
||
| relop_expr relop simple_expr
|
||
{
|
||
if ($2.type == Operators.NotIn)
|
||
$$ = new un_expr(new bin_expr($1, $3, Operators.In, @$),Operators.LogicalNOT,@$);
|
||
else
|
||
$$ = new bin_expr($1, $3, $2.type, @$);
|
||
}
|
||
| relop_expr relop new_question_expr
|
||
{
|
||
if ($2.type == Operators.NotIn)
|
||
$$ = new un_expr(new bin_expr($1, $3, Operators.In, @$),Operators.LogicalNOT,@$);
|
||
else
|
||
$$ = new bin_expr($1, $3, $2.type, @$);
|
||
}
|
||
| is_type_expr tkRoundOpen pattern_out_param_list tkRoundClose
|
||
{
|
||
var isTypeCheck = $1 as typecast_node;
|
||
var deconstructorPattern = new deconstructor_pattern($3 as List<pattern_parameter>, isTypeCheck.type_def, null, @$);
|
||
$$ = new is_pattern_expr(isTypeCheck.expr, deconstructorPattern, @$);
|
||
}
|
||
/*
|
||
| term tkIs collection_pattern
|
||
{
|
||
$$ = new is_pattern_expr($1, $3 as pattern_node, @$);
|
||
}
|
||
| term tkIs tuple_pattern
|
||
{
|
||
$$ = new is_pattern_expr($1, $3 as pattern_node, @$);
|
||
}
|
||
*/
|
||
;
|
||
|
||
pattern
|
||
: simple_or_template_type_reference tkRoundOpen pattern_out_param_list tkRoundClose
|
||
{
|
||
$$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, null, @$);
|
||
}
|
||
;
|
||
|
||
pattern_optional_var
|
||
: simple_or_template_type_reference tkRoundOpen pattern_out_param_list_optional_var tkRoundClose
|
||
{
|
||
$$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, null, @$);
|
||
}
|
||
;
|
||
|
||
deconstruction_or_const_pattern
|
||
: simple_or_template_type_reference tkRoundOpen pattern_out_param_list_optional_var tkRoundClose
|
||
{
|
||
$$ = new deconstructor_pattern($3 as List<pattern_parameter>, $1, null, @$);
|
||
}
|
||
| const_pattern_expr_list
|
||
{
|
||
$$ = new const_pattern($1 as List<syntax_tree_node>, @$);
|
||
}
|
||
;
|
||
|
||
const_pattern_expr_list
|
||
: const_pattern_expression
|
||
{
|
||
$$ = new List<syntax_tree_node>();
|
||
($$ as List<syntax_tree_node>).Add($1);
|
||
}
|
||
| const_pattern_expr_list tkComma const_pattern_expression
|
||
{
|
||
var list = $1 as List<syntax_tree_node>;
|
||
list.Add($3);
|
||
$$ = list;
|
||
}
|
||
;
|
||
|
||
const_pattern_expression
|
||
: literal_or_number
|
||
{ $$ = $1; }
|
||
| simple_or_template_type_reference
|
||
{ $$ = $1; }
|
||
| tkNil
|
||
{
|
||
$$ = new nil_const();
|
||
$$.source_context = @$;
|
||
}
|
||
| sizeof_expr
|
||
{ $$ = $1; }
|
||
| typeof_expr
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
collection_pattern
|
||
: tkSquareOpen collection_pattern_expr_list tkSquareClose
|
||
{
|
||
$$ = new collection_pattern($2 as List<pattern_parameter>, @$);
|
||
}
|
||
;
|
||
|
||
collection_pattern_expr_list
|
||
: collection_pattern_list_item
|
||
{
|
||
$$ = new List<pattern_parameter>();
|
||
($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
|
||
}
|
||
| collection_pattern_expr_list tkComma collection_pattern_list_item
|
||
{
|
||
var list = $1 as List<pattern_parameter>;
|
||
list.Add($3 as pattern_parameter);
|
||
$$ = list;
|
||
}
|
||
;
|
||
|
||
collection_pattern_list_item
|
||
: literal_or_number
|
||
{
|
||
$$ = new const_pattern_parameter($1, @$);
|
||
}
|
||
| collection_pattern_var_item
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| tkUnderscore
|
||
{
|
||
$$ = new collection_pattern_wild_card(@$);
|
||
}
|
||
/*| pattern
|
||
{
|
||
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
|
||
}*/
|
||
| pattern_optional_var
|
||
{
|
||
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
|
||
}
|
||
| collection_pattern
|
||
{
|
||
$$ = new recursive_collection_parameter($1 as pattern_node, @$);
|
||
}
|
||
| tuple_pattern
|
||
{
|
||
$$ = new recursive_tuple_parameter($1 as pattern_node, @$);
|
||
}
|
||
| tkDotDot
|
||
{
|
||
$$ = new collection_pattern_gap_parameter(@$);
|
||
}
|
||
;
|
||
|
||
collection_pattern_var_item
|
||
: tkVar identifier
|
||
{
|
||
$$ = new collection_pattern_var_parameter($2, null, @$);
|
||
}
|
||
;
|
||
|
||
tuple_pattern
|
||
: tkRoundOpen tuple_pattern_item_list tkRoundClose
|
||
{
|
||
if (($2 as List<pattern_parameter>).Count>6)
|
||
parserTools.AddErrorFromResource("TUPLE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7",@$);
|
||
$$ = new tuple_pattern($2 as List<pattern_parameter>, @$);
|
||
}
|
||
;
|
||
|
||
tuple_pattern_item
|
||
: tkUnderscore
|
||
{
|
||
$$ = new tuple_pattern_wild_card(@$);
|
||
}
|
||
| literal_or_number
|
||
{
|
||
$$ = new const_pattern_parameter($1, @$);
|
||
}
|
||
| sign literal_or_number
|
||
{
|
||
$$ = new const_pattern_parameter(new un_expr($2, $1.type, @$), @$);
|
||
}
|
||
| tkVar identifier
|
||
{
|
||
$$ = new tuple_pattern_var_parameter($2, null, @$);
|
||
}
|
||
| pattern_optional_var
|
||
{
|
||
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
|
||
}
|
||
| collection_pattern
|
||
{
|
||
$$ = new recursive_collection_parameter($1 as pattern_node, @$);
|
||
}
|
||
| tuple_pattern
|
||
{
|
||
$$ = new recursive_tuple_parameter($1 as pattern_node, @$);
|
||
}
|
||
;
|
||
|
||
tuple_pattern_item_list
|
||
: tuple_pattern_item
|
||
{
|
||
$$ = new List<pattern_parameter>();
|
||
($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
|
||
}
|
||
| tuple_pattern_item_list tkComma tuple_pattern_item
|
||
{
|
||
var list = $1 as List<pattern_parameter>;
|
||
list.Add($3 as pattern_parameter);
|
||
$$ = list;
|
||
}
|
||
;
|
||
|
||
pattern_out_param_list_optional_var
|
||
: pattern_out_param_optional_var
|
||
{
|
||
$$ = new List<pattern_parameter>();
|
||
($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
|
||
}
|
||
| pattern_out_param_list_optional_var tkSemiColon pattern_out_param_optional_var
|
||
{
|
||
var list = $1 as List<pattern_parameter>;
|
||
list.Add($3 as pattern_parameter);
|
||
$$ = list;
|
||
}
|
||
| pattern_out_param_list_optional_var tkComma pattern_out_param_optional_var
|
||
{
|
||
var list = $1 as List<pattern_parameter>;
|
||
list.Add($3 as pattern_parameter);
|
||
$$ = list;
|
||
}
|
||
;
|
||
|
||
pattern_out_param_list
|
||
: pattern_out_param
|
||
{
|
||
$$ = new List<pattern_parameter>();
|
||
($$ as List<pattern_parameter>).Add($1 as pattern_parameter);
|
||
}
|
||
| pattern_out_param_list tkSemiColon pattern_out_param
|
||
{
|
||
var list = $1 as List<pattern_parameter>;
|
||
list.Add($3 as pattern_parameter);
|
||
$$ = list;
|
||
}
|
||
| pattern_out_param_list tkComma pattern_out_param
|
||
{
|
||
var list = $1 as List<pattern_parameter>;
|
||
list.Add($3 as pattern_parameter);
|
||
$$ = list;
|
||
}
|
||
;
|
||
|
||
pattern_out_param
|
||
: tkUnderscore
|
||
{
|
||
$$ = new wild_card_deconstructor_parameter(@$);
|
||
}
|
||
| literal_or_number
|
||
{
|
||
$$ = new const_pattern_parameter($1, @$);
|
||
}
|
||
| tkVar identifier tkColon type_ref
|
||
{
|
||
$$ = new var_deconstructor_parameter($2, $4, true, @$);
|
||
}
|
||
| tkVar identifier
|
||
{
|
||
$$ = new var_deconstructor_parameter($2, null, true, @$);
|
||
}
|
||
| pattern
|
||
{
|
||
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
|
||
}
|
||
| collection_pattern
|
||
{
|
||
$$ = new recursive_collection_parameter($1 as pattern_node, @$);
|
||
}
|
||
| tuple_pattern
|
||
{
|
||
$$ = new recursive_tuple_parameter($1 as pattern_node, @$);
|
||
}
|
||
;
|
||
|
||
pattern_out_param_optional_var
|
||
: tkUnderscore
|
||
{
|
||
$$ = new wild_card_deconstructor_parameter(@$);
|
||
}
|
||
| literal_or_number
|
||
{
|
||
$$ = new const_pattern_parameter($1, @$);
|
||
}
|
||
| sign literal_or_number
|
||
{
|
||
$$ = new const_pattern_parameter(new un_expr($2, $1.type, @$), @$);
|
||
}
|
||
| identifier tkColon type_ref
|
||
{
|
||
$$ = new var_deconstructor_parameter($1, $3, false, @$);
|
||
}
|
||
| identifier
|
||
{
|
||
$$ = new var_deconstructor_parameter($1, null, false, @$);
|
||
}
|
||
| tkVar identifier tkColon type_ref
|
||
{
|
||
$$ = new var_deconstructor_parameter($2, $4, true, @$);
|
||
}
|
||
| tkVar identifier
|
||
{
|
||
$$ = new var_deconstructor_parameter($2, null, true, @$);
|
||
}
|
||
| pattern_optional_var
|
||
{
|
||
$$ = new recursive_deconstructor_parameter($1 as pattern_node, @$);
|
||
}
|
||
| collection_pattern
|
||
{
|
||
$$ = new recursive_collection_parameter($1 as pattern_node, @$);
|
||
}
|
||
| tuple_pattern
|
||
{
|
||
$$ = new recursive_tuple_parameter($1 as pattern_node, @$);
|
||
}
|
||
;
|
||
|
||
simple_expr_or_nothing
|
||
: simple_expr
|
||
{
|
||
$$ = $1;
|
||
}
|
||
|
|
||
{
|
||
$$ = null;
|
||
}
|
||
;
|
||
|
||
const_expr_or_nothing
|
||
: const_expr
|
||
{
|
||
$$ = $1;
|
||
}
|
||
|
|
||
{
|
||
$$ = null;
|
||
}
|
||
;
|
||
/*
|
||
simple_expr_with_deref_or_nothing
|
||
: tkDeref simple_expr
|
||
{
|
||
$$ = new simple_expr_with_deref($2, true);
|
||
}
|
||
| simple_expr
|
||
{
|
||
$$ = new simple_expr_with_deref($1, false);
|
||
}
|
||
|
|
||
{
|
||
$$ = null;
|
||
}
|
||
;
|
||
|
||
simple_expr_with_deref
|
||
: simple_expr
|
||
{
|
||
$$ = new simple_expr_with_deref($1, false);
|
||
}
|
||
| tkDeref simple_expr
|
||
{
|
||
$$ = new simple_expr_with_deref($2, true);
|
||
}
|
||
;
|
||
*/
|
||
format_expr
|
||
: simple_expr tkColon simple_expr_or_nothing
|
||
{
|
||
$$ = new format_expr($1, $3, null, @$);
|
||
}
|
||
| tkColon simple_expr_or_nothing
|
||
{
|
||
$$ = new format_expr(null, $2, null, @$);
|
||
}
|
||
| simple_expr tkColon simple_expr_or_nothing tkColon simple_expr
|
||
{
|
||
$$ = new format_expr($1, $3, $5, @$);
|
||
}
|
||
| tkColon simple_expr_or_nothing tkColon simple_expr
|
||
{
|
||
$$ = new format_expr(null, $2, $4, @$);
|
||
}
|
||
;
|
||
|
||
format_const_expr
|
||
: const_expr tkColon const_expr_or_nothing
|
||
{
|
||
$$ = new format_expr($1, $3, null, @$);
|
||
}
|
||
| tkColon const_expr_or_nothing
|
||
{
|
||
$$ = new format_expr(null, $2, null, @$);
|
||
}
|
||
| const_expr tkColon const_expr_or_nothing tkColon const_expr
|
||
{
|
||
$$ = new format_expr($1, $3, $5, @$);
|
||
}
|
||
| tkColon const_expr_or_nothing tkColon const_expr
|
||
{
|
||
$$ = new format_expr(null, $2, $4, @$);
|
||
}
|
||
;
|
||
|
||
|
||
relop
|
||
: tkEqual
|
||
{ $$ = $1; }
|
||
| tkNotEqual
|
||
{ $$ = $1; }
|
||
| tkLower
|
||
{ $$ = $1; }
|
||
| tkGreater
|
||
{ $$ = $1; }
|
||
| tkLowerEqual
|
||
{ $$ = $1; }
|
||
| tkGreaterEqual
|
||
{ $$ = $1; }
|
||
| tkIn
|
||
{ $$ = $1; }
|
||
| tkNot tkIn
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = $2;
|
||
else
|
||
{
|
||
$$ = $2;
|
||
$$.type = Operators.NotIn;
|
||
}
|
||
}
|
||
;
|
||
|
||
simple_expr
|
||
: term1
|
||
{ $$ = $1; }
|
||
| simple_expr tkDotDot term1
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
$$ = new diapason_expr($1,$3,@$);
|
||
else
|
||
$$ = new diapason_expr_new($1,$3,@$);
|
||
}
|
||
;
|
||
|
||
term1
|
||
: term
|
||
{ $$ = $1; }
|
||
| term1 addop term
|
||
{
|
||
$$ = new bin_expr($1, $3, $2.type, @$);
|
||
}
|
||
| term1 addop new_question_expr
|
||
{
|
||
$$ = new bin_expr($1, $3, $2.type, @$);
|
||
}
|
||
;
|
||
|
||
addop
|
||
: tkPlus
|
||
{ $$ = $1; }
|
||
| tkMinus
|
||
{ $$ = $1; }
|
||
| tkOr
|
||
{ $$ = $1; }
|
||
| tkXor
|
||
{ $$ = $1; }
|
||
| tkCSharpStyleOr
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
typecast_op
|
||
: tkAs
|
||
{
|
||
$$ = op_typecast.as_op;
|
||
}
|
||
| tkIs
|
||
{
|
||
$$ = op_typecast.is_op;
|
||
}
|
||
;
|
||
|
||
as_is_expr
|
||
: is_type_expr
|
||
{ $$ = $1; }
|
||
| as_expr
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
as_expr
|
||
: term tkAs simple_or_template_type_reference
|
||
{
|
||
$$ = NewAsIsExpr($1, op_typecast.as_op, $3, @$);
|
||
}
|
||
| term tkAs array_type
|
||
{
|
||
$$ = NewAsIsExpr($1, op_typecast.as_op, $3, @$);
|
||
}
|
||
;
|
||
|
||
is_type_expr
|
||
: term tkIs simple_or_template_type_reference
|
||
{
|
||
$$ = NewAsIsExpr($1, op_typecast.is_op, $3, @$);
|
||
}
|
||
| term tkIs array_type
|
||
{
|
||
$$ = NewAsIsExpr($1, op_typecast.is_op, $3, @$);
|
||
}
|
||
;
|
||
|
||
power_expr
|
||
: factor_without_unary_op tkStarStar factor
|
||
{ $$ = new bin_expr($1,$3,($2).type, @$); }
|
||
| factor_without_unary_op tkStarStar power_expr
|
||
{ $$ = new bin_expr($1,$3,($2).type, @$); }
|
||
| sign power_expr
|
||
{ $$ = new un_expr($2, $1.type, @$); }
|
||
;
|
||
|
||
term
|
||
: factor
|
||
{ $$ = $1; }
|
||
| new_expr
|
||
{ $$ = $1; }
|
||
| power_expr
|
||
{ $$ = $1; }
|
||
| term mulop factor
|
||
{ $$ = new bin_expr($1,$3,($2).type, @$); }
|
||
| term mulop power_expr
|
||
{ $$ = new bin_expr($1,$3,($2).type, @$); }
|
||
| term mulop new_question_expr
|
||
{ $$ = new bin_expr($1,$3,($2).type, @$); }
|
||
| as_is_expr
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
mulop
|
||
: tkStar
|
||
{ $$ = $1; }
|
||
| tkSlash
|
||
{ $$ = $1; }
|
||
| tkDiv
|
||
{ $$ = $1; }
|
||
| tkMod
|
||
{ $$ = $1; }
|
||
| tkShl
|
||
{ $$ = $1; }
|
||
| tkShr
|
||
{ $$ = $1; }
|
||
| tkAnd
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
default_expr
|
||
: tkDefault tkRoundOpen simple_or_template_or_question_type_reference tkRoundClose
|
||
{
|
||
$$ = new default_operator($3 as named_type_reference, @$);
|
||
}
|
||
;
|
||
|
||
tuple
|
||
: tkRoundOpen expr_l1_or_unpacked tkComma expr_l1_or_unpacked_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose // lambda_type_ref optional_full_lambda_fp_list нужно оставить чтобы не было конфликтов с грамматикой лямбд
|
||
{
|
||
if ($2 is unpacked_list_of_ident_or_list)
|
||
parserTools.AddErrorFromResource("EXPRESSION_EXPECTED",@2);
|
||
foreach (var ex in ($4 as expression_list).expressions)
|
||
if (ex is unpacked_list_of_ident_or_list)
|
||
parserTools.AddErrorFromResource("EXPRESSION_EXPECTED",ex.source_context);
|
||
if (!($5 is lambda_inferred_type))
|
||
parserTools.AddErrorFromResource("BAD_TUPLE",@5);
|
||
if ($6 != null)
|
||
parserTools.AddErrorFromResource("BAD_TUPLE",@6);
|
||
|
||
if (($4 as expression_list).Count>6)
|
||
parserTools.AddErrorFromResource("TUPLE_ELEMENTS_COUNT_MUST_BE_LESSEQUAL_7",@$);
|
||
($4 as expression_list).Insert(0,$2);
|
||
$$ = new tuple_node($4 as expression_list,@$);
|
||
}
|
||
;
|
||
|
||
factor_without_unary_op
|
||
: literal_or_number
|
||
{ $$ = $1; }
|
||
| var_reference
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
factor
|
||
: tkNil
|
||
{
|
||
$$ = new nil_const();
|
||
$$.source_context = @$;
|
||
}
|
||
| literal_or_number
|
||
{ $$ = $1; }
|
||
| default_expr
|
||
{ $$ = $1; }
|
||
| tkSquareOpen elem_list tkSquareClose
|
||
{
|
||
$$ = new pascal_set_constant($2 as expression_list, @$);
|
||
}
|
||
| tkNot factor
|
||
{
|
||
$$ = new un_expr($2, $1.type, @$);
|
||
}
|
||
| sign factor
|
||
{
|
||
if ($1.type == Operators.Minus)
|
||
{
|
||
var i64 = $2 as int64_const;
|
||
if (i64 != null && i64.val == (Int64)Int32.MaxValue + 1)
|
||
{
|
||
$$ = new int32_const(Int32.MinValue,@$);
|
||
break;
|
||
}
|
||
var ui64 = $2 as uint64_const;
|
||
if (ui64 != null && ui64.val == (UInt64)Int64.MaxValue + 1)
|
||
{
|
||
$$ = new int64_const(Int64.MinValue,@$);
|
||
break;
|
||
}
|
||
if (ui64 != null && ui64.val > (UInt64)Int64.MaxValue + 1)
|
||
{
|
||
parserTools.AddErrorFromResource("BAD_INT2",@$);
|
||
break;
|
||
}
|
||
// можно сделать вычисление константы с вмонтированным минусом
|
||
}
|
||
$$ = new un_expr($2, $1.type, @$);
|
||
}
|
||
| tkDeref factor
|
||
{
|
||
$$ = new index($2, true, @$);
|
||
}
|
||
| var_reference
|
||
{ $$ = $1; }
|
||
| tuple
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
literal_or_number
|
||
: literal
|
||
{ $$ = $1; }
|
||
| unsigned_number
|
||
{ $$ = $1; }
|
||
/* | sign unsigned_number
|
||
{
|
||
$$ = new un_expr($2, $1.type, @$);
|
||
}*/
|
||
;
|
||
|
||
|
||
var_question_point
|
||
: variable tkQuestionPoint variable
|
||
{
|
||
$$ = new dot_question_node($1 as addressed_value,$3 as addressed_value,@$);
|
||
}
|
||
| variable tkQuestionPoint var_question_point
|
||
{
|
||
$$ = new dot_question_node($1 as addressed_value,$3 as addressed_value,@$);
|
||
}
|
||
;
|
||
|
||
var_reference
|
||
: var_address variable
|
||
{
|
||
$$ = NewVarReference($1 as get_address, $2 as addressed_value, @$);
|
||
}
|
||
| variable
|
||
{ $$ = $1; }
|
||
| var_question_point
|
||
{ $$ = $1; }
|
||
| tkRoundOpen tkVar identifier tkAssign expr_dq tkRoundClose
|
||
{ $$ = new let_var_expr($3,$5,@$); }
|
||
;
|
||
|
||
var_address
|
||
: tkAddressOf
|
||
{
|
||
$$ = NewVarAddress(@$);
|
||
}
|
||
| var_address tkAddressOf
|
||
{
|
||
$$ = NewVarAddress($1 as get_address, @$);
|
||
}
|
||
;
|
||
|
||
attribute_variable
|
||
: simple_type_identifier optional_expr_list_with_bracket
|
||
{
|
||
$$ = new attribute(null, $1 as named_type_reference, $2 as expression_list, @$);
|
||
}
|
||
| template_type optional_expr_list_with_bracket
|
||
{
|
||
$$ = new attribute(null, $1 as named_type_reference, $2 as expression_list, @$);
|
||
}
|
||
;
|
||
|
||
dotted_identifier
|
||
: identifier { $$ = $1; }
|
||
| dotted_identifier tkPoint identifier_or_keyword
|
||
{
|
||
if ($1 is index)
|
||
parserTools.AddErrorFromResource("UNEXPECTED_SYMBOL{0}", @1, "^");
|
||
$$ = new dot_node($1 as addressed_value, $3 as addressed_value, @$);
|
||
}
|
||
;
|
||
|
||
variable_as_type
|
||
: dotted_identifier { $$ = $1;}
|
||
| dotted_identifier template_type_params
|
||
{ $$ = new ident_with_templateparams($1 as addressed_value, $2 as template_param_list, @$); }
|
||
;
|
||
|
||
variable_or_literal_or_number
|
||
: variable
|
||
{ $$ = $1; }
|
||
| literal_or_number
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
var_with_init_for_expr_with_let
|
||
: tkVar identifier tkAssign expr tkSemiColon
|
||
{
|
||
$$ = new assign($2 as addressed_value, $4, Operators.Assignment, @$);
|
||
}
|
||
;
|
||
|
||
var_with_init_for_expr_with_let_list
|
||
: var_with_init_for_expr_with_let
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| var_with_init_for_expr_with_let_list var_with_init_for_expr_with_let
|
||
{
|
||
$1 = new statement_list($2 as statement, @$);
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
proc_func_call
|
||
: variable tkRoundOpen optional_expr_list_func_param tkRoundClose
|
||
{
|
||
if ($1 is index)
|
||
parserTools.AddErrorFromResource("UNEXPECTED_SYMBOL{0}", @1, "^");
|
||
$$ = new method_call($1 as addressed_value,$3 as expression_list, @$);
|
||
}
|
||
;
|
||
|
||
variable
|
||
: identifier
|
||
{ $$ = $1; }
|
||
| operator_name_ident
|
||
{ $$ = $1; }
|
||
| tkInherited identifier
|
||
{
|
||
$$ = new inherited_ident($2.name, @$);
|
||
}
|
||
| tkRoundOpen expr tkRoundClose
|
||
{
|
||
if (!parserTools.buildTreeForFormatter)
|
||
{
|
||
$2.source_context = @$;
|
||
$$ = $2;
|
||
}
|
||
else $$ = new bracket_expr($2, @$);
|
||
}
|
||
| tkRoundOpen var_with_init_for_expr_with_let_list expr tkRoundClose
|
||
{
|
||
if (!parserTools.buildTreeForFormatter)
|
||
{
|
||
$3.source_context = @$;
|
||
$$ = $3;
|
||
}
|
||
else $$ = new expression_with_let($2 as statement_list, $2 as expression, @$);
|
||
}
|
||
| sizeof_expr
|
||
{ $$ = $1; }
|
||
| typeof_expr
|
||
{ $$ = $1; }
|
||
| literal_or_number tkPoint identifier_or_keyword
|
||
{
|
||
if ($1 is index)
|
||
parserTools.AddErrorFromResource("UNEXPECTED_SYMBOL{0}", @1, "^");
|
||
$$ = new dot_node($1 as addressed_value, $3 as addressed_value, @$);
|
||
}
|
||
| variable_or_literal_or_number tkSquareOpen expr_list tkSquareClose
|
||
{
|
||
var el = $3 as expression_list; // SSM 10/03/16
|
||
if (el.Count==1 && el.expressions[0] is format_expr)
|
||
{
|
||
var fe = el.expressions[0] as format_expr;
|
||
if (!parserTools.buildTreeForFormatter)
|
||
{
|
||
if (fe.expr == null)
|
||
fe.expr = new int32_const(int.MaxValue,@3);
|
||
if (fe.format1 == null)
|
||
fe.format1 = new int32_const(int.MaxValue,@3);
|
||
}
|
||
$$ = new slice_expr($1 as addressed_value,fe.expr,fe.format1,fe.format2,@$);
|
||
}
|
||
// многомерные срезы
|
||
else if (el.expressions.Any(e => e is format_expr))
|
||
{
|
||
if (el.expressions.Count > 4)
|
||
parserTools.AddErrorFromResource("SLICES_OF MULTIDIMENSIONAL_ARRAYS_ALLOW_ONLY_FOR_RANK_LT_5",@$); // Срезы многомерных массивов разрешены только для массивов размерности < 5
|
||
var ll = new List<Tuple<expression, expression, expression>>();
|
||
foreach (var ex in el.expressions)
|
||
{
|
||
if (ex is format_expr fe)
|
||
{
|
||
if (fe.expr == null)
|
||
fe.expr = new int32_const(int.MaxValue, fe.source_context);
|
||
if (fe.format1 == null)
|
||
fe.format1 = new int32_const(int.MaxValue, fe.source_context);
|
||
if (fe.format2 == null)
|
||
fe.format2 = new int32_const(1, fe.source_context);
|
||
ll.Add(Tuple.Create(fe.expr, fe.format1, fe.format2));
|
||
}
|
||
else
|
||
{
|
||
ll.Add(Tuple.Create(ex, (expression)new int32_const(0, ex.source_context), (expression)new int32_const(int.MaxValue, ex.source_context))); // скалярное значение вместо среза
|
||
}
|
||
}
|
||
var sle = new slice_expr($1 as addressed_value,null,null,null,@$);
|
||
sle.slices = ll;
|
||
$$ = sle;
|
||
}
|
||
else $$ = new indexer($1 as addressed_value, el, @$);
|
||
}
|
||
| variable_or_literal_or_number tkQuestionSquareOpen format_expr tkSquareClose
|
||
{
|
||
var fe = $3 as format_expr; // SSM 9/01/17
|
||
if (!parserTools.buildTreeForFormatter)
|
||
{
|
||
if (fe.expr == null)
|
||
fe.expr = new int32_const(int.MaxValue,@3);
|
||
if (fe.format1 == null)
|
||
fe.format1 = new int32_const(int.MaxValue,@3);
|
||
}
|
||
$$ = new slice_expr_question($1 as addressed_value,fe.expr,fe.format1,fe.format2,@$);
|
||
}
|
||
| tkVertParen elem_list tkVertParen
|
||
{
|
||
$$ = new array_const_new($2 as expression_list, @$);
|
||
}
|
||
| proc_func_call
|
||
{ $$ = $1; }
|
||
| variable tkPoint identifier_keyword_operatorname
|
||
{
|
||
if ($1 is index)
|
||
parserTools.AddErrorFromResource("UNEXPECTED_SYMBOL{0}", @1, "^");
|
||
$$ = new dot_node($1 as addressed_value, $3 as addressed_value, @$);
|
||
}
|
||
| tuple tkPoint identifier_keyword_operatorname
|
||
{
|
||
$$ = new dot_node($1 as addressed_value, $3 as addressed_value, @$);
|
||
}
|
||
/*| variable tkQuestionPoint identifier_keyword_operatorname
|
||
{
|
||
$$ = new dot_question_node($1 as addressed_value, $3 as addressed_value, @$);
|
||
}*/
|
||
| variable tkDeref
|
||
{
|
||
$$ = new roof_dereference($1 as addressed_value,@$);
|
||
}
|
||
| variable tkAmpersend template_type_params
|
||
{
|
||
$$ = new ident_with_templateparams($1 as addressed_value, $3 as template_param_list, @$);
|
||
}
|
||
;
|
||
|
||
optional_expr_list
|
||
: expr_list
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
optional_expr_list_func_param
|
||
: expr_list_func_param
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
elem_list
|
||
: elem_list1
|
||
{ $$ = $1; }
|
||
|
|
||
{ $$ = null; }
|
||
;
|
||
|
||
elem_list1
|
||
: elem
|
||
{
|
||
$$ = new expression_list($1, @$);
|
||
}
|
||
| elem_list1 tkComma elem
|
||
{
|
||
$$ = ($1 as expression_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
elem
|
||
: expr
|
||
{ $$ = $1; }
|
||
| expr tkDotDot expr
|
||
{ $$ = new diapason_expr($1, $3, @$); }
|
||
;
|
||
|
||
one_literal
|
||
: tkStringLiteral
|
||
{ $$ = $1 as literal; }
|
||
| tkAsciiChar
|
||
{ $$ = $1 as literal; }
|
||
;
|
||
|
||
literal
|
||
:literal_list
|
||
{
|
||
$$ = NewLiteral($1 as literal_const_line);
|
||
}
|
||
| tkFormatStringLiteral
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
{
|
||
$$ = $1 as string_const;
|
||
}
|
||
else
|
||
{
|
||
$$ = NewFormatString($1 as string_const);
|
||
}
|
||
}
|
||
| tkMultilineStringLiteral
|
||
{
|
||
if (parserTools.buildTreeForFormatter)
|
||
{
|
||
var sc = $1 as string_const;
|
||
sc.IsMultiline = true;
|
||
$$ = sc;
|
||
}
|
||
else
|
||
{
|
||
$$ = NewLiteral(new literal_const_line($1 as literal, @$));
|
||
}
|
||
}
|
||
;
|
||
|
||
literal_list
|
||
: one_literal
|
||
{
|
||
$$ = new literal_const_line($1 as literal, @$);
|
||
}
|
||
| literal_list one_literal
|
||
{
|
||
var line = $1 as literal_const_line;
|
||
if (line.literals.Last() is string_const && $2 is string_const)
|
||
parserTools.AddErrorFromResource("TWO_STRING_LITERALS_IN_SUCCESSION",@2);
|
||
$$ = line.Add($2 as literal, @$);
|
||
}
|
||
;
|
||
|
||
operator_name_ident
|
||
: tkOperator overload_operator
|
||
{
|
||
$$ = new operator_name_ident(($2 as op_type_node).text, ($2 as op_type_node).type, @$);
|
||
}
|
||
;
|
||
|
||
optional_method_modificators
|
||
: tkSemiColon
|
||
{
|
||
$$ = new procedure_attributes_list(new List<procedure_attribute>(),@$);
|
||
}
|
||
| tkSemiColon meth_modificators tkSemiColon
|
||
{
|
||
//parserTools.AddModifier((procedure_attributes_list)$2, proc_attribute.attr_overload);
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
optional_method_modificators1
|
||
:
|
||
{
|
||
$$ = new procedure_attributes_list(new List<procedure_attribute>(),@$);
|
||
}
|
||
| tkSemiColon meth_modificators
|
||
{
|
||
//parserTools.AddModifier((procedure_attributes_list)$2, proc_attribute.attr_overload);
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
meth_modificators
|
||
: meth_modificator
|
||
{
|
||
$$ = new procedure_attributes_list($1 as procedure_attribute, @$);
|
||
}
|
||
| meth_modificators tkSemiColon meth_modificator
|
||
{
|
||
$$ = ($1 as procedure_attributes_list).Add($3 as procedure_attribute, @$);
|
||
}
|
||
;
|
||
|
||
identifier
|
||
: tkIdentifier
|
||
{ $$ = $1; }
|
||
| property_specifier_directives
|
||
{ $$ = $1; }
|
||
| non_reserved
|
||
{ $$ = $1; }
|
||
| tkStep
|
||
{ $$ = new ident($1.text, @$); }
|
||
| tkIndex
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
identifier_or_keyword
|
||
: identifier
|
||
{ $$ = $1; }
|
||
| keyword
|
||
{ $$ = new ident($1.text, @$); }
|
||
| reserved_keyword
|
||
{ $$ = new ident($1.text, @$); }
|
||
;
|
||
|
||
identifier_keyword_operatorname
|
||
: identifier
|
||
{ $$ = $1; }
|
||
| keyword
|
||
{ $$ = new ident($1.text, @$); }
|
||
| operator_name_ident
|
||
{ $$ = (ident)$1; }
|
||
;
|
||
|
||
meth_modificator
|
||
: tkAbstract
|
||
{ $$ = $1; }
|
||
| tkOverload
|
||
{
|
||
$$ = $1;
|
||
parserTools.AddWarningFromResource("OVERLOAD_IS_NOT_USED", $1.source_context);
|
||
}
|
||
| tkReintroduce
|
||
{ $$ = $1; }
|
||
| tkOverride
|
||
{ $$ = $1; }
|
||
| tkExtensionMethod
|
||
{ $$ = $1; }
|
||
| tkVirtual
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
property_modificator
|
||
: tkVirtual
|
||
{ $$ = $1; }
|
||
| tkOverride
|
||
{ $$ = $1; }
|
||
| tkAbstract
|
||
{ $$ = $1; }
|
||
| tkReintroduce
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
property_specifier_directives
|
||
: tkRead
|
||
{ $$ = $1; }
|
||
| tkWrite
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
non_reserved
|
||
: tkName
|
||
{ $$ = $1; }
|
||
| tkNew
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
visibility_specifier
|
||
: tkInternal
|
||
{ $$ = $1; }
|
||
| tkPublic
|
||
{ $$ = $1; }
|
||
| tkProtected
|
||
{ $$ = $1; }
|
||
| tkPrivate
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
keyword
|
||
: visibility_specifier
|
||
{
|
||
$$ = new token_info($1.name, @$);
|
||
}
|
||
| tkSealed
|
||
{ $$ = $1; }
|
||
| tkTemplate
|
||
{ $$ = $1; }
|
||
| tkOr
|
||
{ $$ = $1; }
|
||
| tkTypeOf
|
||
{ $$ = $1; }
|
||
| tkSizeOf
|
||
{ $$ = $1; }
|
||
| tkDefault
|
||
{ $$ = $1; }
|
||
| tkWhere
|
||
{ $$ = $1; }
|
||
| tkXor
|
||
{ $$ = $1; }
|
||
| tkAnd
|
||
{ $$ = $1; }
|
||
| tkDiv
|
||
{ $$ = $1; }
|
||
| tkMod
|
||
{ $$ = $1; }
|
||
| tkShl
|
||
{ $$ = $1; }
|
||
| tkShr
|
||
{ $$ = $1; }
|
||
| tkNot
|
||
{ $$ = $1; }
|
||
| tkAs
|
||
{ $$ = $1; }
|
||
| tkIn
|
||
{ $$ = $1; }
|
||
| tkIs
|
||
{ $$ = $1; }
|
||
| tkArray
|
||
{ $$ = $1; }
|
||
| tkSequence
|
||
{ $$ = $1; }
|
||
| tkBegin
|
||
{ $$ = $1; }
|
||
| tkCase
|
||
{ $$ = $1; }
|
||
| tkClass
|
||
{ $$ = $1; }
|
||
| tkConst
|
||
{ $$ = $1; }
|
||
| tkConstructor
|
||
{ $$ = $1; }
|
||
| tkDestructor
|
||
{ $$ = $1; }
|
||
| tkDownto
|
||
{ $$ = $1; }
|
||
| tkDo
|
||
{ $$ = $1; }
|
||
| tkElse
|
||
{ $$ = $1; }
|
||
| tkEnd
|
||
{ $$ = $1; }
|
||
| tkExcept
|
||
{ $$ = $1; }
|
||
| tkFile
|
||
{ $$ = $1; }
|
||
| tkAuto
|
||
{ $$ = $1; }
|
||
| tkFinalization
|
||
{ $$ = $1; }
|
||
| tkFinally
|
||
{ $$ = $1; }
|
||
| tkFor
|
||
{ $$ = $1; }
|
||
| tkForeach
|
||
{ $$ = $1; }
|
||
| tkFunction
|
||
{ $$ = $1; }
|
||
| tkIf
|
||
{ $$ = $1; }
|
||
| tkImplementation
|
||
{ $$ = $1; }
|
||
| tkInherited
|
||
{ $$ = $1; }
|
||
| tkInitialization
|
||
{ $$ = $1; }
|
||
| tkInterface
|
||
{ $$ = $1; }
|
||
| tkProcedure
|
||
{ $$ = $1; }
|
||
| tkProperty
|
||
{ $$ = $1; }
|
||
| tkRaise
|
||
{ $$ = $1; }
|
||
| tkRecord
|
||
{ $$ = $1; }
|
||
| tkRepeat
|
||
{ $$ = $1; }
|
||
| tkSet
|
||
{ $$ = $1; }
|
||
| tkTry
|
||
{ $$ = $1; }
|
||
| tkType
|
||
{ $$ = $1; }
|
||
| tkStatic
|
||
{ $$ = $1; }
|
||
| tkThen
|
||
{ $$ = $1; }
|
||
| tkTo
|
||
{ $$ = $1; }
|
||
| tkUntil
|
||
{ $$ = $1; }
|
||
| tkUses
|
||
{ $$ = $1; }
|
||
| tkVar
|
||
{ $$ = $1; }
|
||
| tkWhile
|
||
{ $$ = $1; }
|
||
| tkWith
|
||
{ $$ = $1; }
|
||
| tkNil
|
||
{ $$ = $1; }
|
||
| tkGoto
|
||
{ $$ = $1; }
|
||
| tkOf
|
||
{ $$ = $1; }
|
||
| tkLabel
|
||
{ $$ = $1; }
|
||
| tkProgram
|
||
{ $$ = $1; }
|
||
| tkUnit
|
||
{ $$ = $1; }
|
||
| tkLibrary
|
||
{ $$ = $1; }
|
||
| tkNamespace
|
||
{ $$ = $1; }
|
||
| tkExternal
|
||
{ $$ = $1; }
|
||
| tkParams
|
||
{ $$ = $1; }
|
||
| tkEvent
|
||
{ $$ = $1; }
|
||
| tkYield
|
||
{ $$ = $1; }
|
||
| tkMatch
|
||
{ $$ = $1; }
|
||
| tkWhen
|
||
{ $$ = $1; }
|
||
| tkPartial
|
||
{ $$ = $1; }
|
||
| tkAbstract
|
||
{ $$ = new token_info($1.name, @$); }
|
||
| tkLock
|
||
{ $$ = $1; }
|
||
| tkImplicit
|
||
{ $$ = $1; }
|
||
| tkExplicit
|
||
{ $$ = $1; }
|
||
| tkOn
|
||
{ $$ = new token_info($1.name, @$); }
|
||
| tkVirtual
|
||
{ $$ = new token_info($1.name, @$); }
|
||
| tkOverride
|
||
{ $$ = new token_info($1.name, @$); }
|
||
| tkLoop
|
||
{ $$ = $1; }
|
||
| tkExtensionMethod
|
||
{ $$ = new token_info($1.name, @$); }
|
||
| tkOverload
|
||
{ $$ = new token_info($1.name, @$); }
|
||
| tkReintroduce
|
||
{ $$ = new token_info($1.name, @$); }
|
||
| tkForward
|
||
{ $$ = new token_info($1.name, @$); }
|
||
;
|
||
|
||
reserved_keyword
|
||
: tkOperator
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
overload_operator
|
||
: tkMinus
|
||
{ $$ = $1; }
|
||
| tkPlus
|
||
{ $$ = $1; }
|
||
| tkSlash
|
||
{ $$ = $1; }
|
||
| tkStar
|
||
{ $$ = $1; }
|
||
| tkEqual
|
||
{ $$ = $1; }
|
||
| tkGreater
|
||
{ $$ = $1; }
|
||
| tkGreaterEqual
|
||
{ $$ = $1; }
|
||
| tkLower
|
||
{ $$ = $1; }
|
||
| tkLowerEqual
|
||
{ $$ = $1; }
|
||
| tkNotEqual
|
||
{ $$ = $1; }
|
||
| tkOr
|
||
{ $$ = $1; }
|
||
| tkXor
|
||
{ $$ = $1; }
|
||
| tkAnd
|
||
{ $$ = $1; }
|
||
| tkDiv
|
||
{ $$ = $1; }
|
||
| tkMod
|
||
{ $$ = $1; }
|
||
| tkShl
|
||
{ $$ = $1; }
|
||
| tkShr
|
||
{ $$ = $1; }
|
||
| tkNot
|
||
{ $$ = $1; }
|
||
| tkIn
|
||
{ $$ = $1; }
|
||
| tkImplicit
|
||
{ $$ = $1; }
|
||
| tkExplicit
|
||
{ $$ = $1; }
|
||
| assign_operator
|
||
{ $$ = $1; }
|
||
| tkStarStar
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
assign_operator
|
||
: tkAssign
|
||
{ $$ = $1; }
|
||
| tkPlusEqual
|
||
{ $$ = $1; }
|
||
| tkMinusEqual
|
||
{ $$ = $1; }
|
||
| tkMultEqual
|
||
{ $$ = $1; }
|
||
| tkDivEqual
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
lambda_unpacked_params
|
||
: tkBackSlashRoundOpen lambda_list_of_unpacked_params_or_id tkComma lambda_unpacked_params_or_id tkRoundClose
|
||
{
|
||
// результат надо присвоить какому то сахарному полю в function_lambda_definition
|
||
($2 as unpacked_list_of_ident_or_list).Add($4 as ident_or_list);
|
||
$$ = $2 as unpacked_list_of_ident_or_list;
|
||
}
|
||
;
|
||
|
||
lambda_unpacked_params_or_id
|
||
: lambda_unpacked_params // ident_or_list
|
||
{
|
||
$$ = new ident_or_list($1 as unpacked_list_of_ident_or_list);
|
||
}
|
||
| identifier // ident_or_list
|
||
{
|
||
$$ = new ident_or_list($1 as ident);
|
||
}
|
||
;
|
||
|
||
lambda_list_of_unpacked_params_or_id
|
||
: lambda_unpacked_params_or_id
|
||
{
|
||
$$ = new unpacked_list_of_ident_or_list();
|
||
($$ as unpacked_list_of_ident_or_list).Add($1 as ident_or_list);
|
||
($$ as unpacked_list_of_ident_or_list).source_context = @1;
|
||
}
|
||
| lambda_list_of_unpacked_params_or_id tkComma lambda_unpacked_params_or_id
|
||
{
|
||
$$ = $1;
|
||
($$ as unpacked_list_of_ident_or_list).Add($3 as ident_or_list);
|
||
($$ as unpacked_list_of_ident_or_list).source_context = LexLocation.MergeAll(@1,@3);
|
||
}
|
||
;
|
||
|
||
|
||
expr_l1_or_unpacked
|
||
: expr_l1
|
||
{ $$ = $1; }
|
||
| lambda_unpacked_params
|
||
{ $$ = $1; }
|
||
;
|
||
|
||
|
||
expr_l1_or_unpacked_list
|
||
: expr_l1_or_unpacked
|
||
{
|
||
$$ = new expression_list($1, @$);
|
||
}
|
||
| expr_l1_or_unpacked_list tkComma expr_l1_or_unpacked
|
||
{
|
||
$$ = ($1 as expression_list).Add($3, @$);
|
||
}
|
||
;
|
||
|
||
func_decl_lambda
|
||
: identifier tkArrow lambda_function_body
|
||
{
|
||
var idList = new ident_list($1, @1);
|
||
var formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new lambda_any_type_node_syntax(), @1), parametr_kind.none, null, @1), @1);
|
||
//var sl = $3 as statement_list;
|
||
//if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName($3, "Result") != null) // если это было выражение или есть переменная Result, то автовывод типа
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, new lambda_inferred_type(new lambda_any_type_node_syntax(), @1), $3 as statement_list, @$);
|
||
//else
|
||
//$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, $3 as statement_list, @$);
|
||
}
|
||
| tkRoundOpen tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body
|
||
{
|
||
// Здесь надо анализировать по телу и либо оставлять lambda_inferred_type, либо делать его null!
|
||
var sl = $5 as statement_list;
|
||
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $3, sl, @$);
|
||
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, null, sl, @$);
|
||
}
|
||
| tkRoundOpen identifier tkColon fptype tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body
|
||
{
|
||
var idList = new ident_list($2, @2);
|
||
var loc = LexLocation.MergeAll(@2,@3,@4);
|
||
var formalPars = new formal_parameters(new typed_parameters(idList, $4, parametr_kind.none, null, loc), loc);
|
||
var sl = $8 as statement_list;
|
||
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $6, sl, @$);
|
||
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$);
|
||
}
|
||
| tkRoundOpen identifier tkSemiColon full_lambda_fp_list tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body
|
||
{
|
||
var idList = new ident_list($2, @2);
|
||
var formalPars = new formal_parameters(new typed_parameters(idList, new lambda_inferred_type(new lambda_any_type_node_syntax(), null), parametr_kind.none, null, @2), LexLocation.MergeAll(@2,@3,@4));
|
||
for (int i = 0; i < ($4 as formal_parameters).Count; i++)
|
||
formalPars.Add(($4 as formal_parameters).params_list[i]);
|
||
var sl = $8 as statement_list;
|
||
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $6, sl, @$);
|
||
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$);
|
||
}
|
||
| tkRoundOpen identifier tkColon fptype tkSemiColon full_lambda_fp_list tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body
|
||
{
|
||
var idList = new ident_list($2, @2);
|
||
var loc = LexLocation.MergeAll(@2,@3,@4);
|
||
var formalPars = new formal_parameters(new typed_parameters(idList, $4, parametr_kind.none, null, loc), LexLocation.MergeAll(@2,@3,@4,@5,@6));
|
||
for (int i = 0; i < ($6 as formal_parameters).Count; i++)
|
||
formalPars.Add(($6 as formal_parameters).params_list[i]);
|
||
var sl = $10 as statement_list;
|
||
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, $8, sl, @$);
|
||
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, sl, @$);
|
||
}
|
||
| tkRoundOpen expr_l1_or_unpacked tkComma expr_l1_or_unpacked_list lambda_type_ref optional_full_lambda_fp_list tkRoundClose rem_lambda // optional_full_lambda_fp_list - так сделано из-за конфликтов в граматике
|
||
{
|
||
var pair = $8 as pair_type_stlist;
|
||
|
||
if ($5 is lambda_inferred_type)
|
||
{
|
||
// добавим сюда \(x,y)
|
||
// Пройтись по всем expr_list1. Если хотя бы одна - типа ident_or_list то пойти по этой ветке и выйти
|
||
// убедиться, что $6 = null
|
||
// сформировать List<expression> для unpacked_params и присвоить
|
||
var has_unpacked = false;
|
||
if ($2 is unpacked_list_of_ident_or_list)
|
||
has_unpacked = true;
|
||
if (!has_unpacked)
|
||
foreach (var x in ($4 as expression_list).expressions)
|
||
{
|
||
if (x is unpacked_list_of_ident_or_list)
|
||
{
|
||
has_unpacked = true;
|
||
break;
|
||
}
|
||
}
|
||
if (has_unpacked) // тут новая ветка
|
||
{
|
||
if ($6 != null)
|
||
{
|
||
parserTools.AddErrorFromResource("SEMICOLON_IN_PARAMS",@6);
|
||
}
|
||
|
||
var lst_ex = new List<expression>();
|
||
lst_ex.Add($2 as expression);
|
||
foreach (var x in ($4 as expression_list).expressions)
|
||
lst_ex.Add(x);
|
||
|
||
function_lambda_definition fld = null; //= new function_lambda_definition(lambdaHelper.CreateLambdaName(), null,
|
||
//new lambda_inferred_type(new lambda_any_type_node_syntax(), @2), pair.exprs, @$);
|
||
|
||
var sl1 = pair.exprs;
|
||
if (sl1.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl1, "result") != null) // то надо выводить
|
||
fld = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, pair.tn, pair.exprs, @$);
|
||
else fld = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, null, pair.exprs, @$);
|
||
|
||
fld.unpacked_params = lst_ex;
|
||
$$ = fld;
|
||
return;
|
||
}
|
||
|
||
var formal_pars = new formal_parameters();
|
||
var idd = $2 as ident;
|
||
if (idd==null)
|
||
parserTools.AddErrorFromResource("ONE_TKIDENTIFIER",@2);
|
||
var lambda_inf_type = new lambda_inferred_type(new lambda_any_type_node_syntax(), null);
|
||
var new_typed_pars = new typed_parameters(new ident_list(idd, idd.source_context), lambda_inf_type, parametr_kind.none, null, idd.source_context);
|
||
formal_pars.Add(new_typed_pars);
|
||
foreach (var id in ($4 as expression_list).expressions)
|
||
{
|
||
var idd1 = id as ident;
|
||
if (idd1==null)
|
||
parserTools.AddErrorFromResource("ONE_TKIDENTIFIER",id.source_context);
|
||
|
||
lambda_inf_type = new lambda_inferred_type(new lambda_any_type_node_syntax(), null);
|
||
new_typed_pars = new typed_parameters(new ident_list(idd1, idd1.source_context), lambda_inf_type, parametr_kind.none, null, idd1.source_context);
|
||
formal_pars.Add(new_typed_pars);
|
||
}
|
||
|
||
if ($6 != null)
|
||
for (int i = 0; i < ($6 as formal_parameters).Count; i++)
|
||
formal_pars.Add(($6 as formal_parameters).params_list[i]);
|
||
|
||
formal_pars.source_context = LexLocation.MergeAll(@2,@3,@4,@5);
|
||
|
||
var sl = pair.exprs;
|
||
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formal_pars, pair.tn, pair.exprs, @$);
|
||
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formal_pars, null, pair.exprs, @$);
|
||
}
|
||
else
|
||
{
|
||
var loc = LexLocation.MergeAll(@2,@3,@4);
|
||
var idd = $2 as ident;
|
||
if (idd==null)
|
||
parserTools.AddErrorFromResource("ONE_TKIDENTIFIER",@2);
|
||
|
||
var idList = new ident_list(idd, loc);
|
||
|
||
var iddlist = ($4 as expression_list).expressions;
|
||
|
||
for (int j = 0; j < iddlist.Count; j++)
|
||
{
|
||
var idd2 = iddlist[j] as ident;
|
||
if (idd2==null)
|
||
parserTools.AddErrorFromResource("ONE_TKIDENTIFIER",idd2.source_context);
|
||
idList.Add(idd2);
|
||
}
|
||
var parsType = $5;
|
||
var formalPars = new formal_parameters(new typed_parameters(idList, parsType, parametr_kind.none, null, LexLocation.MergeAll(@2,@3,@4,@5)), LexLocation.MergeAll(@2,@3,@4,@5,@6));
|
||
|
||
if ($6 != null)
|
||
for (int i = 0; i < ($6 as formal_parameters).Count; i++)
|
||
formalPars.Add(($6 as formal_parameters).params_list[i]);
|
||
|
||
var sl = pair.exprs;
|
||
if (sl.expr_lambda_body || SyntaxVisitors.HasNameVisitor.HasName(sl, "result") != null) // то надо выводить
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, pair.tn, pair.exprs, @$);
|
||
else $$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), formalPars, null, pair.exprs, @$);
|
||
}
|
||
}
|
||
| lambda_unpacked_params rem_lambda // лямбда с распаковкой
|
||
{
|
||
var pair = $2 as pair_type_stlist;
|
||
// пока формальные параметры - null. Раскроем их сахарным визитором
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null,
|
||
new lambda_inferred_type(new lambda_any_type_node_syntax(), @1), pair.exprs, @$);
|
||
// unpacked_params - это для одного параметра. Для нескольких - надо другую структуру. Возможно, список списков
|
||
var lst_ex = new List<expression>();
|
||
lst_ex.Add($1 as unpacked_list_of_ident_or_list);
|
||
($$ as function_lambda_definition).unpacked_params = lst_ex;
|
||
}
|
||
| expl_func_decl_lambda
|
||
{
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
optional_full_lambda_fp_list
|
||
: { $$ = null; }
|
||
| tkSemiColon full_lambda_fp_list
|
||
{
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
rem_lambda
|
||
: lambda_type_ref_noproctype tkArrow lambda_function_body
|
||
{
|
||
$$ = new pair_type_stlist($1,$3 as statement_list);
|
||
}
|
||
;
|
||
|
||
expl_func_decl_lambda
|
||
: tkFunction lambda_type_ref_noproctype tkArrow lambda_function_body // SSM 11.08.20 добавил _noproctype в 3 подправилах
|
||
{
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $2, $4 as statement_list, 1, @$);
|
||
}
|
||
| tkFunction tkRoundOpen tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body
|
||
{
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, $4, $6 as statement_list, 1, @$);
|
||
}
|
||
| tkFunction tkRoundOpen full_lambda_fp_list tkRoundClose lambda_type_ref_noproctype tkArrow lambda_function_body
|
||
{
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), $3 as formal_parameters, $5, $7 as statement_list, 1, @$);
|
||
}
|
||
| tkProcedure tkArrow lambda_procedure_body
|
||
{
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, null, $3 as statement_list, 2, @$);
|
||
}
|
||
| tkProcedure tkRoundOpen tkRoundClose tkArrow lambda_procedure_body
|
||
{
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), null, null, $5 as statement_list, 2, @$);
|
||
}
|
||
| tkProcedure tkRoundOpen full_lambda_fp_list tkRoundClose tkArrow lambda_procedure_body
|
||
{
|
||
$$ = new function_lambda_definition(lambdaHelper.CreateLambdaName(), $3 as formal_parameters, null, $6 as statement_list, 2, @$);
|
||
}
|
||
;
|
||
|
||
full_lambda_fp_list
|
||
: lambda_simple_fp_sect
|
||
{
|
||
var typed_pars = $1 as typed_parameters;
|
||
if (typed_pars.vars_type is lambda_inferred_type)
|
||
{
|
||
$$ = new formal_parameters();
|
||
foreach (var id in typed_pars.idents.idents)
|
||
{
|
||
var lambda_inf_type = new lambda_inferred_type(new lambda_any_type_node_syntax(), null);
|
||
var new_typed_pars = new typed_parameters(new ident_list(id, id.source_context), lambda_inf_type, parametr_kind.none, null, id.source_context);
|
||
($$ as formal_parameters).Add(new_typed_pars);
|
||
}
|
||
$$.source_context = @$;
|
||
}
|
||
else
|
||
{
|
||
$$ = new formal_parameters(typed_pars, @$);
|
||
}
|
||
}
|
||
| full_lambda_fp_list tkSemiColon lambda_simple_fp_sect
|
||
{
|
||
$$ =($1 as formal_parameters).Add($3 as typed_parameters, @$);
|
||
}
|
||
;
|
||
|
||
lambda_simple_fp_sect
|
||
: ident_list lambda_type_ref
|
||
{
|
||
$$ = new typed_parameters($1 as ident_list, $2, parametr_kind.none, null, @$);
|
||
}
|
||
;
|
||
|
||
lambda_type_ref
|
||
:
|
||
{
|
||
$$ = new lambda_inferred_type(new lambda_any_type_node_syntax(), null);
|
||
}
|
||
| tkColon fptype
|
||
{
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
lambda_type_ref_noproctype
|
||
:
|
||
{
|
||
$$ = new lambda_inferred_type(new lambda_any_type_node_syntax(), null);
|
||
}
|
||
| tkColon fptype_noproctype
|
||
{
|
||
$$ = $2;
|
||
}
|
||
;
|
||
|
||
common_lambda_body
|
||
: compound_stmt
|
||
{
|
||
$$ = $1;
|
||
}
|
||
| if_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| while_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| repeat_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| for_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| foreach_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| loop_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| case_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| try_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| lock_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| raise_stmt
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| yield_stmt
|
||
{
|
||
parserTools.AddErrorFromResource("YIELD_STATEMENT_CANNOT_BE_USED_IN_LAMBDA_BODY", @$);
|
||
}
|
||
| tkRoundOpen assignment tkRoundClose
|
||
{
|
||
$$ = new statement_list($2 as statement, @2);
|
||
}
|
||
;
|
||
|
||
|
||
lambda_function_body
|
||
: expr_l1_for_lambda
|
||
{
|
||
var id = SyntaxVisitors.HasNameVisitor.HasName($1, "Result");
|
||
if (id != null)
|
||
{
|
||
parserTools.AddErrorFromResource("RESULT_IDENT_NOT_EXPECTED_IN_THIS_CONTEXT", id.source_context);
|
||
}
|
||
var sl = new statement_list(new assign("result",$1,@$),@$); // надо помечать ещё и assign как автосгенерированный для лямбды - чтобы запретить явный Result
|
||
sl.expr_lambda_body = true;
|
||
$$ = sl;
|
||
}
|
||
| common_lambda_body
|
||
{
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
lambda_procedure_body
|
||
: proc_call
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| assignment
|
||
{
|
||
$$ = new statement_list($1 as statement, @$);
|
||
}
|
||
| common_lambda_body
|
||
{
|
||
$$ = $1;
|
||
}
|
||
;
|
||
|
||
%% |