Java Code Examples for com.intellij.lang.impl.PsiBuilderImpl#ProductionMarker

The following examples show how to use com.intellij.lang.impl.PsiBuilderImpl#ProductionMarker . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: GeneratedParserUtilBase.java    From intellij-latte with MIT License 5 votes vote down vote up
private static boolean reportError(PsiBuilder builder,
                                   ErrorState state,
                                   Frame frame,
                                   IElementType elementType,
                                   boolean force,
                                   boolean advance) {
	String expectedText = state.getExpectedText(builder);
	boolean notEmpty = StringUtil.isNotEmpty(expectedText);
	if (!(force || notEmpty || advance)) return false;

	String gotText = builder.eof() ? "unexpected end of file" :
		notEmpty? "got '" + builder.getTokenText() +"'" :
			"'" + builder.getTokenText() +"' unexpected";
	String message = expectedText + gotText;
	if (advance) {
		PsiBuilder.Marker mark = builder.mark();
		builder.advanceLexer();
		mark.error(message);
	}
	else if (!force) {
		PsiBuilder.Marker extensionMarker = null;
		IElementType extensionTokenType = null;
		PsiBuilderImpl.ProductionMarker latestDoneMarker = elementType == null ? null : (PsiBuilderImpl.ProductionMarker)builder.getLatestDoneMarker();
		if (latestDoneMarker != null &&
			frame.position >= latestDoneMarker.getStartIndex() &&
			frame.position <= latestDoneMarker.getEndIndex()) {
			extensionMarker = ((PsiBuilder.Marker)latestDoneMarker).precede();
			extensionTokenType = latestDoneMarker.getTokenType();
			((PsiBuilder.Marker)latestDoneMarker).drop();
		}
		builder.error(message);
		if (extensionMarker != null) extensionMarker.done(extensionTokenType);
	}
	else {
		builder.error(message);
	}
	builder.eof(); // skip whitespaces
	frame.errorReportedAt = builder.rawTokenIndex();
	return true;
}
 
Example 2
Source File: GeneratedParserUtilBase.java    From intellij-xquery with Apache License 2.0 5 votes vote down vote up
private static boolean reportError(PsiBuilder builder,
                                   ErrorState state,
                                   Frame frame,
                                   IElementType elementType,
                                   boolean force,
                                   boolean advance) {
    String expectedText = state.getExpectedText(builder);
    boolean notEmpty = isNotEmpty(expectedText);
    if (!(force || notEmpty || advance)) return false;

    String actual = "'" + first(notNullize(builder.getTokenText(), "null"), MAX_ERROR_TOKEN_TEXT, true) + "'";
    String message = expectedText + (builder.eof() ? "unexpected end of file" : notEmpty ? "got " + actual : actual + " unexpected");
    if (advance) {
        PsiBuilder.Marker mark = builder.mark();
        builder.advanceLexer();
        mark.error(message);
    }
    else if (!force) {
        PsiBuilder.Marker extensionMarker = null;
        IElementType extensionTokenType = null;
        PsiBuilderImpl.ProductionMarker latestDoneMarker = elementType == null ? null : (PsiBuilderImpl.ProductionMarker)builder.getLatestDoneMarker();
        if (latestDoneMarker != null &&
                frame.position >= latestDoneMarker.getStartIndex() &&
                frame.position <= latestDoneMarker.getEndIndex()) {
            extensionMarker = ((PsiBuilder.Marker)latestDoneMarker).precede();
            extensionTokenType = latestDoneMarker.getTokenType();
            ((PsiBuilder.Marker)latestDoneMarker).drop();
        }
        builder.error(message);
        if (extensionMarker != null) extensionMarker.done(extensionTokenType);
    }
    else {
        builder.error(message);
    }
    builder.eof(); // skip whitespaces
    frame.errorReportedAt = builder.rawTokenIndex();
    return true;
}
 
Example 3
Source File: GeneratedParserUtilBase.java    From consulo with Apache License 2.0 5 votes vote down vote up
@Override
public PsiBuilder.Marker run(PsiBuilder builder, PsiBuilder.Marker marker, String param) {
  PsiBuilderImpl.ProductionMarker m = (PsiBuilderImpl.ProductionMarker)marker;
  int start = m == null ? builder.getCurrentOffset() : m.getStartOffset();
  int end = m == null ? start : m.getEndOffset();
  String prefix = "[" + start + ", " + end + "]" + (m == null ? "" : " " + m.getTokenType());
  builder.mark().error(prefix + ": " + param);
  return marker;
}
 
