protected void createLabel(CElement parent, IToken token) throws CModelException { String labelName = token.getImage(); int index = getGlobalLabelIndex(labelName); boolean global = index > 0; if (!global) { index = registerLabel(labelName); } AsmLabel label = new AsmLabel(parent, labelName, global, index); SourceManipulationInfo labelInfo = label.getSourceManipulationInfo(); labelInfo.setIdPos(token.getOffset(), token.getLength()); labelInfo.setPos(token.getOffset(), token.getLength()); if (fLastLabel != null) { fixupLastLabel(); } if (global) { // new global label if (fLastGlobalLabel != null) { fixupLastGlobalLabel(); } fLastGlobalLabel = label; } else { // add under global label if available if (fLastGlobalLabel != null) { parent = fLastGlobalLabel; } } fLastLabel = label; parent.addChild(label); }
private void parsePPInclude(CElement parent) throws CModelException, OffsetLimitReachedException { int startOffset = fLexer.currentToken().getOffset(); int nameStart = 0; int nameEnd = 0; String name = null; boolean isStandard = false; IToken t = nextToken(); switch (t.getType()) { case IToken.tLT: nameStart = fLexer.currentToken().getOffset(); do { t = nextToken(); } while (t.getType() != IToken.tGT); nameEnd = fLexer.currentToken().getEndOffset(); name = new String(fLexer.getInputChars(nameStart + 1, nameEnd - 1)); isStandard = true; break; case IToken.tSTRING: nameStart = fLexer.currentToken().getOffset(); nameEnd = fLexer.currentToken().getEndOffset(); name = t.getImage().substring(1, t.getLength() - 1); break; case IToken.tIDENTIFIER: nameStart = fLexer.currentToken().getOffset(); nameEnd = fLexer.currentToken().getEndOffset(); name = t.getImage(); break; default: } if (name == null) { return; } int endOffset = skipToNewLine(); Include include = new Include(parent, name, isStandard); SourceManipulationInfo includeInfo = include.getSourceManipulationInfo(); includeInfo.setIdPos(nameStart, nameEnd - nameStart); includeInfo.setPos(startOffset, endOffset - startOffset); parent.addChild(include); }
private void parsePPDefine(CElement parent) throws CModelException, OffsetLimitReachedException { int startOffset = fLexer.currentToken().getOffset(); int nameStart = 0; int nameEnd = 0; String name = null; IToken t = nextToken(); if (t.getType() == IToken.tIDENTIFIER) { nameStart = fLexer.currentToken().getOffset(); nameEnd = fLexer.currentToken().getEndOffset(); name = t.getImage(); } if (name == null) { return; } int endOffset = skipToNewLine(); Macro macro = new Macro(parent, name); SourceManipulationInfo macroInfo = macro.getSourceManipulationInfo(); macroInfo.setIdPos(nameStart, nameEnd - nameStart); macroInfo.setPos(startOffset, endOffset - startOffset); parent.addChild(macro); }
private void parsePPDirective(CElement parent) throws CModelException { IToken token = nextToken(); if (token != null && token.getType() == IToken.tIDENTIFIER) { final String image = token.getImage(); if (image.equals("define")) { // $NON-NLS-1$ try { parsePPDefine(parent); } catch (OffsetLimitReachedException exc) { } return; } else if (image.equals("include")) { // $NON-NLS-1$ try { parsePPInclude(parent); } catch (OffsetLimitReachedException exc) { } return; } } try { skipToNewLine(); } catch (OffsetLimitReachedException exc) { } }
private boolean parseGlobalDirective() { boolean eol = false; do { IToken t = nextToken(); if (t == null) { break; } switch (t.getType()) { case IToken.tIDENTIFIER: registerGlobalLabel(t.getImage()); break; case Lexer.tNEWLINE: eol = true; break; default: if (fLineSeparatorChar != 0) { if (t.getLength() == 1 && t.getCharImage()[0] == fLineSeparatorChar) { eol = true; } } } } while (!eol); return eol; }
/** * Build the model. * * @param source * @throws CModelException */ private void buildModel(final char[] source) throws CModelException { fGlobals = new HashMap<String, Counter>(); fLabels = new HashMap<String, Counter>(); fLastLabel = null; fLastGlobalLabel = null; fLastLabelEndOffset = 0; final LexerOptions lexerOptions = new LexerOptions(); fLexer = new Lexer(source, lexerOptions, new LexerLog(), null); // if true the next token is the first on a (logical) line boolean firstTokenOnLine = true; // next token can be an instruction or a label boolean expectInstruction = true; // inside instruction boolean inInstruction = false; IToken token = nextToken(); while (token != null) { switch (token.getType()) { case IToken.tPOUND: if (fLexer.currentTokenIsFirstOnLine()) { parsePPDirective(fTranslationUnit); } break; case IToken.tDOT: // assembly directive? firstTokenOnLine = false; if (expectInstruction) { expectInstruction = false; token = nextToken(); if (token != null && token.getType() == IToken.tIDENTIFIER) { String text = token.getImage(); if (isGlobalDirective(text)) { firstTokenOnLine = parseGlobalDirective(); } else if (isDataDirective(text)) { inInstruction = true; } } } break; case IToken.tIDENTIFIER: // identifier may be a label or part of an instruction if (firstTokenOnLine) { // peek next char char nextChar = source[token.getEndOffset()]; if (nextChar == ':') { createLabel(fTranslationUnit, token); expectInstruction = true; } else { expectInstruction = false; inInstruction = true; } firstTokenOnLine = false; } else if (expectInstruction) { expectInstruction = false; inInstruction = true; } break; case Lexer.tNEWLINE: if (!firstTokenOnLine) { firstTokenOnLine = true; if (inInstruction) { fLastLabelEndOffset = fLexer.currentToken().getEndOffset(); } } break; default: expectInstruction = false; firstTokenOnLine = false; if (fLineSeparatorChar != 0) { if (token.getLength() == 1 && token.getCharImage()[0] == fLineSeparatorChar) { firstTokenOnLine = true; } } } if (firstTokenOnLine) { expectInstruction = true; inInstruction = false; } token = nextToken(); } if (!firstTokenOnLine && inInstruction) { fLastLabelEndOffset = fLexer.currentToken().getEndOffset(); } if (fLastLabel != null) { fixupLastLabel(); } if (fLastGlobalLabel != null) { fixupLastGlobalLabel(); } }