44import org .antlr .v4 .runtime .CommonTokenStream ;
55import org .prop4j .Node ;
66import org .prop4j .Not ;
7+ import org .tinylog .Logger ;
8+ import org .variantsync .diffdetective .error .UncheckedUnParseableFormulaException ;
79import org .variantsync .diffdetective .error .UnparseableFormulaException ;
8- import org .variantsync .diffdetective .feature .AbstractingFormulaExtractor ;
10+ import org .variantsync .diffdetective .feature .DiffLineFormulaExtractor ;
911import org .variantsync .diffdetective .feature .ParseErrorListener ;
1012import org .variantsync .diffdetective .feature .antlr .CExpressionLexer ;
1113import org .variantsync .diffdetective .feature .antlr .CExpressionParser ;
2224 *
2325 * @author Paul Bittner, Sören Viegener, Benjamin Moosherr, Alexander Schultheiß
2426 */
25- public class CPPDiffLineFormulaExtractor extends AbstractingFormulaExtractor {
27+ public class CPPDiffLineFormulaExtractor implements DiffLineFormulaExtractor {
2628 // ^[+-]?\s*#\s*(if|ifdef|ifndef|elif)(\s+(.*)|\((.*)\))$
2729 private static final String CPP_ANNOTATION_REGEX = "^[+-]?\\ s*#\\ s*(if|ifdef|ifndef|elif)([\\ s(].*)$" ;
2830 private static final Pattern CPP_ANNOTATION_PATTERN = Pattern .compile (CPP_ANNOTATION_REGEX );
2931
30- public CPPDiffLineFormulaExtractor () {
31- super (CPP_ANNOTATION_PATTERN );
32- }
33-
3432 /**
3533 * Extracts and parses the feature formula from a macro line (possibly within a diff).
3634 *
@@ -39,38 +37,36 @@ public CPPDiffLineFormulaExtractor() {
3937 */
4038 @ Override
4139 public Node extractFormula (final String line ) throws UnparseableFormulaException {
42- // Delegate the formula extraction to AbstractingFormulaExtractor
43- Node fm = super .extractFormula (line );
44-
45- // negate for ifndef
40+ // Match the formula from the macro line
4641 final Matcher matcher = CPP_ANNOTATION_PATTERN .matcher (line );
47- if (matcher .find () && "ifndef" . equals ( matcher . group ( 1 ) )) {
48- fm = new Not ( fm );
42+ if (! matcher .find ()) {
43+ throw new UnparseableFormulaException ( "Could not extract formula from line \" " + line + " \" ." );
4944 }
45+ String annotationType = matcher .group (1 );
46+ String formula = matcher .group (2 );
5047
51- return fm ;
52- }
48+ // abstract complex formulas (e.g., if they contain arithmetics or macro calls)
49+ Node parsedFormula ;
50+ try {
51+ CExpressionLexer lexer = new CExpressionLexer (CharStreams .fromString (formula ));
52+ CommonTokenStream tokens = new CommonTokenStream (lexer );
5353
54- /**
55- * Abstract the given formula.
56- * <p>
57- * First, the visitor uses ANTLR to parse the formula into a parse tree gives the tree to a {@link ControllingCExpressionVisitor}.
58- * The visitor traverses the tree starting from the root, searching for subtrees that must be abstracted.
59- * If such a subtree is found, the visitor calls an {@link AbstractingCExpressionVisitor} to abstract the part of
60- * the formula in the subtree.
61- * </p>
62- *
63- * @param formula that is to be abstracted
64- * @return the abstracted formula
65- */
66- @ Override
67- protected Node abstractFormula (String formula ) {
68- CExpressionLexer lexer = new CExpressionLexer (CharStreams .fromString (formula ));
69- CommonTokenStream tokens = new CommonTokenStream (lexer );
54+ CExpressionParser parser = new CExpressionParser (tokens );
55+ parser .addErrorListener (new ParseErrorListener (formula ));
56+
57+ parsedFormula = parser .expression ().accept (new ControllingCExpressionVisitor ());
58+ } catch (UncheckedUnParseableFormulaException e ) {
59+ throw e .inner ();
60+ } catch (Exception e ) {
61+ Logger .warn (e );
62+ throw new UnparseableFormulaException (e );
63+ }
7064
71- CExpressionParser parser = new CExpressionParser (tokens );
72- parser .addErrorListener (new ParseErrorListener (formula ));
65+ // negate for ifndef
66+ if ("ifndef" .equals (annotationType )) {
67+ parsedFormula = new Not (parsedFormula );
68+ }
7369
74- return parser . expression (). accept ( new ControllingCExpressionVisitor ()) ;
70+ return parsedFormula ;
7571 }
7672}
0 commit comments