Example 4
Source File: GeneratedParserUtilBase.java    From consulo with Apache License 2.0 5 votes vote down vote up
private static boolean reportError(PsiBuilder builder,
                                   ErrorState state,
                                   Frame frame,
                                   IElementType elementType,
                                   boolean force,
                                   boolean advance) {
  String expectedText = state.getExpectedText(builder);
  boolean notEmpty = isNotEmpty(expectedText);
  if (!(force || notEmpty || advance)) return false;

  String actual = "'" + first(notNullize(builder.getTokenText(), "null"), MAX_ERROR_TOKEN_TEXT, true) + "'";
  String message = expectedText + (builder.eof() ? "unexpected end of file" : notEmpty ? "got " + actual : actual + " unexpected");
  if (advance) {
    PsiBuilder.Marker mark = builder.mark();
    builder.advanceLexer();
    mark.error(message);
  }
  else if (!force) {
    PsiBuilder.Marker extensionMarker = null;
    IElementType extensionTokenType = null;
    PsiBuilderImpl.ProductionMarker latestDoneMarker = elementType == null ? null : (PsiBuilderImpl.ProductionMarker)builder.getLatestDoneMarker();
    if (latestDoneMarker != null &&
        frame.position >= latestDoneMarker.getStartIndex() &&
        frame.position <= latestDoneMarker.getEndIndex()) {
      extensionMarker = ((PsiBuilder.Marker)latestDoneMarker).precede();
      extensionTokenType = latestDoneMarker.getTokenType();
      ((PsiBuilder.Marker)latestDoneMarker).drop();
    }
    builder.error(message);
    if (extensionMarker != null) extensionMarker.done(extensionTokenType);
  }
  else {
    builder.error(message);
  }
  builder.eof(); // skip whitespaces
  frame.errorReportedAt = builder.rawTokenIndex();
  return true;
}
 
