diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs index 86f279b39..66973bbf6 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.cs @@ -2,7 +2,7 @@ // This CSharp output file generated by Gardens Point LEX // Version: 1.1.3.301 // Machine: DESKTOP-G8V08V4 -// DateTime: 06.01.2020 1:08:55 +// DateTime: 06.01.2020 19:58:31 // UserName: ????????? // GPLEX input file // GPLEX frame file diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y index e1833bc60..3fed6d5d5 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascal.y +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascal.y @@ -3166,9 +3166,16 @@ question_expr } | tkIf expr_dq tkThen expr_l1 tkElse expr_l1 { - if ($4 is nil_const && $6 is nil_const) - parsertools.AddErrorFromResource("TWO_NILS_IN_QUESTION_EXPR",@4); - $$ = new question_colon_expression($2, $4, $6, @$); + if (parsertools.build_tree_for_formatter) + { + $$ = 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, @$); + } } ; diff --git a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs index e89628257..578936434 100644 --- a/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs +++ b/Parsers/PascalABCParserNewSaushkin/ABCPascalYacc.cs @@ -2,7 +2,7 @@ // GPPG version 1.3.6 // Machine: DESKTOP-G8V08V4 -// DateTime: 06.01.2020 1:08:55 +// DateTime: 06.01.2020 19:58:32 // UserName: ????????? // Input file @@ -5491,9 +5491,16 @@ public partial class GPPGParser: ShiftReduceParser tkIf, expr_dq, tkThen, expr_l1, tkElse, expr_l1 { - if (ValueStack[ValueStack.Depth-3].ex is nil_const && ValueStack[ValueStack.Depth-1].ex is nil_const) - parsertools.AddErrorFromResource("TWO_NILS_IN_QUESTION_EXPR",LocationStack[LocationStack.Depth-3]); - CurrentSemanticValue.ex = new question_colon_expression(ValueStack[ValueStack.Depth-5].ex, ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + if (parsertools.build_tree_for_formatter) + { + CurrentSemanticValue.ex = new if_expr_new(ValueStack[ValueStack.Depth-5].ex, ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } + else + { + if (ValueStack[ValueStack.Depth-3].ex is nil_const && ValueStack[ValueStack.Depth-1].ex is nil_const) + parsertools.AddErrorFromResource("TWO_NILS_IN_QUESTION_EXPR",LocationStack[LocationStack.Depth-3]); + CurrentSemanticValue.ex = new question_colon_expression(ValueStack[ValueStack.Depth-5].ex, ValueStack[ValueStack.Depth-3].ex, ValueStack[ValueStack.Depth-1].ex, CurrentLocationSpan); + } } break; case 592: // empty_template_type_reference -> simple_type_identifier, diff --git a/Parsers/PascalABCParserNewSaushkin/PABC.ymc b/Parsers/PascalABCParserNewSaushkin/PABC.ymc index 41181fd73..86f5779d3 100644 --- a/Parsers/PascalABCParserNewSaushkin/PABC.ymc +++ b/Parsers/PascalABCParserNewSaushkin/PABC.ymc @@ -256,5 +256,6 @@ script= + diff --git a/SyntaxTree/tree/AbstractVisitor.cs b/SyntaxTree/tree/AbstractVisitor.cs index 0fbd1aaf0..755e907e9 100644 --- a/SyntaxTree/tree/AbstractVisitor.cs +++ b/SyntaxTree/tree/AbstractVisitor.cs @@ -1257,6 +1257,11 @@ namespace PascalABCCompiler.SyntaxTree { DefaultVisit(_diapason_expr_new); } + + public virtual void visit(if_expr_new _if_expr_new) + { + DefaultVisit(_if_expr_new); + } } diff --git a/SyntaxTree/tree/HierarchyVisitor.cs b/SyntaxTree/tree/HierarchyVisitor.cs index 9d6a9f301..4380680d9 100644 --- a/SyntaxTree/tree/HierarchyVisitor.cs +++ b/SyntaxTree/tree/HierarchyVisitor.cs @@ -2005,6 +2005,14 @@ namespace PascalABCCompiler.SyntaxTree { } + public virtual void pre_do_visit(if_expr_new _if_expr_new) + { + } + + public virtual void post_do_visit(if_expr_new _if_expr_new) + { + } + public override void visit(expression _expression) { DefaultVisit(_expression); @@ -4140,6 +4148,16 @@ namespace PascalABCCompiler.SyntaxTree visit(diapason_expr_new.right); post_do_visit(_diapason_expr_new); } + + public override void visit(if_expr_new _if_expr_new) + { + DefaultVisit(_if_expr_new); + pre_do_visit(_if_expr_new); + visit(if_expr_new.condition); + visit(if_expr_new.if_true); + visit(if_expr_new.if_false); + post_do_visit(_if_expr_new); + } } diff --git a/SyntaxTree/tree/SyntaxTreeStreamReader.cs b/SyntaxTree/tree/SyntaxTreeStreamReader.cs index 1d73fc876..ea74a627a 100644 --- a/SyntaxTree/tree/SyntaxTreeStreamReader.cs +++ b/SyntaxTree/tree/SyntaxTreeStreamReader.cs @@ -520,6 +520,8 @@ namespace PascalABCCompiler.SyntaxTree return new recursive_tuple_parameter(); case 249: return new diapason_expr_new(); + case 250: + return new if_expr_new(); } return null; } @@ -4370,6 +4372,20 @@ namespace PascalABCCompiler.SyntaxTree _diapason_expr_new.right = _read_node() as expression; } + + public void visit(if_expr_new _if_expr_new) + { + read_if_expr_new(_if_expr_new); + } + + public void read_if_expr_new(if_expr_new _if_expr_new) + { + read_expression(_if_expr_new); + _if_expr_new.condition = _read_node() as expression; + _if_expr_new.if_true = _read_node() as expression; + _if_expr_new.if_false = _read_node() as expression; + } + } diff --git a/SyntaxTree/tree/SyntaxTreeStreamWriter.cs b/SyntaxTree/tree/SyntaxTreeStreamWriter.cs index b319cdc34..f70c17675 100644 --- a/SyntaxTree/tree/SyntaxTreeStreamWriter.cs +++ b/SyntaxTree/tree/SyntaxTreeStreamWriter.cs @@ -6825,6 +6825,45 @@ namespace PascalABCCompiler.SyntaxTree } } + + public void visit(if_expr_new _if_expr_new) + { + bw.Write((Int16)250); + write_if_expr_new(_if_expr_new); + } + + public void write_if_expr_new(if_expr_new _if_expr_new) + { + write_expression(_if_expr_new); + if (_if_expr_new.condition == null) + { + bw.Write((byte)0); + } + else + { + bw.Write((byte)1); + _if_expr_new.condition.visit(this); + } + if (_if_expr_new.if_true == null) + { + bw.Write((byte)0); + } + else + { + bw.Write((byte)1); + _if_expr_new.if_true.visit(this); + } + if (_if_expr_new.if_false == null) + { + bw.Write((byte)0); + } + else + { + bw.Write((byte)1); + _if_expr_new.if_false.visit(this); + } + } + } diff --git a/SyntaxTree/tree/Tree.cs b/SyntaxTree/tree/Tree.cs index 638482942..b840e45b0 100644 --- a/SyntaxTree/tree/Tree.cs +++ b/SyntaxTree/tree/Tree.cs @@ -53458,6 +53458,229 @@ namespace PascalABCCompiler.SyntaxTree } + /// + ///Новое условное выражение в стиле Паскаля. Доступно только при форматировании + /// + [Serializable] + public partial class if_expr_new : expression + { + + /// + ///Конструктор без параметров. + /// + public if_expr_new() + { + + } + + /// + ///Конструктор с параметрами. + /// + public if_expr_new(expression _condition,expression _if_true,expression _if_false) + { + this._condition=_condition; + this._if_true=_if_true; + this._if_false=_if_false; + FillParentsInDirectChilds(); + } + + /// + ///Конструктор с параметрами. + /// + public if_expr_new(expression _condition,expression _if_true,expression _if_false,SourceContext sc) + { + this._condition=_condition; + this._if_true=_if_true; + this._if_false=_if_false; + source_context = sc; + FillParentsInDirectChilds(); + } + protected expression _condition; + protected expression _if_true; + protected expression _if_false; + + /// + /// + /// + public expression condition + { + get + { + return _condition; + } + set + { + _condition=value; + if (_condition != null) + _condition.Parent = this; + } + } + + /// + /// + /// + public expression if_true + { + get + { + return _if_true; + } + set + { + _if_true=value; + if (_if_true != null) + _if_true.Parent = this; + } + } + + /// + /// + /// + public expression if_false + { + get + { + return _if_false; + } + set + { + _if_false=value; + if (_if_false != null) + _if_false.Parent = this; + } + } + + + /// Создает копию узла + public override syntax_tree_node Clone() + { + if_expr_new copy = new if_expr_new(); + copy.Parent = this.Parent; + if (source_context != null) + copy.source_context = new SourceContext(source_context); + if (attributes != null) + { + copy.attributes = (attribute_list)attributes.Clone(); + copy.attributes.Parent = copy; + } + if (condition != null) + { + copy.condition = (expression)condition.Clone(); + copy.condition.Parent = copy; + } + if (if_true != null) + { + copy.if_true = (expression)if_true.Clone(); + copy.if_true.Parent = copy; + } + if (if_false != null) + { + copy.if_false = (expression)if_false.Clone(); + copy.if_false.Parent = copy; + } + return copy; + } + + /// Получает копию данного узла корректного типа + public new if_expr_new TypedClone() + { + return Clone() as if_expr_new; + } + + /// Заполняет поля Parent в непосредственных дочерних узлах + public override void FillParentsInDirectChilds() + { + if (attributes != null) + attributes.Parent = this; + if (condition != null) + condition.Parent = this; + if (if_true != null) + if_true.Parent = this; + if (if_false != null) + if_false.Parent = this; + } + + /// Заполняет поля Parent во всем поддереве + public override void FillParentsInAllChilds() + { + FillParentsInDirectChilds(); + attributes?.FillParentsInAllChilds(); + condition?.FillParentsInAllChilds(); + if_true?.FillParentsInAllChilds(); + if_false?.FillParentsInAllChilds(); + } + + /// + ///Свойство для получения количества всех подузлов без элементов поля типа List + /// + public override Int32 subnodes_without_list_elements_count + { + get + { + return 3; + } + } + /// + ///Свойство для получения количества всех подузлов. Подузлом также считается каждый элемент поля типа List + /// + public override Int32 subnodes_count + { + get + { + return 3; + } + } + /// + ///Индексатор для получения всех подузлов + /// + public override syntax_tree_node this[Int32 ind] + { + get + { + if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) + throw new IndexOutOfRangeException(); + switch(ind) + { + case 0: + return condition; + case 1: + return if_true; + case 2: + return if_false; + } + return null; + } + set + { + if(subnodes_count == 0 || ind < 0 || ind > subnodes_count-1) + throw new IndexOutOfRangeException(); + switch(ind) + { + case 0: + condition = (expression)value; + break; + case 1: + if_true = (expression)value; + break; + case 2: + if_false = (expression)value; + break; + } + } + } + /// + ///Метод для обхода дерева посетителем + /// + ///Объект-посетитель. + ///Return value is void + public override void visit(IVisitor visitor) + { + visitor.visit(this); + } + + } + + } diff --git a/SyntaxTree/tree/Visitor.cs b/SyntaxTree/tree/Visitor.cs index f90e5c151..0cf174ffb 100644 --- a/SyntaxTree/tree/Visitor.cs +++ b/SyntaxTree/tree/Visitor.cs @@ -1504,6 +1504,12 @@ namespace PascalABCCompiler.SyntaxTree ///Node to visit /// Return value is void void visit(diapason_expr_new _diapason_expr_new); + /// + ///Method to visit if_expr_new. + /// + ///Node to visit + /// Return value is void + void visit(if_expr_new _if_expr_new); } diff --git a/SyntaxTree/tree/tree.xml b/SyntaxTree/tree/tree.xml index 63341bac2..10c572fcf 100644 --- a/SyntaxTree/tree/tree.xml +++ b/SyntaxTree/tree/tree.xml @@ -3236,6 +3236,18 @@ + + + + + + + + + + + + Tree.cs @@ -3285,6 +3297,7 @@ + @@ -3299,6 +3312,8 @@ + + @@ -3856,6 +3871,10 @@ + + + +