Пример #1
0
		/// <summary>
		/// Attempts to return a direct link to the specified parent.
		/// </summary>
		/// <param name="parent">The parent to look for.</param>
		/// <returns>The <see cref="Link"/> to the specified parent;
		/// or <see langword="null"/> when the specified frame is no parent
		/// of this frame.</returns>
		public Link TryGetParentLink(Frame parent)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(parent != null);
			#endregion
			return this.Links.FirstOrDefault(l => l.Parent == parent);
		}
Пример #2
0
		/// <summary>
		/// Initializes a new instance of the <see cref="ActionState"/> class.
		/// </summary>
		/// <param name="stack"></param>
		/// <param name="state"></param>
		/// <param name="currentToken"></param>
		public ActionState(Frame stack, StateRef state, CodePoint currentToken)
			: this()
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(stack != null);
			#endregion

			this.Stack = stack;
			this.NextState = state;
			this.CurrentToken = currentToken;
		}
Пример #3
0
		/// <summary>
		/// Initializes a new instance of the <see cref="Link"/> class.
		/// </summary>
		/// <param name="parent">The parent/destination frame.</param>
		/// <param name="label">The label of this link.</param>
		/// <param name="length"></param>
		public Link(Frame parent, IParseNode label, int length)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(parent != null);
			Contract.Requires<ArgumentNullException>(label != null);
			Contract.Requires<ArgumentOutOfRangeException>(length >= 0);
			#endregion
			this.Parent = parent;
			this.Label = label;
			this.IsRejected = false;
			this.Length = length;
		}
Пример #4
0
		/// <summary>
		/// Initializes a new instance of the <see cref="Path"/> class.
		/// </summary>
		/// <param name="next">The next node in the path; or <see langword="null"/>.</param>
		/// <param name="link">The associated link; or <see langword="null"/>.</param>
		/// <param name="frame">The associated stack frame.</param>
		/// <param name="length"></param>
		public Path(Path next, Link link, Frame frame, int length)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(frame != null);
			Contract.Requires<ArgumentOutOfRangeException>(length >= 0);
			#endregion
			this.Next = next;
			this.Link = link;
			this.Frame = frame;
			this.Length = length;
			this.AncestorCount = next != null ? next.AncestorCount + 1 : 0;
			this.label = this.Link?.Label;
		}
Пример #5
0
		/// <summary>
		/// Gets an active stack frame with the specified state,
		/// or creates and adds one if there is none.
		/// </summary>
		/// <param name="state">The state to look for.</param>
		/// <returns>A <see cref="Frame"/> with the specified state.</returns>
		private Frame GetOrCreateActiveFrame(StateRef state)
		{
			#region Contract
			Contract.Ensures(Contract.Result<Frame>() != null);
			Contract.Ensures(Contract.Result<Frame>().State == state);
			#endregion

			var frame = GetActiveFrame(state);
			if (frame == null)
			{
				frame = new Frame(state);
				this.activeStacks.PushFront(frame);
			}
			return frame;
		}
Пример #6
0
		/// <summary>
		/// Checks whether the production is a completion production, and if so, checks
		/// the boundaries for the completion region, the parser location and the cursor
		/// location, and whether the parser is in completion mode.
		/// Otherwise, when the production is not a completion production,
		/// checks whether it is a recover production, or the parser is in fine grained recovery mode.
		/// </summary>
		/// <param name="stack"></param>
		/// <param name="production"></param>
		/// <returns></returns>
		private bool RecoverModeOk(Frame stack, ProductionRule production)
		{
			if (!production.IsCompletion)
				return !production.IsRecover || isFineGrainedMode;  // TODO: isFineGrainedMode
			return InCompletionMode(production);
		}
