public override CompilerParser VisitAssignment([NotNull] CompilerParser.AssignmentContext context) { // Получаем доступ к родительскому контексту (всегда будет Statement, поэтому на null можно не проверять) var parentContext = context.Parent as CompilerParser.StatementContext; // Для разрешения неоднозначности между Expression и Condition (в обоих есть альтернатива ID) // То есть в выражении вида a = b переменная b может быть как логической и числовой, и при таком // выражении, исходя из грамматики, визитор всегда будет уходить в узел Condition. Поэтому берем // напрямую значение переменной b из памяти и копируем в переменную a. if (context.Start.Type == CompilerParser.ID && context.Start.StopIndex - context.Start.Text.Length + 1 == context.Stop.StartIndex) { AddToMemory(parentContext.Start.Text, CompilerParser.memory[context.Start.Text]); return(null); } // В зависимости от того, что представляет собой выражение, посещаем соответствующий узел // и записываем в память его значение if (context.exp != null) { Visit(context.exp); AddToMemory(parentContext.Start.Text, context.exp.val); } else { Visit(context.cond); AddToMemory(parentContext.Start.Text, context.cond.val); } return(null); }
/// <summary> /// Exit a parse tree produced by <see cref="CompilerParser.assignment"/>. /// <para>The default implementation does nothing.</para> /// </summary> /// <param name="context">The parse tree.</param> public virtual void ExitAssignment([NotNull] CompilerParser.AssignmentContext context) { }
/// <summary> /// Visit a parse tree produced by <see cref="CompilerParser.assignment"/>. /// <para> /// The default implementation returns the result of calling <see cref="AbstractParseTreeVisitor{Result}.VisitChildren(IRuleNode)"/> /// on <paramref name="context"/>. /// </para> /// </summary> /// <param name="context">The parse tree.</param> /// <return>The visitor result.</return> public virtual Result VisitAssignment([NotNull] CompilerParser.AssignmentContext context) { return(VisitChildren(context)); }