001/*-------------------------------------------------------------------------+ 002| | 003| Copyright (c) 2009-2017 CQSE GmbH | 004| | 005+-------------------------------------------------------------------------*/ 006package eu.cqse.check.framework.shallowparser.languages.cobol; 007 008import static eu.cqse.check.framework.scanner.ETokenType.DOLLAR_ELSE; 009import static eu.cqse.check.framework.scanner.ETokenType.DOLLAR_IF; 010import static eu.cqse.check.framework.scanner.ETokenType.DOT; 011import static eu.cqse.check.framework.scanner.ETokenType.ELSE; 012 013import java.util.List; 014 015import eu.cqse.check.framework.scanner.ETokenType; 016import eu.cqse.check.framework.scanner.IToken; 017import eu.cqse.check.framework.shallowparser.TokenStreamUtils; 018import eu.cqse.check.framework.shallowparser.framework.ParserState; 019import eu.cqse.check.framework.shallowparser.framework.RecognizerBase; 020 021/** 022 * Recognizes that there is not an else token after an if token has been 023 * encountered. It caters for the IF statement and $IF meta entities. 024 */ 025public class NoElseRecognizer extends RecognizerBase<ECobolParserState> { 026 027 /** 028 * The IF or $IF token types. 029 */ 030 private ETokenType ifType; 031 032 /** 033 * The END_IF or $END token types. 034 */ 035 private ETokenType endIfType; 036 037 /** Constructor. */ 038 public NoElseRecognizer(ETokenType ifType, ETokenType endIfType) { 039 this.ifType = ifType; 040 this.endIfType = endIfType; 041 } 042 043 /** {@inheritDoc} */ 044 @Override 045 protected int matchesLocally(ParserState<ECobolParserState> parserState, List<IToken> tokens, int startOffset) { 046 int endIfOrDotTokenIndex = TokenStreamUtils.firstTokenOfType(tokens, startOffset, endIfType, DOT); 047 if (endIfOrDotTokenIndex == NO_MATCH) { 048 // This is unusual but we need handle it 049 return NO_MATCH; 050 } 051 052 List<IToken> newTokens = tokens.subList(startOffset, endIfOrDotTokenIndex); 053 int countIfTokens = TokenStreamUtils.count(newTokens, ifType); 054 ETokenType elseType = ELSE; 055 if (ifType == DOLLAR_IF) { 056 elseType = DOLLAR_ELSE; 057 } 058 059 int countElseTokens = TokenStreamUtils.count(newTokens, elseType); 060 if (countIfTokens >= countElseTokens) { 061 // There could be matching If-else statements or just singleton if 062 // statements. 063 return super.matchesLocally(parserState, newTokens, startOffset); 064 } 065 066 return NO_MATCH; 067 } 068}