|
33 | 33 | import org.antlr.v4.runtime.ConsoleErrorListener; |
34 | 34 | import org.antlr.v4.runtime.RecognitionException; |
35 | 35 | import org.antlr.v4.runtime.Recognizer; |
36 | | -import org.antlr.v4.runtime.tree.ParseTreeWalker; |
37 | 36 |
|
38 | 37 | import java.io.IOException; |
39 | 38 | import java.nio.file.FileSystems; |
@@ -134,7 +133,8 @@ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int |
134 | 133 | }); |
135 | 134 |
|
136 | 135 | UVLListener uvlListener = createUVLListener(); |
137 | | - ParseTreeWalker walker = new ParseTreeWalker(); |
| 136 | + IterativeParseTreeWalker walker = new IterativeParseTreeWalker(); |
| 137 | + |
138 | 138 | walker.walk(uvlListener, UVLJavaParser.constraintLine()); |
139 | 139 |
|
140 | 140 | return uvlListener.getConstraint(); |
@@ -314,8 +314,10 @@ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int |
314 | 314 | }); |
315 | 315 |
|
316 | 316 |
|
| 317 | + |
317 | 318 | UVLListener uvlListener = createUVLListener(); |
318 | | - ParseTreeWalker walker = new ParseTreeWalker(); |
| 319 | + IterativeParseTreeWalker walker = new IterativeParseTreeWalker(); |
| 320 | + |
319 | 321 | walker.walk(uvlListener, UVLJavaParser.featureModel()); |
320 | 322 | FeatureModel featureModel = null; |
321 | 323 |
|
@@ -388,42 +390,55 @@ public void syntaxError(Recognizer<?, ?> recognizer, Object offendingSymbol, int |
388 | 390 | } |
389 | 391 |
|
390 | 392 | private void resolveImportPlaceholders(Constraint constraint, FeatureModel featureModel) { |
391 | | - if (constraint instanceof AndConstraint || constraint instanceof OrConstraint || constraint instanceof NotConstraint || constraint instanceof ImplicationConstraint || constraint instanceof ParenthesisConstraint || constraint instanceof EquivalenceConstraint) { |
392 | | - for (Constraint subPart : constraint.getConstraintSubParts()) { |
393 | | - resolveImportPlaceholders(subPart, featureModel); |
| 393 | + final Deque<Constraint> stack = new ArrayDeque<>(); |
| 394 | + stack.push(constraint); |
| 395 | + |
| 396 | + while (!stack.isEmpty()) { |
| 397 | + final Constraint current = stack.pop(); |
| 398 | + |
| 399 | + if (current instanceof ExpressionConstraint) { |
| 400 | + ExpressionConstraint expressionConstraint = (ExpressionConstraint) current; |
| 401 | + resolveImportPlaceholders(expressionConstraint.getLeft(), featureModel); |
| 402 | + resolveImportPlaceholders(expressionConstraint.getRight(), featureModel); |
| 403 | + } else if (current instanceof LiteralConstraint) { |
| 404 | + LiteralConstraint literalConstraint = (LiteralConstraint) current; |
| 405 | + if (literalConstraint.getReference() instanceof ImportedVariablePlaceholder) { |
| 406 | + ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder) literalConstraint.getReference(); |
| 407 | + literalConstraint.setReference(resolvePlaceholder(placeholder, featureModel)); |
| 408 | + } |
394 | 409 | } |
395 | | - } else if (constraint instanceof ExpressionConstraint) { |
396 | | - ExpressionConstraint expressionConstraint = (ExpressionConstraint) constraint; |
397 | | - resolveImportPlaceholders(expressionConstraint.getLeft(), featureModel); |
398 | | - resolveImportPlaceholders(expressionConstraint.getRight(), featureModel); |
399 | | - } else if (constraint instanceof LiteralConstraint) { |
400 | | - LiteralConstraint literalConstraint = (LiteralConstraint) constraint; |
401 | | - if (literalConstraint.getReference() instanceof ImportedVariablePlaceholder) { |
402 | | - ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder) literalConstraint.getReference(); |
403 | | - literalConstraint.setReference(resolvePlaceholder(placeholder, featureModel)); |
| 410 | + |
| 411 | + final List<Constraint> subConstraints = current.getConstraintSubParts(); |
| 412 | + for (int i = subConstraints.size() - 1; i >= 0; i--) { |
| 413 | + stack.push(subConstraints.get(i)); |
404 | 414 | } |
405 | 415 | } |
406 | 416 | } |
407 | 417 |
|
408 | 418 | private void resolveImportPlaceholders(Expression expression, FeatureModel featureModel) { |
409 | | - if (expression instanceof BinaryExpression) { |
410 | | - BinaryExpression binaryExpression = (BinaryExpression) expression; |
411 | | - resolveImportPlaceholders(binaryExpression.getLeft(), featureModel); |
412 | | - resolveImportPlaceholders(binaryExpression.getRight(), featureModel); |
413 | | - } else if (expression instanceof ParenthesisExpression) { |
414 | | - ParenthesisExpression parenthesisExpression = (ParenthesisExpression) expression; |
415 | | - resolveImportPlaceholders(parenthesisExpression.getContent(), featureModel); |
416 | | - } else if (expression instanceof LengthAggregateFunctionExpression) { |
417 | | - LengthAggregateFunctionExpression lengthAggregateFunctionExpression = (LengthAggregateFunctionExpression) expression; |
418 | | - if (lengthAggregateFunctionExpression.getReference() instanceof ImportedVariablePlaceholder) { |
419 | | - ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder) lengthAggregateFunctionExpression.getReference(); |
420 | | - lengthAggregateFunctionExpression.setReference(resolvePlaceholder(placeholder, featureModel)); |
| 419 | + final Deque<Expression> stack = new ArrayDeque<>(); |
| 420 | + stack.push(expression); |
| 421 | + |
| 422 | + while (!stack.isEmpty()) { |
| 423 | + final Expression current = stack.pop(); |
| 424 | + |
| 425 | + if (current instanceof LengthAggregateFunctionExpression) { |
| 426 | + LengthAggregateFunctionExpression lengthAggregateFunctionExpression = (LengthAggregateFunctionExpression) current; |
| 427 | + if (lengthAggregateFunctionExpression.getReference() instanceof ImportedVariablePlaceholder) { |
| 428 | + ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder) lengthAggregateFunctionExpression.getReference(); |
| 429 | + lengthAggregateFunctionExpression.setReference(resolvePlaceholder(placeholder, featureModel)); |
| 430 | + } |
| 431 | + } else if (current instanceof LiteralExpression) { |
| 432 | + LiteralExpression literalExpression = (LiteralExpression) current; |
| 433 | + if (literalExpression.getContent() instanceof ImportedVariablePlaceholder) { |
| 434 | + ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder) literalExpression.getContent(); |
| 435 | + literalExpression.setContent(resolvePlaceholder(placeholder, featureModel)); |
| 436 | + } |
421 | 437 | } |
422 | | - } else if (expression instanceof LiteralExpression) { |
423 | | - LiteralExpression literalExpression = (LiteralExpression) expression; |
424 | | - if (literalExpression.getContent() instanceof ImportedVariablePlaceholder) { |
425 | | - ImportedVariablePlaceholder placeholder = (ImportedVariablePlaceholder) literalExpression.getContent(); |
426 | | - literalExpression.setContent(resolvePlaceholder(placeholder, featureModel)); |
| 438 | + |
| 439 | + final List<Expression> subExpressions = current.getExpressionSubParts(); |
| 440 | + for (int i = subExpressions.size() - 1; i >= 0; i--) { |
| 441 | + stack.push(subExpressions.get(i)); |
427 | 442 | } |
428 | 443 | } |
429 | 444 | } |
@@ -521,28 +536,38 @@ private void validateTypeLevelConstraints(final FeatureModel featureModel) { |
521 | 536 | } |
522 | 537 |
|
523 | 538 | private boolean validateTypeLevelConstraint(final Constraint constraint) { |
524 | | - boolean result = true; |
525 | | - if (constraint instanceof ExpressionConstraint) { |
526 | | - String leftReturnType = ((ExpressionConstraint) constraint).getLeft().getReturnType(); |
527 | | - String rightReturnType = ((ExpressionConstraint) constraint).getRight().getReturnType(); |
| 539 | + final Deque<Constraint> stack = new ArrayDeque<>(); |
| 540 | + stack.push(constraint); |
528 | 541 |
|
529 | | - if (!(leftReturnType.equalsIgnoreCase(Constants.TRUE) || rightReturnType.equalsIgnoreCase(Constants.TRUE))) { |
530 | | - // if not attribute constraint |
531 | | - result = result && ((ExpressionConstraint) constraint).getLeft().getReturnType().equalsIgnoreCase(((ExpressionConstraint) constraint).getRight().getReturnType()); |
532 | | - } |
533 | | - if (!result) { |
534 | | - return false; |
535 | | - } |
536 | | - for (final Expression expr: ((ExpressionConstraint) constraint).getExpressionSubParts()) { |
537 | | - result = result && validateTypeLevelExpression(expr); |
| 542 | + while (!stack.isEmpty()) { |
| 543 | + final Constraint current = stack.pop(); |
| 544 | + |
| 545 | + if (current instanceof ExpressionConstraint) { |
| 546 | + final ExpressionConstraint expressionConstraint = (ExpressionConstraint) current; |
| 547 | + |
| 548 | + final String leftReturnType = expressionConstraint.getLeft().getReturnType(); |
| 549 | + final String rightReturnType = expressionConstraint.getRight().getReturnType(); |
| 550 | + |
| 551 | + if (!(leftReturnType.equalsIgnoreCase(Constants.TRUE) || rightReturnType.equalsIgnoreCase(Constants.TRUE))) { |
| 552 | + if (!leftReturnType.equalsIgnoreCase(rightReturnType)) { |
| 553 | + return false; |
| 554 | + } |
| 555 | + } |
| 556 | + |
| 557 | + for (final Expression expr : expressionConstraint.getExpressionSubParts()) { |
| 558 | + if (!validateTypeLevelExpression(expr)) { |
| 559 | + return false; |
| 560 | + } |
| 561 | + } |
538 | 562 | } |
539 | | - } |
540 | 563 |
|
541 | | - for (final Constraint subCons: constraint.getConstraintSubParts()) { |
542 | | - result = result && validateTypeLevelConstraint(subCons); |
| 564 | + final List<Constraint> subConstraints = current.getConstraintSubParts(); |
| 565 | + for (int i = subConstraints.size() - 1; i >= 0; i--) { |
| 566 | + stack.push(subConstraints.get(i)); |
| 567 | + } |
543 | 568 | } |
544 | 569 |
|
545 | | - return result; |
| 570 | + return true; |
546 | 571 | } |
547 | 572 |
|
548 | 573 | private boolean validateTypeLevelExpression(final Expression expression) { |
|
0 commit comments