Example 5
Source File: GeneratedParserUtilBase.java    From intellij-latte with MIT License 4 votes vote down vote up
private static void exit_section_impl_(ErrorState state,
                                       Frame frame,
                                       PsiBuilder builder,
                                       @Nullable IElementType elementType,
                                       boolean result,
                                       boolean pinned,
                                       @Nullable Parser eatMore) {
	int initialPos = builder.rawTokenIndex();
	boolean willFail = !result && !pinned;
	if (willFail && initialPos == frame.position && state.lastExpectedVariantPos == frame.position &&
		frame.name != null && state.variants.size() - frame.variantCount > 1) {
		state.clearVariants(true, frame.variantCount);
		addVariantInner(state, initialPos, frame.name);
	}
	int lastErrorPos = getLastVariantPos(state, initialPos);
	if (!state.suppressErrors && eatMore != null) {
		state.suppressErrors = true;
		final boolean eatMoreFlagOnce = !builder.eof() && eatMore.parse(builder, frame.level + 1);
		boolean eatMoreFlag = eatMoreFlagOnce || !result && frame.position == initialPos && lastErrorPos > frame.position;

		PsiBuilderImpl.ProductionMarker latestDoneMarker =
			(pinned || result) && (state.altMode || elementType != null) &&
				eatMoreFlagOnce ? (PsiBuilderImpl.ProductionMarker)builder.getLatestDoneMarker() : null;
		PsiBuilder.Marker extensionMarker = null;
		IElementType extensionTokenType = null;
		// whitespace prefix makes the very first frame offset bigger than marker start offset which is always 0
		if (latestDoneMarker != null &&
			frame.position >= latestDoneMarker.getStartIndex() &&
			frame.position <= latestDoneMarker.getEndIndex()) {
			extensionMarker = ((PsiBuilder.Marker)latestDoneMarker).precede();
			extensionTokenType = latestDoneMarker.getTokenType();
			((PsiBuilder.Marker)latestDoneMarker).drop();
		}
		// advance to the last error pos
		// skip tokens until lastErrorPos. parseAsTree might look better here...
		int parenCount = 0;
		while ((eatMoreFlag || parenCount > 0) && builder.rawTokenIndex() < lastErrorPos) {
			IElementType tokenType = builder.getTokenType();
			if (state.braces != null) {
				if (tokenType == state.braces[0].getLeftBraceType()) parenCount ++;
				else if (tokenType == state.braces[0].getRightBraceType()) parenCount --;
			}
			if (!(builder.rawTokenIndex() < lastErrorPos)) break;
			builder.advanceLexer();
			eatMoreFlag = eatMore.parse(builder, frame.level + 1);
		}
		boolean errorReported = frame.errorReportedAt == initialPos || !result && frame.errorReportedAt >= frame.position;
		if (errorReported) {
			if (eatMoreFlag) {
				builder.advanceLexer();
				parseAsTree(state, builder, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
			}
		}
		else if (eatMoreFlag) {
			errorReported = reportError(builder, state, frame, null, true, true);
			parseAsTree(state, builder, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
		}
		else if (eatMoreFlagOnce || (!result && frame.position != builder.rawTokenIndex()) || frame.errorReportedAt > initialPos) {
			errorReported = reportError(builder, state, frame, null, true, false);
		}
		else if (!result && pinned && frame.errorReportedAt < 0) {
			errorReported = reportError(builder, state, frame, elementType, false, false);
		}
		if (extensionMarker != null) {
			extensionMarker.done(extensionTokenType);
		}
		state.suppressErrors = false;
		if (errorReported || result) {
			state.clearVariants(true, 0);
			state.clearVariants(false, 0);
			state.lastExpectedVariantPos = -1;
		}
	}
	else if (!result && pinned && frame.errorReportedAt < 0) {
		// do not report if there are errors beyond current position
		if (lastErrorPos == initialPos) {
			// do not force, inner recoverRoot might have skipped some tokens
			reportError(builder, state, frame, elementType, false, false);
		}
		else if (lastErrorPos > initialPos) {
			// set error pos here as if it is reported for future reference
			frame.errorReportedAt = lastErrorPos;
		}
	}
	// propagate errorReportedAt up the stack to avoid duplicate reporting
	Frame prevFrame = willFail && eatMore == null ? null : state.currentFrame;
	if (prevFrame != null && prevFrame.errorReportedAt < frame.errorReportedAt) {
		prevFrame.errorReportedAt = frame.errorReportedAt;
	}
}
 
Example 6
Source File: GeneratedParserUtilBase.java    From intellij-latte with MIT License 4 votes vote down vote up
private static void close_frame_impl_(ErrorState state,
                                      Frame frame,
                                      PsiBuilder builder,
                                      PsiBuilder.Marker marker,
                                      IElementType elementType,
                                      boolean result,
                                      boolean pinned) {
	if (elementType != null && marker != null) {
		if ((frame.modifiers & _COLLAPSE_) != 0) {
			PsiBuilderImpl.ProductionMarker last = result || pinned? (PsiBuilderImpl.ProductionMarker)builder.getLatestDoneMarker() : null;
			if (last != null && last.getStartIndex() == frame.position &&
				state.typeExtends(last.getTokenType(), elementType)) {
				IElementType resultType = last.getTokenType();
				((PsiBuilder.Marker)last).drop();
				marker.done(resultType);
				return;
			}
		}
		if (result || pinned) {
			if ((frame.modifiers & _UPPER_) != 0) {
				marker.drop();
				for (Frame f = frame.parentFrame; f != null; f = f.parentFrame) {
					if (f.elementType == null) continue;
					f.elementType = elementType;
					break;
				}
			}
			else if ((frame.modifiers & _LEFT_INNER_) != 0 && frame.leftMarker != null) {
				marker.done(elementType);
				frame.leftMarker.precede().done(((LighterASTNode)frame.leftMarker).getTokenType());
				frame.leftMarker.drop();
			}
			else if ((frame.modifiers & _LEFT_) != 0 && frame.leftMarker != null) {
				marker.drop();
				frame.leftMarker.precede().done(elementType);
			}
			else {
				if (frame.level == 0) builder.eof(); // skip whitespaces
				marker.done(elementType);
			}
		}
		else {
			close_marker_impl_(frame, marker, null, false);
		}
	}
	else if (result || pinned) {
		if (marker != null) marker.drop();
		if ((frame.modifiers & _LEFT_INNER_) != 0 && frame.leftMarker != null) {
			frame.leftMarker.precede().done(((LighterASTNode)frame.leftMarker).getTokenType());
			frame.leftMarker.drop();
		}
	}
	else {
		close_marker_impl_(frame, marker, null, false);
	}
}
 
Example 7
Source File: GeneratedParserUtilBase.java    From intellij-xquery with Apache License 2.0 4 votes vote down vote up
private static void exit_section_impl_(ErrorState state,
                                       Frame frame,
                                       PsiBuilder builder,
                                       @Nullable IElementType elementType,
                                       boolean result,
                                       boolean pinned,
                                       @Nullable Parser eatMore) {
    int initialPos = builder.rawTokenIndex();
    boolean willFail = !result && !pinned;
    replace_variants_with_name_(state, frame, builder, result, pinned);
    int lastErrorPos = getLastVariantPos(state, initialPos);
    if (!state.suppressErrors && eatMore != null) {
        state.suppressErrors = true;
        final boolean eatMoreFlagOnce = !builder.eof() && eatMore.parse(builder, frame.level + 1);
        boolean eatMoreFlag = eatMoreFlagOnce || !result && frame.position == initialPos && lastErrorPos > frame.position;

        PsiBuilderImpl.ProductionMarker latestDoneMarker =
                (pinned || result) && (state.altMode || elementType != null) &&
                        eatMoreFlagOnce ? (PsiBuilderImpl.ProductionMarker)builder.getLatestDoneMarker() : null;
        PsiBuilder.Marker extensionMarker = null;
        IElementType extensionTokenType = null;
        // whitespace prefix makes the very first frame offset bigger than marker start offset which is always 0
        if (latestDoneMarker != null &&
                frame.position >= latestDoneMarker.getStartIndex() &&
                frame.position <= latestDoneMarker.getEndIndex()) {
            extensionMarker = ((PsiBuilder.Marker)latestDoneMarker).precede();
            extensionTokenType = latestDoneMarker.getTokenType();
            ((PsiBuilder.Marker)latestDoneMarker).drop();
        }
        // advance to the last error pos
        // skip tokens until lastErrorPos. parseAsTree might look better here...
        int parenCount = 0;
        while ((eatMoreFlag || parenCount > 0) && builder.rawTokenIndex() < lastErrorPos) {
            IElementType tokenType = builder.getTokenType();
            if (state.braces != null) {
                if (tokenType == state.braces[0].getLeftBraceType()) parenCount ++;
                else if (tokenType == state.braces[0].getRightBraceType()) parenCount --;
            }
            if (!(builder.rawTokenIndex() < lastErrorPos)) break;
            builder.advanceLexer();
            eatMoreFlag = eatMore.parse(builder, frame.level + 1);
        }
        boolean errorReported = frame.errorReportedAt == initialPos || !result && frame.errorReportedAt >= frame.position;
        if (errorReported) {
            if (eatMoreFlag) {
                builder.advanceLexer();
                parseAsTree(state, builder, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
            }
        }
        else if (eatMoreFlag) {
            errorReported = reportError(builder, state, frame, null, true, true);
            parseAsTree(state, builder, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
        }
        else if (eatMoreFlagOnce || (!result && frame.position != builder.rawTokenIndex()) || frame.errorReportedAt > initialPos) {
            errorReported = reportError(builder, state, frame, null, true, false);
        }
        else if (!result && pinned && frame.errorReportedAt < 0) {
            errorReported = reportError(builder, state, frame, elementType, false, false);
        }
        if (extensionMarker != null) {
            extensionMarker.done(extensionTokenType);
        }
        state.suppressErrors = false;
        if (errorReported || result) {
            state.clearVariants(true, 0);
            state.clearVariants(false, 0);
            state.lastExpectedVariantPos = -1;
        }
    }
    else if (!result && pinned) {
        // do not report if there are errors beyond current position
        if (lastErrorPos == initialPos) {
            // do not force, inner recoverRoot might have skipped some tokens
            reportError(builder, state, frame, elementType, false, false);
        }
        else if (lastErrorPos > initialPos) {
            // set error pos here as if it is reported for future reference
            frame.errorReportedAt = lastErrorPos;
        }
    }
    // propagate errorReportedAt up the stack to avoid duplicate reporting
    Frame prevFrame = willFail && eatMore == null ? null : state.currentFrame;
    if (prevFrame != null && prevFrame.errorReportedAt < frame.errorReportedAt) {
        prevFrame.errorReportedAt = frame.errorReportedAt;
    }
}
 
Example 8
Source File: GeneratedParserUtilBase.java    From intellij-xquery with Apache License 2.0 4 votes vote down vote up
private static void close_frame_impl_(ErrorState state,
                                      Frame frame,
                                      PsiBuilder builder,
                                      PsiBuilder.Marker marker,
                                      IElementType elementType,
                                      boolean result,
                                      boolean pinned) {
    if (elementType != null && marker != null) {
        if (result || pinned) {
            if ((frame.modifiers & _COLLAPSE_) != 0) {
                PsiBuilderImpl.ProductionMarker last = (PsiBuilderImpl.ProductionMarker)builder.getLatestDoneMarker();
                if (last != null &&
                        last.getStartIndex() == frame.position &&
                        state.typeExtends(last.getTokenType(), elementType) &&
                        wasAutoSkipped(builder, builder.rawTokenIndex() - last.getEndIndex())) {
                    elementType = last.getTokenType();
                    ((PsiBuilder.Marker)last).drop();
                }
            }
            if ((frame.modifiers & _UPPER_) != 0) {
                marker.drop();
                for (Frame f = frame.parentFrame; f != null; f = f.parentFrame) {
                    if (f.elementType == null) continue;
                    f.elementType = elementType;
                    break;
                }
            }
            else if ((frame.modifiers & _LEFT_INNER_) != 0 && frame.leftMarker != null) {
                marker.done(elementType);
                frame.leftMarker.precede().done(((LighterASTNode)frame.leftMarker).getTokenType());
                frame.leftMarker.drop();
            }
            else if ((frame.modifiers & _LEFT_) != 0 && frame.leftMarker != null) {
                marker.drop();
                frame.leftMarker.precede().done(elementType);
            }
            else {
                if (frame.level == 0) builder.eof(); // skip whitespaces
                marker.done(elementType);
            }
        }
        else {
            close_marker_impl_(frame, marker, null, false);
        }
    }
    else if (result || pinned) {
        if (marker != null) marker.drop();
        if ((frame.modifiers & _LEFT_INNER_) != 0 && frame.leftMarker != null) {
            frame.leftMarker.precede().done(((LighterASTNode)frame.leftMarker).getTokenType());
            frame.leftMarker.drop();
        }
    }
    else {
        close_marker_impl_(frame, marker, null, false);
    }
}
 
Example 9
Source File: GeneratedParserUtilBase.java    From consulo with Apache License 2.0 4 votes vote down vote up
private static void exit_section_impl_(ErrorState state,
                                       Frame frame,
                                       PsiBuilder builder,
                                       @Nullable IElementType elementType,
                                       boolean result,
                                       boolean pinned,
                                       @Nullable Parser eatMore) {
  int initialPos = builder.rawTokenIndex();
  boolean willFail = !result && !pinned;
  replace_variants_with_name_(state, frame, builder, result, pinned);
  int lastErrorPos = getLastVariantPos(state, initialPos);
  if (!state.suppressErrors && eatMore != null) {
    state.suppressErrors = true;
    final boolean eatMoreFlagOnce = !builder.eof() && eatMore.parse(builder, frame.level + 1);
    boolean eatMoreFlag = eatMoreFlagOnce || !result && frame.position == initialPos && lastErrorPos > frame.position;

    PsiBuilderImpl.ProductionMarker latestDoneMarker =
            (pinned || result) && (state.altMode || elementType != null) &&
            eatMoreFlagOnce ? (PsiBuilderImpl.ProductionMarker)builder.getLatestDoneMarker() : null;
    PsiBuilder.Marker extensionMarker = null;
    IElementType extensionTokenType = null;
    // whitespace prefix makes the very first frame offset bigger than marker start offset which is always 0
    if (latestDoneMarker != null &&
        frame.position >= latestDoneMarker.getStartIndex() &&
        frame.position <= latestDoneMarker.getEndIndex()) {
      extensionMarker = ((PsiBuilder.Marker)latestDoneMarker).precede();
      extensionTokenType = latestDoneMarker.getTokenType();
      ((PsiBuilder.Marker)latestDoneMarker).drop();
    }
    // advance to the last error pos
    // skip tokens until lastErrorPos. parseAsTree might look better here...
    int parenCount = 0;
    while ((eatMoreFlag || parenCount > 0) && builder.rawTokenIndex() < lastErrorPos) {
      IElementType tokenType = builder.getTokenType();
      if (state.braces != null) {
        if (tokenType == state.braces[0].getLeftBraceType()) parenCount ++;
        else if (tokenType == state.braces[0].getRightBraceType()) parenCount --;
      }
      if (!(builder.rawTokenIndex() < lastErrorPos)) break;
      builder.advanceLexer();
      eatMoreFlag = eatMore.parse(builder, frame.level + 1);
    }
    boolean errorReported = frame.errorReportedAt == initialPos || !result && frame.errorReportedAt >= frame.position;
    if (errorReported) {
      if (eatMoreFlag) {
        builder.advanceLexer();
        parseAsTree(state, builder, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
      }
    }
    else if (eatMoreFlag) {
      errorReported = reportError(builder, state, frame, null, true, true);
      parseAsTree(state, builder, frame.level + 1, DUMMY_BLOCK, true, TOKEN_ADVANCER, eatMore);
    }
    else if (eatMoreFlagOnce || (!result && frame.position != builder.rawTokenIndex()) || frame.errorReportedAt > initialPos) {
      errorReported = reportError(builder, state, frame, null, true, false);
    }
    else if (!result && pinned && frame.errorReportedAt < 0) {
      errorReported = reportError(builder, state, frame, elementType, false, false);
    }
    if (extensionMarker != null) {
      extensionMarker.done(extensionTokenType);
    }
    state.suppressErrors = false;
    if (errorReported || result) {
      state.clearVariants(true, 0);
      state.clearVariants(false, 0);
      state.lastExpectedVariantPos = -1;
    }
  }
  else if (!result && pinned && frame.errorReportedAt < 0) {
    // do not report if there are errors beyond current position
    if (lastErrorPos == initialPos) {
      // do not force, inner recoverRoot might have skipped some tokens
      reportError(builder, state, frame, elementType, false, false);
    }
    else if (lastErrorPos > initialPos) {
      // set error pos here as if it is reported for future reference
      frame.errorReportedAt = lastErrorPos;
    }
  }
  // propagate errorReportedAt up the stack to avoid duplicate reporting
  Frame prevFrame = willFail && eatMore == null ? null : state.currentFrame;
  if (prevFrame != null && prevFrame.errorReportedAt < frame.errorReportedAt) {
    prevFrame.errorReportedAt = frame.errorReportedAt;
  }
}
 
Example 10
Source File: GeneratedParserUtilBase.java    From consulo with Apache License 2.0 4 votes vote down vote up
private static void close_frame_impl_(ErrorState state,
                                      Frame frame,
                                      PsiBuilder builder,
                                      PsiBuilder.Marker marker,
                                      IElementType elementType,
                                      boolean result,
                                      boolean pinned) {
  if (elementType != null && marker != null) {
    if (result || pinned) {
      if ((frame.modifiers & _COLLAPSE_) != 0) {
        PsiBuilderImpl.ProductionMarker last = (PsiBuilderImpl.ProductionMarker)builder.getLatestDoneMarker();
        if (last != null &&
            last.getStartIndex() == frame.position &&
            state.typeExtends(last.getTokenType(), elementType) &&
            wasAutoSkipped(builder, builder.rawTokenIndex() - last.getEndIndex())) {
          elementType = last.getTokenType();
          ((PsiBuilder.Marker)last).drop();
        }
      }
      if ((frame.modifiers & _UPPER_) != 0) {
        marker.drop();
        for (Frame f = frame.parentFrame; f != null; f = f.parentFrame) {
          if (f.elementType == null) continue;
          f.elementType = elementType;
          break;
        }
      }
      else if ((frame.modifiers & _LEFT_INNER_) != 0 && frame.leftMarker != null) {
        marker.done(elementType);
        frame.leftMarker.precede().done(((LighterASTNode)frame.leftMarker).getTokenType());
        frame.leftMarker.drop();
      }
      else if ((frame.modifiers & _LEFT_) != 0 && frame.leftMarker != null) {
        marker.drop();
        frame.leftMarker.precede().done(elementType);
      }
      else {
        if (frame.level == 0) builder.eof(); // skip whitespaces
        marker.done(elementType);
      }
    }
    else {
      close_marker_impl_(frame, marker, null, false);
    }
  }
  else if (result || pinned) {
    if (marker != null) marker.drop();
    if ((frame.modifiers & _LEFT_INNER_) != 0 && frame.leftMarker != null) {
      frame.leftMarker.precede().done(((LighterASTNode)frame.leftMarker).getTokenType());
      frame.leftMarker.drop();
    }
  }
  else {
    close_marker_impl_(frame, marker, null, false);
  }
}