Пример #7
0
		/// <param name="st0"></param>
		/// <param name="nextState"></param>
		/// <param name="label"></param>
		/// <param name="kids">A list of trees.</param>
		/// <param name="path"></param>
		private void Reducer(Frame st0, StateRef nextState, LabelRef label, IReadOnlyList<IParseNode> kids, Path path)
		{
			var production = this.parseTable.Labels[label.Index].Production;

			Contract.Assert(!production.IsRecover);

			// t := application of a -> A to kids
			IParseNode t = ApplyProduction(production, kids, /* TODO */ 0, /* TODO */ 0, /* TODO */ false, /* TODO */ false);

			Frame st1 = GetActiveFrame(nextState);

			if (st1 != null)
			{
				// A stack with state nextState exists. Check for ambiguities.
				Link nl = st1.TryGetParentLink(st0);
				if (nl != null)
				{
					// There exists a direct link from st1 to st0.
					// TODO: Add `t` to the possiblities of the ambiguity node at `tree(nl)`
					if (production.IsReject)
						nl.Reject();

					// TODO: Can't modify a link.
					//nl.Label = t;
				}
				else
				{
					// There is no direct link from st1 to st0.
					nl = new Link(st0, t, path.Length);
					st1.Links.Add(nl);

					if (production.IsReject)
						nl.Reject();

					ActorOnActiveStacksOverNewLink(nl);
				}
			}
			else
			{
				// Found no existing stack frame with state nextState.
				st1 = new Frame(nextState);
				this.activeStacks.PushFront(st1);
				this.forActorDelayed.PushFront(st1);

				var nl = new Link(st0, t, path.Length);
				st1.Links.Add(nl);

				if (production.IsReject)
					nl.Reject();
			}
		}
Пример #8
0
		// TODO: Rename to DoReductions?
		/// <summary>
		/// 
		/// </summary>
		/// <param name="stack"></param>
		/// <param name="label"></param>
		/// <param name="link">; or <see langword="null"/>.</param>
		public void DoLimitedReductions(Frame stack, LabelRef label, Link link)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(stack != null);
			Contract.Requires<ArgumentNullException>(label != null);
			#endregion

			var production = this.parseTable.Labels[label.Index].Production;

			if (!RecoverModeOk(stack, production))
				return;

			var paths = stack.FindPathsToRoot(production.Arity, link);
			ReduceAllPaths(label, paths);
		}
Пример #9
0
		/// <summary>
		/// Reduces the specified stack frame 
		/// </summary>
		/// <param name="stack"></param>
		/// <param name="label"></param>
		public void DoReductions(Frame stack, LabelRef label)
		{
			DoLimitedReductions(stack, label, null);
		}
Пример #10
0
		// TODO: Can currentToken be removed?
		/// <summary>
		/// Enqueues the specified stack frame and next state for the shifter.
		/// </summary>
		/// <param name="stack">The current stack frame.</param>
		/// <param name="nextState">The next state.</param>
		/// <param name="currentToken">The current token.</param>
		public void EnqueueForShifter(Frame stack, StateRef nextState, CodePoint currentToken)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(stack != null);
			Contract.Requires<ArgumentNullException>(nextState != null);
			#endregion
			this.forShifter.PushFront(new ActionState(stack, nextState, currentToken));
		}
Пример #11
0
		/// <summary>
		/// Attempts to accept the specified stack frame.
		/// </summary>
		/// <param name="stack">The stack frame to accept.</param>
		/// <returns><see langword="true"/> when the stack frame was accepted;
		/// otherwise, <see langword="false"/>.</returns>
		public bool TryAccept(Frame stack)
		{
			#region Contract
			Contract.Requires<ArgumentNullException>(stack != null);
			#endregion
			if (stack.IsRejected)
				return false;

			this.AcceptingStack = stack;

			SglrEngine.trace.TraceInformation($"Accepted stack {stack}.");

			return true;
		}
Пример #12
0
		/// <summary>
		/// Executes all actions associated with the current state of the stack frame,
		/// if the action accepts the current token.
		/// </summary>
		/// <param name="frame">The stack frame.</param>
		private void ExecuteActions(Frame frame)
		{
			SglrEngine.trace.TraceInformation("Executing actions for frame {0}.", frame);

			var state = GetState(frame.State);
			foreach (var action in state.Actions)
			{
				if (!action.Accepts(this.CurrentToken))
					continue;

				foreach (var actionItem in action.Items)
				{
					actionItem.Execute(this, frame);
				}
			}
		}