instanceCheck) {
+ StringBuilder sb = new StringBuilder();
+ for (ParseTree subtree : expressionContext.children) {
+ if (instanceCheck.apply(subtree)) {
+ // Some operand (i.e., a subtree) that we have to visit
+ sb.append(subtree.accept(this));
+ } else if (subtree instanceof TerminalNode terminal) {
+ // Some operator (i.e., a leaf node) that requires direct abstraction
+ sb.append(BooleanAbstraction.abstractToken(terminal.getText().trim()));
+ } else {
+ // sanity check: loop does not work as expected
+ throw new IllegalStateException();
+ }
+ }
+ return sb;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/feature/BooleanAbstraction.java b/src/main/java/org/variantsync/diffdetective/feature/BooleanAbstraction.java
index f0e5e20e3..44fe89898 100644
--- a/src/main/java/org/variantsync/diffdetective/feature/BooleanAbstraction.java
+++ b/src/main/java/org/variantsync/diffdetective/feature/BooleanAbstraction.java
@@ -51,69 +51,134 @@ private BooleanAbstraction(){}
public static final String XOR = "__XOR__";
/** Abstraction value for the condition of the ternary operator ?
. */
public static final String THEN = "__THEN__";
- /** Abstraction value for the alternative of the ternary operator :
. */
- public static final String ELSE = "__ELSE__";
+ /** Abstraction value for the alternative of the ternary operator :
, or just colons. */
+ public static final String COLON = "__COLON__";
/** Abstraction value for opening brackets (
. */
public static final String BRACKET_L = "__LB__";
- /** Abstraction value for clsong brackets )
. */
+ /** Abstraction value for closing brackets )
. */
public static final String BRACKET_R = "__RB__";
+ /** Abstraction value for unary 'and' &
. */
+ public static final String U_AND = "__U_AND__";
+ /** Abstraction value for unary star *
. */
+ public static final String U_STAR = "__U_STAR__";
+ /** Abstraction value for unary plus +
. */
+ public static final String U_PLUS = "__U_PLUS__";
+ /** Abstraction value for unary minus -
. */
+ public static final String U_MINUS = "__U_MINUS__";
+ /** Abstraction value for unary tilde ~
. */
+ public static final String U_TILDE = "__U_TILDE__";
+ /** Abstraction value for unary not !
. */
+ public static final String U_NOT = "__U_NOT__";
+ /** Abstraction value for logical and &&
. */
+ public static final String L_AND = "__L_AND__";
+ /** Abstraction value for logical or ||
. */
+ public static final String L_OR = "__L_OR__";
+ /** Abstraction value for dots in paths .
. */
+ public static final String DOT = "__DOT__";
+ /** Abstraction value for quotation marks in paths "
. */
+ public static final String QUOTE = "__QUOTE__";
+ /** Abstraction value for single quotation marks '
. */
+ public static final String SQUOTE = "__SQUOTE__";
+ /** Abstraction value for assign operator =
. */
+ public static final String ASSIGN = "__ASSIGN__";
+ /** Abstraction value for star assign operator *=
. */
+ public static final String STAR_ASSIGN = "__STA___ASSIGN__";
+ /** Abstraction value for div assign operator /=
. */
+ public static final String DIV_ASSIGN = "__DIV___ASSIGN__";
+ /** Abstraction value for mod assign operator %=
. */
+ public static final String MOD_ASSIGN = "__MOD___ASSIGN__";
+ /** Abstraction value for plus assign operator +=
. */
+ public static final String PLUS_ASSIGN = "__PLU___ASSIGN__";
+ /** Abstraction value for minus assign operator -=
. */
+ public static final String MINUS_ASSIGN = "__MIN___ASSIGN__";
+ /** Abstraction value for left shift assign operator <<=
. */
+ public static final String LEFT_SHIFT_ASSIGN = "__LSH___ASSIGN__";
+ /** Abstraction value for right shift assign operator >>=
. */
+ public static final String RIGHT_SHIFT_ASSIGN = "__RSH___ASSIGN__";
+ /** Abstraction value for 'and' assign operator &=
. */
+ public static final String AND_ASSIGN = "__AND___ASSIGN__";
+ /** Abstraction value for xor assign operator ^=
. */
+ public static final String XOR_ASSIGN = "__XOR___ASSIGN__";
+ /** Abstraction value for 'or' assign operator |=
. */
+ public static final String OR_ASSIGN = "__OR___ASSIGN__";
+ /** Abstraction value for whitespace
. */
+ public static final String WHITESPACE = "_";
+ /** Abstraction value for backslash \
. */
+ public static final String BSLASH = "__B_SLASH__";
- private static class Replacement {
- private Pattern pattern;
- private String replacement;
+ // The preprocessor has six special operators that require additional abstraction.
+ // These operators are documented under https://gcc.gnu.org/onlinedocs/cpp/Conditional-Syntax.html
+ /** Abstraction value for has_attribute operator __has_attribute(ATTRIBUTE)
.
+ * One of the six special operators that require abstraction.
+ * */
+ public static final String HAS_ATTRIBUTE = "HAS_ATTRIBUTE_";
+ /** Abstraction value for has_cpp_attribute operator __has_cpp_attribute(ATTRIBUTE)
.
+ * One of the six special preprocessor operators that require abstraction. */
+ public static final String HAS_CPP_ATTRIBUTE = "HAS_CPP_ATTRIBUTE_";
+ /** Abstraction value for has_c_attribute operator __has_c_attribute(ATTRIBUTE)
.
+ * One of the six special preprocessor operators that require abstraction. */
+ public static final String HAS_C_ATTRIBUTE = "HAS_C_ATTRIBUTE_";
+ /** Abstraction value for has_builtin operator __has_builtin(BUILTIN)
.
+ * One of the six special preprocessor operators that require abstraction. */
+ public static final String HAS_BUILTIN = "HAS_BUILTIN_";
+ /** Abstraction value for has_include operator __has_include(INCLUDE)
.
+ * One of the six special preprocessor operators that require abstraction. */
+ public static final String HAS_INCLUDE = "HAS_INCLUDE_";
+ /** Abstraction value for defined operator defined
.
+ * One of the six special preprocessor operators that require abstraction. */
+ public static final String DEFINED = "DEFINED_";
+ private record Replacement(Pattern pattern, String replacement) {
/**
- * @param original the literal string to be replaced if it matches a whole word
+ * @param pattern the literal string to be replaced if it matches a whole word
* @param replacement the replacement with special escape codes according to
- * {@link Matcher#replaceAll}
+ * {@link Matcher#replaceAll}
*/
- private Replacement(Pattern pattern, String replacement) {
- this.pattern = pattern;
- this.replacement = replacement;
+ private Replacement {
}
- /**
- * Creates a new replacement matching {@code original} literally.
- *
- * @param original a string which is searched for literally (without any special
- * characters)
- * @param replacement the literal replacement for strings matched by {@code original}
- */
- public static Replacement literal(String original, String replacement) {
- return new Replacement(
- Pattern.compile(Pattern.quote(original)),
- Matcher.quoteReplacement(replacement)
- );
- }
+ /**
+ * Creates a new replacement matching {@code original} literally.
+ *
+ * @param original a string which is searched for literally (without any special
+ * characters)
+ * @param replacement the literal replacement for strings matched by {@code original}
+ */
+ public static Replacement literal(String original, String replacement) {
+ return new Replacement(
+ Pattern.compile(Pattern.quote(original)),
+ Matcher.quoteReplacement(replacement)
+ );
+ }
- /**
- * Creates a new replacement matching {@code original} literally but only on word
- * boundaries.
- *
- * A word boundary is defined as the transition from a word character (alphanumerical
- * characters) to a non-word character (everything else) or the transition from any
- * character to a bracket (the characters {@code (} and {@code )}).
- *
- * @param original a string which is searched for as a whole word literally (without any
- * special characters)
- * @param replacement the literal replacement for strings matched by {@code original}
- */
- public static Replacement onlyFullWord(String original, String replacement) {
- return new Replacement(
- Pattern.compile("(?<=\\b|[()])" + Pattern.quote(original) + "(?=\\b|[()])"),
- Matcher.quoteReplacement(replacement)
- );
- }
+ /**
+ * Creates a new replacement matching {@code original} literally but only on word
+ * boundaries.
+ *
+ * A word boundary is defined as the transition from a word character (alphanumerical
+ * characters) to a non-word character (everything else) or the transition from any
+ * character to a bracket (the characters {@code (} and {@code )}).
+ *
+ * @param original a string which is searched for as a whole word literally (without any
+ * special characters)
+ * @param replacement the literal replacement for strings matched by {@code original}
+ */
+ public static Replacement onlyFullWord(String original, String replacement) {
+ return new Replacement(
+ Pattern.compile("(?<=\\b|[()])" + Pattern.quote(original) + "(?=\\b|[()])"),
+ Matcher.quoteReplacement(replacement)
+ );
+ }
- /**
- * Replaces all patterns found in {@code value} by its replacement.
- */
- public String applyTo(String value) {
- return pattern.matcher(value).replaceAll(replacement);
+ /**
+ * Replaces all patterns found in {@code value} by its replacement.
+ */
+ public String applyTo(String value) {
+ return pattern.matcher(value).replaceAll(replacement);
+ }
}
- }
- private static final List ARITHMETICS = List.of(
+ private static final List REPLACEMENTS = List.of(
// These replacements are carefully ordered by their length (longest first) to ensure that
// the longest match is replaced first.
Replacement.literal("<<", LSHIFT),
@@ -132,61 +197,72 @@ public String applyTo(String value) {
Replacement.literal("^", XOR),
Replacement.literal("~", NOT),
Replacement.literal("?", THEN),
- Replacement.literal(":", ELSE),
+ Replacement.literal(":", COLON),
+ Replacement.literal( "&&", L_AND),
+ Replacement.literal( "||", L_OR),
+ Replacement.literal( ".", DOT),
+ Replacement.literal( "\"", QUOTE),
+ Replacement.literal( "'", SQUOTE),
+ Replacement.literal( "(", BRACKET_L),
+ Replacement.literal( ")", BRACKET_R),
+ Replacement.literal( "__has_attribute", HAS_ATTRIBUTE),
+ Replacement.literal( "__has_cpp_attribute", HAS_CPP_ATTRIBUTE),
+ Replacement.literal( "__has_c_attribute", HAS_C_ATTRIBUTE),
+ Replacement.literal( "__has_builtin", HAS_BUILTIN),
+ Replacement.literal( "__has_include", HAS_INCLUDE),
+ Replacement.literal( "defined", DEFINED),
+ Replacement.literal( "=", ASSIGN),
+ Replacement.literal( "*=", STAR_ASSIGN),
+ Replacement.literal( "/=", DIV_ASSIGN),
+ Replacement.literal( "%=", MOD_ASSIGN),
+ Replacement.literal( "+=", PLUS_ASSIGN),
+ Replacement.literal( "-=", MINUS_ASSIGN),
+ Replacement.literal( "<<=", LEFT_SHIFT_ASSIGN),
+ Replacement.literal( ">>=", RIGHT_SHIFT_ASSIGN),
+ Replacement.literal( "&=", AND_ASSIGN),
+ Replacement.literal( "^=", XOR_ASSIGN),
+ Replacement.literal( "|=", OR_ASSIGN),
+ Replacement.literal( "\\", BSLASH),
+ new Replacement( Pattern.compile("\\s+"), WHITESPACE),
Replacement.onlyFullWord("&", AND), // && has to be left untouched
Replacement.onlyFullWord("|", OR) // || has to be left untouched
);
- private static final Pattern COMMA = Pattern.compile(",");
- private static final String COMMA_REPLACEMENT = "__";
- private static final Pattern CALL = Pattern.compile("\\((\\w*)\\)");
- private static final String CALL_REPLACEMENT = BRACKET_L + "$1" + BRACKET_R;
-
- private static String abstractAll(String formula, final List replacements) {
- for (var replacement : replacements) {
+ /**
+ * Apply all possible abstraction replacements for substrings of the given formula.
+ * @param formula the formula to abstract
+ * @return a fully abstracted formula
+ */
+ public static String abstractAll(String formula) {
+ for (var replacement : BooleanAbstraction.REPLACEMENTS) {
formula = replacement.applyTo(formula);
}
return formula;
}
/**
- * Abstracts all arithmetics in the given formula.
- * For example, a formula "3 >= 1 + 2" would be abstracted to a single variable "3__GEQ__1__ADD__2".
- * The given formula should be a string of a CPP conforming condition.
- * @param formula The formula whose arithmetics should be abstracted.
- * @return A copy of the formula with abstracted arithmetics.
- */
- public static String arithmetics(final String formula) {
- return abstractAll(formula, ARITHMETICS);
- }
-
- /**
- * Abstracts parentheses, including the commas of macro calls, in the given formula.
+ *
+ * Search for the first replacement that matches the entire text and apply it. This is the case, if the given text
+ * corresponds to a single token (e.g., '&&', '||'). If no replacement for the entire text is found (e.g., if the token
+ * has no replacement), all possible replacements are applied to abstract substrings of the token that require
+ * abstraction.
+ *
*
- * For example, a call "FOO(3, 4, lol)" would be abstracted to a single variable "FOO__3__4__lol".
- * The given formula should be a string of a CPP conforming condition.
- * @param formula The formula whose function calls should be abstracted.
- * @return A copy of the formula with abstracted function calls.
+ * The purpose of this method is to achieve a slight speedup for scenarios in which the text usually contains a single
+ * token. For example, this is useful when abstracting individual tokens of an extracted preprocessor formula
+ * in {@link AbstractingCExpressionVisitor}. In all other cases, directly calling {@link #abstractAll(String)} should
+ * be preferred.
+ *
+ *
+ * @param text the text to abstract
+ * @return a fully abstracted text
*/
- public static String parentheses(String formula) {
- ////// abstract function calls
- /// replace commata in macro calls
- formula = COMMA.matcher(formula).replaceAll(COMMA_REPLACEMENT);
-
- /// inline macro calls as long as there are some
- /// Example
- /// bar(2, foo(A__MUL__(B__PLUS__C))
- /// -> bar(2__foo(A__MUL__(B__PLUS__C))) // because of the comma replacement above
- /// -> bar(2__foo(A__MUL____LB__B__PLUS__C__RB__))
- /// -> bar(2__foo__LB__A__MUL____LB__B__PLUS__C__RB____RB__)
- /// -> bar__LB__2__foo__LB__A__MUL____LB__B__PLUS__C__RB____RB____RB__
- String old;
- do {
- old = formula;
- formula = CALL.matcher(formula).replaceAll(CALL_REPLACEMENT);
-// formula = formula.replaceAll("(\\w+)\\((\\w*)\\)", "$1__$2");
- } while (!old.equals(formula));
-
- return formula;
+ public static String abstractToken(String text) {
+ for (Replacement replacement : REPLACEMENTS) {
+ if (replacement.pattern.matcher(text).matches()) {
+ return replacement.applyTo(text);
+ }
+ }
+ return abstractAll(text);
}
}
diff --git a/src/main/java/org/variantsync/diffdetective/feature/CPPAnnotationParser.java b/src/main/java/org/variantsync/diffdetective/feature/CPPAnnotationParser.java
index 515e21bf0..d413bc488 100644
--- a/src/main/java/org/variantsync/diffdetective/feature/CPPAnnotationParser.java
+++ b/src/main/java/org/variantsync/diffdetective/feature/CPPAnnotationParser.java
@@ -2,7 +2,7 @@
import org.prop4j.Literal;
import org.prop4j.Node;
-import org.variantsync.diffdetective.variation.diff.parse.IllFormedAnnotationException;
+import org.variantsync.diffdetective.error.UnparseableFormulaException;
/**
* A parser of C-preprocessor annotations.
@@ -40,9 +40,9 @@ public CPPAnnotationParser(final PropositionalFormulaParser formulaParser, CPPDi
* @param line The line of code of a preprocessor annotation.
* @return The formula of the macro in the given line.
* If no such formula could be parsed, returns a Literal with the line's condition as name.
- * @throws IllFormedAnnotationException when {@link CPPDiffLineFormulaExtractor#extractFormula(String)} throws.
+ * @throws UnparseableFormulaException when {@link CPPDiffLineFormulaExtractor#extractFormula(String)} throws.
*/
- public Node parseDiffLine(String line) throws IllFormedAnnotationException {
+ public Node parseDiffLine(String line) throws UnparseableFormulaException {
return parseCondition(extractor.extractFormula(line));
}
diff --git a/src/main/java/org/variantsync/diffdetective/feature/CPPDiffLineFormulaExtractor.java b/src/main/java/org/variantsync/diffdetective/feature/CPPDiffLineFormulaExtractor.java
index ddfc51bc8..6b853d4e4 100644
--- a/src/main/java/org/variantsync/diffdetective/feature/CPPDiffLineFormulaExtractor.java
+++ b/src/main/java/org/variantsync/diffdetective/feature/CPPDiffLineFormulaExtractor.java
@@ -1,7 +1,16 @@
package org.variantsync.diffdetective.feature;
-import org.variantsync.diffdetective.variation.diff.parse.IllFormedAnnotationException;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.atn.ATNConfigSet;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.tinylog.Logger;
+import org.variantsync.diffdetective.error.UnparseableFormulaException;
+import org.variantsync.diffdetective.error.UncheckedUnParseableFormulaException;
+import org.variantsync.diffdetective.feature.antlr.CExpressionLexer;
+import org.variantsync.diffdetective.feature.antlr.CExpressionParser;
+import java.util.BitSet;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -11,15 +20,13 @@
* For example, given the annotation "#if defined(A) || B()", the extractor would extract
* "A || B". The extractor detects if, ifdef, ifndef and elif annotations.
* (Other annotations do not have expressions.)
- * The given pre processor statement might also a line in a diff (i.e., preceeded by a - or +).
+ * The given pre-processor statement might also a line in a diff (i.e., preceeded by a - or +).
* @author Paul Bittner, Sören Viegener, Benjamin Moosherr
*/
public class CPPDiffLineFormulaExtractor {
// ^[+-]?\s*#\s*(if|ifdef|ifndef|elif)(\s+(.*)|\((.*)\))$
- private static final String CPP_ANNOTATION_REGEX = "^[+-]?\\s*#\\s*(if|ifdef|ifndef|elif)(\\s+(.*)|\\((.*)\\))$";
+ private static final String CPP_ANNOTATION_REGEX = "^[+-]?\\s*#\\s*(if|ifdef|ifndef|elif)(\\s+(.*)|(\\(.*\\)))$";
private static final Pattern CPP_ANNOTATION_REGEX_PATTERN = Pattern.compile(CPP_ANNOTATION_REGEX);
- private static final Pattern COMMENT_PATTERN = Pattern.compile("/\\*.*?\\*/");
- private static final Pattern DEFINED_PATTERN = Pattern.compile("\\bdefined\\b(\\s*\\(\\s*(\\w*)\\s*\\))?");
/**
* Resolves any macros in the given formula that are relevant for feature annotations.
@@ -38,12 +45,12 @@ protected String resolveFeatureMacroFunctions(String formula) {
* @param line The line of which to get the feature mapping
* @return The feature mapping as a String of the given line
*/
- public String extractFormula(final String line) throws IllFormedAnnotationException {
- // TODO: There still regexes here in replaceAll that could be optimized by precompiling the regexes once.
+ public String extractFormula(final String line) throws UnparseableFormulaException {
final Matcher matcher = CPP_ANNOTATION_REGEX_PATTERN.matcher(line);
- final Supplier couldNotExtractFormula = () ->
- IllFormedAnnotationException.IfWithoutCondition("Could not extract formula from line \""+ line + "\".");
+ final Supplier couldNotExtractFormula = () ->
+ new UnparseableFormulaException("Could not extract formula from line \""+ line + "\".");
+ // Retrieve the formula from the macro line
String fm;
if (matcher.find()) {
if (matcher.group(3) != null) {
@@ -55,21 +62,15 @@ public String extractFormula(final String line) throws IllFormedAnnotationExcept
throw couldNotExtractFormula.get();
}
- // remove comments
- fm = fm.split("//")[0];
- fm = COMMENT_PATTERN.matcher(fm).replaceAll("");
-
- // remove defined()
- fm = DEFINED_PATTERN.matcher(fm).replaceAll("DEFINED_$2");
-
- // remove whitespace
- fm = fm.replaceAll("\\s", "");
-
- fm = resolveFeatureMacroFunctions(fm);
-
- ////// abstract arithmetics
- fm = BooleanAbstraction.arithmetics(fm);
- fm = BooleanAbstraction.parentheses(fm);
+ // abstract complex formulas (e.g., if they contain arithmetics or macro calls)
+ try {
+ fm = abstractFormula(fm);
+ } catch (UncheckedUnParseableFormulaException e) {
+ throw e.inner();
+ } catch (Exception e) {
+ Logger.warn(e);
+ throw new UnparseableFormulaException(e);
+ }
if (fm.isEmpty()) {
throw couldNotExtractFormula.get();
@@ -82,4 +83,43 @@ public String extractFormula(final String line) throws IllFormedAnnotationExcept
return fm;
}
+
+ /**
+ * Abstract the given formula.
+ *
+ * First, the visitor uses ANTLR to parse the formula into a parse tree gives the tree to a {@link ControllingCExpressionVisitor}.
+ * The visitor traverses the tree starting from the root, searching for subtrees that must be abstracted.
+ * If such a subtree is found, the visitor calls an {@link AbstractingCExpressionVisitor} to abstract the part of
+ * the formula in the subtree.
+ *
+ * @param formula that is to be abstracted
+ * @return the abstracted formula
+ */
+ private String abstractFormula(String formula) {
+ CExpressionLexer lexer = new CExpressionLexer(CharStreams.fromString(formula));
+ CommonTokenStream tokens = new CommonTokenStream(lexer);
+ CExpressionParser parser = new CExpressionParser(tokens);
+ parser.addErrorListener(new ANTLRErrorListener() {
+ @Override
+ public void syntaxError(Recognizer, ?> recognizer, Object o, int i, int i1, String s, RecognitionException e) {
+ Logger.warn("syntax error: {} ; {}", s, e);
+ Logger.warn("formula: {}", formula);
+ throw new UncheckedUnParseableFormulaException(s, e);
+ }
+
+ @Override
+ public void reportAmbiguity(Parser parser, DFA dfa, int i, int i1, boolean b, BitSet bitSet, ATNConfigSet atnConfigSet) {
+ }
+
+ @Override
+ public void reportAttemptingFullContext(Parser parser, DFA dfa, int i, int i1, BitSet bitSet, ATNConfigSet atnConfigSet) {
+ }
+
+ @Override
+ public void reportContextSensitivity(Parser parser, DFA dfa, int i, int i1, int i2, ATNConfigSet atnConfigSet) {
+ }
+ });
+ ParseTree tree = parser.expression();
+ return tree.accept(new ControllingCExpressionVisitor()).toString();
+ }
}
diff --git a/src/main/java/org/variantsync/diffdetective/feature/ControllingCExpressionVisitor.java b/src/main/java/org/variantsync/diffdetective/feature/ControllingCExpressionVisitor.java
new file mode 100644
index 000000000..658237a8c
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/ControllingCExpressionVisitor.java
@@ -0,0 +1,350 @@
+package org.variantsync.diffdetective.feature;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
+import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.TerminalNode;
+import org.variantsync.diffdetective.feature.antlr.CExpressionParser;
+import org.variantsync.diffdetective.feature.antlr.CExpressionVisitor;
+
+import java.util.function.Function;
+
+/**
+ * Visitor that controls how formulas given as an ANTLR parse tree are abstracted.
+ * To this end, the visitor traverses the parse tree, searching for subtrees that should be abstracted.
+ * If such a subtree is found, the visitor calls an {@link AbstractingCExpressionVisitor} to abstract the entire subtree.
+ * Only those parts of a formula are abstracted that require abstraction, leaving ancestors in the tree unchanged.
+ */
+@SuppressWarnings("CheckReturnValue")
+public class ControllingCExpressionVisitor extends AbstractParseTreeVisitor implements CExpressionVisitor {
+ private final AbstractingCExpressionVisitor abstractingVisitor = new AbstractingCExpressionVisitor();
+
+ public ControllingCExpressionVisitor() {}
+
+ // conditionalExpression
+ // : logicalOrExpression ('?' expression ':' conditionalExpression)?
+ // ;
+ @Override public StringBuilder visitConditionalExpression(CExpressionParser.ConditionalExpressionContext ctx) {
+ if (ctx.expression() != null) {
+ // logicalOrExpression '?' expression ':' conditionalExpression
+ // We have to abstract the expression if it is a ternary expression
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // logicalOrExpression
+ return ctx.logicalOrExpression().accept(this);
+ }
+ }
+
+ // primaryExpression
+ // : macroExpression
+ // | Identifier
+ // | Constant
+ // | StringLiteral+
+ // | '(' expression ')'
+ // | unaryOperator primaryExpression
+ // | specialOperator
+ // ;
+ @Override public StringBuilder visitPrimaryExpression(CExpressionParser.PrimaryExpressionContext ctx) {
+ // macroExpression
+ if (ctx.macroExpression() != null) {
+ return ctx.macroExpression().accept(abstractingVisitor);
+ }
+ // Identifier
+ if (ctx.Identifier() != null) {
+ // Terminal
+ return ctx.accept(abstractingVisitor);
+ }
+ // Constant
+ if (ctx.Constant() != null) {
+ // Terminal
+ return new StringBuilder(ctx.Constant().getText().trim());
+ }
+ // StringLiteral+
+ if (!ctx.StringLiteral().isEmpty()) {
+ return ctx.accept(abstractingVisitor);
+ }
+ // '(' expression ')'
+ if (ctx.expression() != null) {
+ StringBuilder sb = ctx.expression().accept(this);
+ sb.insert(0, "(");
+ sb.append(")");
+ return sb;
+ }
+ // unaryOperator primaryExpression
+ if (ctx.unaryOperator() != null) {
+ StringBuilder sb = ctx.unaryOperator().accept(this);
+ sb.append(ctx.primaryExpression().accept(this));
+ return sb;
+ }
+ // specialOperator
+ if (ctx.specialOperator() != null) {
+ return ctx.specialOperator().accept(abstractingVisitor);
+ }
+
+ // Unreachable
+ throw new IllegalStateException("Unreachable code.");
+ }
+
+ // unaryOperator
+ // : '&' | '*' | '+' | '-' | '~' | '!'
+ // ;
+ @Override public StringBuilder visitUnaryOperator(CExpressionParser.UnaryOperatorContext ctx) { return new StringBuilder(ctx.getText()); }
+
+
+ // namespaceExpression
+ // : primaryExpression (':' primaryExpression)*
+ // ;
+ @Override
+ public StringBuilder visitNamespaceExpression(CExpressionParser.NamespaceExpressionContext ctx) {
+ if (ctx.primaryExpression().size() > 1) {
+ // primaryExpression (('*'|'/'|'%') primaryExpression)+
+ // We have to abstract the arithmetic expression if there is more than one operand
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // primaryExpression
+ // There is exactly one child expression
+ return ctx.primaryExpression(0).accept(this);
+ }
+ }
+
+ // multiplicativeExpression
+ // : primaryExpression (('*'|'/'|'%') primaryExpression)*
+ // ;
+ @Override public StringBuilder visitMultiplicativeExpression(CExpressionParser.MultiplicativeExpressionContext ctx) {
+ if (ctx.namespaceExpression().size() > 1) {
+ // primaryExpression (('*'|'/'|'%') primaryExpression)+
+ // We have to abstract the arithmetic expression if there is more than one operand
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // primaryExpression
+ // There is exactly one child expression
+ return ctx.namespaceExpression(0).accept(this);
+ }
+ }
+
+ // additiveExpression
+ // : multiplicativeExpression (('+'|'-') multiplicativeExpression)*
+ // ;
+ @Override public StringBuilder visitAdditiveExpression(CExpressionParser.AdditiveExpressionContext ctx) {
+ if (ctx.multiplicativeExpression().size() > 1) {
+ // multiplicativeExpression (('+'|'-') multiplicativeExpression)+
+ // We have to abstract the arithmetic expression if there is more than one operand
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // multiplicativeExpression
+ // There is exactly one child expression
+ return ctx.multiplicativeExpression(0).accept(this);
+ }
+ }
+
+ // shiftExpression
+ // : additiveExpression (('<<'|'>>') additiveExpression)*
+ // ;
+ @Override public StringBuilder visitShiftExpression(CExpressionParser.ShiftExpressionContext ctx) {
+ if (ctx.additiveExpression().size() > 1) {
+ // additiveExpression (('<<'|'>>') additiveExpression)+
+ // We have to abstract the shift expression if there is more than one operand
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // additiveExpression
+ // There is exactly one child expression
+ return ctx.additiveExpression(0).accept(this);
+ }
+ }
+
+ // relationalExpression
+ // : shiftExpression (('<'|'>'|'<='|'>=') shiftExpression)*
+ // ;
+ @Override public StringBuilder visitRelationalExpression(CExpressionParser.RelationalExpressionContext ctx) {
+ if (ctx.shiftExpression().size() > 1) {
+ // shiftExpression (('<'|'>'|'<='|'>=') shiftExpression)+
+ // We have to abstract the relational expression if there is more than one operand
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // shiftExpression
+ // There is exactly one child expression
+ return ctx.shiftExpression(0).accept(this);
+ }
+ }
+
+ // equalityExpression
+ // : relationalExpression (('=='| '!=') relationalExpression)*
+ // ;
+ @Override public StringBuilder visitEqualityExpression(CExpressionParser.EqualityExpressionContext ctx) {
+ if (ctx.relationalExpression().size() > 1) {
+ // relationalExpression (('=='| '!=') relationalExpression)+
+ // We have to abstract the equality expression if there is more than one operand
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // relationalExpression
+ // There is exactly one child expression
+ return ctx.relationalExpression(0).accept(this);
+ }
+ }
+
+ // specialOperator
+ // : HasAttribute ('(' specialOperatorArgument ')')?
+ // | HasCPPAttribute ('(' specialOperatorArgument ')')?
+ // | HasCAttribute ('(' specialOperatorArgument ')')?
+ // | HasBuiltin ('(' specialOperatorArgument ')')?
+ // | HasInclude ('(' (PathLiteral | StringLiteral) ')')?
+ // | Defined ('(' specialOperatorArgument ')')
+ // | Defined specialOperatorArgument?
+ // ;
+ @Override public StringBuilder visitSpecialOperator(CExpressionParser.SpecialOperatorContext ctx) {
+ // We have to abstract the special operator
+ return ctx.accept(abstractingVisitor);
+ }
+
+ // specialOperatorArgument
+ // : HasAttribute
+ // | HasCPPAttribute
+ // | HasCAttribute
+ // | HasBuiltin
+ // | HasInclude
+ // | Defined
+ // | Identifier
+ // ;
+ @Override
+ public StringBuilder visitSpecialOperatorArgument(CExpressionParser.SpecialOperatorArgumentContext ctx) {
+ return ctx.accept(abstractingVisitor);
+ }
+
+ // macroExpression
+ // : Identifier '(' argumentExpressionList? ')'
+ // ;
+ @Override
+ public StringBuilder visitMacroExpression(CExpressionParser.MacroExpressionContext ctx) {
+ return ctx.accept(abstractingVisitor);
+ }
+
+ // argumentExpressionList
+ // : assignmentExpression (',' assignmentExpression)*
+ // | assignmentExpression (assignmentExpression)*
+ // ;
+ @Override
+ public StringBuilder visitArgumentExpressionList(CExpressionParser.ArgumentExpressionListContext ctx) {
+ return ctx.accept(abstractingVisitor);
+ }
+
+ // assignmentExpression
+ // : conditionalExpression
+ // | DigitSequence // for
+ // | PathLiteral
+ // | StringLiteral
+ // | primaryExpression assignmentOperator assignmentExpression
+ // ;
+ @Override
+ public StringBuilder visitAssignmentExpression(CExpressionParser.AssignmentExpressionContext ctx) {
+ if (ctx.conditionalExpression() != null) {
+ return ctx.conditionalExpression().accept(this);
+ } else {
+ return ctx.accept(abstractingVisitor);
+ }
+ }
+
+ // assignmentOperator
+ // : '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='
+ // ;
+ @Override
+ public StringBuilder visitAssignmentOperator(CExpressionParser.AssignmentOperatorContext ctx) {
+ return ctx.accept(abstractingVisitor);
+ }
+
+ // expression
+ // : assignmentExpression (',' assignmentExpression)*
+ // ;
+ @Override
+ public StringBuilder visitExpression(CExpressionParser.ExpressionContext ctx) {
+ if (ctx.assignmentExpression().size() > 1) {
+ // assignmentExpression (',' assignmentExpression)+
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // assignmentExpression
+ return ctx.assignmentExpression(0).accept(this);
+ }
+ }
+
+ // andExpression
+ // : equalityExpression ( '&' equalityExpression)*
+ // ;
+ @Override public StringBuilder visitAndExpression(CExpressionParser.AndExpressionContext ctx) {
+ if (ctx.equalityExpression().size() > 1) {
+ // equalityExpression ( '&' equalityExpression)+
+ // We have to abstract the 'and' expression if there is more than one operand
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // equalityExpression
+ // There is exactly one child expression
+ return ctx.equalityExpression(0).accept(this);
+ }
+ }
+
+ // exclusiveOrExpression
+ // : andExpression ('^' andExpression)*
+ // ;
+ @Override public StringBuilder visitExclusiveOrExpression(CExpressionParser.ExclusiveOrExpressionContext ctx) {
+ if (ctx.andExpression().size() > 1) {
+ // andExpression ('^' andExpression)+
+ // We have to abstract the xor expression if there is more than one operand
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // andExpression
+ // There is exactly one child expression
+ return ctx.andExpression(0).accept(this);
+ }
+ }
+
+ // inclusiveOrExpression
+ // : exclusiveOrExpression ('|' exclusiveOrExpression)*
+ // ;
+ @Override public StringBuilder visitInclusiveOrExpression(CExpressionParser.InclusiveOrExpressionContext ctx) {
+ if (ctx.exclusiveOrExpression().size() > 1) {
+ // exclusiveOrExpression ('|' exclusiveOrExpression)+
+ // We have to abstract the 'or' expression if there is more than one operand
+ return ctx.accept(abstractingVisitor);
+ } else {
+ // exclusiveOrExpression
+ // There is exactly one child expression
+ return ctx.exclusiveOrExpression(0).accept(this);
+ }
+ }
+
+ // logicalAndExpression
+ // : logicalOperand ( '&&' logicalOperand)*
+ // ;
+ @Override public StringBuilder visitLogicalAndExpression(CExpressionParser.LogicalAndExpressionContext ctx) {
+ return visitLogicalExpression(ctx, childExpression -> childExpression instanceof CExpressionParser.LogicalOperandContext);
+ }
+
+ // logicalOrExpression
+ // : logicalAndExpression ( '||' logicalAndExpression)*
+ // ;
+ @Override public StringBuilder visitLogicalOrExpression(CExpressionParser.LogicalOrExpressionContext ctx) {
+ return visitLogicalExpression(ctx, childExpression -> childExpression instanceof CExpressionParser.LogicalAndExpressionContext);
+ }
+
+ // logicalOperand
+ // : inclusiveOrExpression
+ // ;
+ @Override
+ public StringBuilder visitLogicalOperand(CExpressionParser.LogicalOperandContext ctx) {
+ return ctx.inclusiveOrExpression().accept(this);
+ }
+
+ private StringBuilder visitLogicalExpression(ParserRuleContext expressionContext, Function instanceCheck) {
+ StringBuilder sb = new StringBuilder();
+ for (ParseTree subtree : expressionContext.children) {
+ if (instanceCheck.apply(subtree)) {
+ // logicalAndExpression | InclusiveOrExpression
+ sb.append(subtree.accept(this));
+ } else if (subtree instanceof TerminalNode terminal) {
+ // '&&' | '||'
+ sb.append(terminal.getText().trim());
+ } else {
+ // loop does not work as expected
+ throw new IllegalStateException();
+ }
+ }
+ return sb;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpression.interp b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpression.interp
new file mode 100644
index 000000000..34e8b181c
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpression.interp
@@ -0,0 +1,165 @@
+token literal names:
+null
+'('
+')'
+'['
+']'
+'{'
+'}'
+'<'
+'<='
+'>'
+'>='
+'<<'
+'>>'
+'+'
+'++'
+'-'
+'--'
+'*'
+'/'
+'%'
+'&'
+'|'
+'&&'
+'||'
+'^'
+'!'
+'~'
+'?'
+':'
+';'
+','
+'='
+'*='
+'/='
+'%='
+'+='
+'-='
+'<<='
+'>>='
+'&='
+'^='
+'|='
+'=='
+'!='
+'->'
+'.'
+'...'
+'__has_attribute'
+'__has_cpp_attribute'
+'__has_c_attribute'
+'__has_builtin'
+'__has_include'
+'defined'
+null
+null
+null
+null
+null
+'#'
+'@'
+'$'
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+LeftParen
+RightParen
+LeftBracket
+RightBracket
+LeftBrace
+RightBrace
+Less
+LessEqual
+Greater
+GreaterEqual
+LeftShift
+RightShift
+Plus
+PlusPlus
+Minus
+MinusMinus
+Star
+Div
+Mod
+And
+Or
+AndAnd
+OrOr
+Caret
+Not
+Tilde
+Question
+Colon
+Semi
+Comma
+Assign
+StarAssign
+DivAssign
+ModAssign
+PlusAssign
+MinusAssign
+LeftShiftAssign
+RightShiftAssign
+AndAssign
+XorAssign
+OrAssign
+Equal
+NotEqual
+Arrow
+Dot
+Ellipsis
+HasAttribute
+HasCPPAttribute
+HasCAttribute
+HasBuiltin
+HasInclude
+Defined
+Identifier
+Constant
+DigitSequence
+StringLiteral
+PathLiteral
+NumberSign
+AtSign
+Dollar
+AsmBlock
+Whitespace
+Newline
+BlockComment
+OpenBlockComment
+LineComment
+
+rule names:
+expression
+conditionalExpression
+primaryExpression
+specialOperator
+specialOperatorArgument
+unaryOperator
+namespaceExpression
+multiplicativeExpression
+additiveExpression
+shiftExpression
+relationalExpression
+equalityExpression
+andExpression
+exclusiveOrExpression
+inclusiveOrExpression
+logicalAndExpression
+logicalOrExpression
+logicalOperand
+macroExpression
+argumentExpressionList
+assignmentExpression
+assignmentOperator
+
+
+atn:
+[4, 1, 66, 255, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 1, 0, 1, 0, 1, 0, 5, 0, 48, 8, 0, 10, 0, 12, 0, 51, 9, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 59, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 4, 2, 65, 8, 2, 11, 2, 12, 2, 66, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 3, 2, 77, 8, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 84, 8, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 91, 8, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 98, 8, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 105, 8, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 112, 8, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 121, 8, 3, 3, 3, 123, 8, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 5, 6, 132, 8, 6, 10, 6, 12, 6, 135, 9, 6, 1, 7, 1, 7, 1, 7, 5, 7, 140, 8, 7, 10, 7, 12, 7, 143, 9, 7, 1, 8, 1, 8, 1, 8, 5, 8, 148, 8, 8, 10, 8, 12, 8, 151, 9, 8, 1, 9, 1, 9, 1, 9, 5, 9, 156, 8, 9, 10, 9, 12, 9, 159, 9, 9, 1, 10, 1, 10, 1, 10, 5, 10, 164, 8, 10, 10, 10, 12, 10, 167, 9, 10, 1, 11, 1, 11, 1, 11, 5, 11, 172, 8, 11, 10, 11, 12, 11, 175, 9, 11, 1, 12, 1, 12, 1, 12, 5, 12, 180, 8, 12, 10, 12, 12, 12, 183, 9, 12, 1, 13, 1, 13, 1, 13, 5, 13, 188, 8, 13, 10, 13, 12, 13, 191, 9, 13, 1, 14, 1, 14, 1, 14, 5, 14, 196, 8, 14, 10, 14, 12, 14, 199, 9, 14, 1, 15, 1, 15, 1, 15, 5, 15, 204, 8, 15, 10, 15, 12, 15, 207, 9, 15, 1, 16, 1, 16, 1, 16, 5, 16, 212, 8, 16, 10, 16, 12, 16, 215, 9, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 3, 18, 222, 8, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 5, 19, 229, 8, 19, 10, 19, 12, 19, 232, 9, 19, 1, 19, 1, 19, 5, 19, 236, 8, 19, 10, 19, 12, 19, 239, 9, 19, 3, 19, 241, 8, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 3, 20, 251, 8, 20, 1, 21, 1, 21, 1, 21, 0, 0, 22, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 0, 8, 2, 0, 47, 53, 56, 57, 5, 0, 13, 13, 15, 15, 17, 17, 20, 20, 25, 26, 1, 0, 17, 19, 2, 0, 13, 13, 15, 15, 1, 0, 11, 12, 1, 0, 7, 10, 1, 0, 42, 43, 1, 0, 31, 41, 272, 0, 44, 1, 0, 0, 0, 2, 52, 1, 0, 0, 0, 4, 76, 1, 0, 0, 0, 6, 122, 1, 0, 0, 0, 8, 124, 1, 0, 0, 0, 10, 126, 1, 0, 0, 0, 12, 128, 1, 0, 0, 0, 14, 136, 1, 0, 0, 0, 16, 144, 1, 0, 0, 0, 18, 152, 1, 0, 0, 0, 20, 160, 1, 0, 0, 0, 22, 168, 1, 0, 0, 0, 24, 176, 1, 0, 0, 0, 26, 184, 1, 0, 0, 0, 28, 192, 1, 0, 0, 0, 30, 200, 1, 0, 0, 0, 32, 208, 1, 0, 0, 0, 34, 216, 1, 0, 0, 0, 36, 218, 1, 0, 0, 0, 38, 240, 1, 0, 0, 0, 40, 250, 1, 0, 0, 0, 42, 252, 1, 0, 0, 0, 44, 49, 3, 40, 20, 0, 45, 46, 5, 30, 0, 0, 46, 48, 3, 40, 20, 0, 47, 45, 1, 0, 0, 0, 48, 51, 1, 0, 0, 0, 49, 47, 1, 0, 0, 0, 49, 50, 1, 0, 0, 0, 50, 1, 1, 0, 0, 0, 51, 49, 1, 0, 0, 0, 52, 58, 3, 32, 16, 0, 53, 54, 5, 27, 0, 0, 54, 55, 3, 0, 0, 0, 55, 56, 5, 28, 0, 0, 56, 57, 3, 2, 1, 0, 57, 59, 1, 0, 0, 0, 58, 53, 1, 0, 0, 0, 58, 59, 1, 0, 0, 0, 59, 3, 1, 0, 0, 0, 60, 77, 3, 36, 18, 0, 61, 77, 5, 53, 0, 0, 62, 77, 5, 54, 0, 0, 63, 65, 5, 56, 0, 0, 64, 63, 1, 0, 0, 0, 65, 66, 1, 0, 0, 0, 66, 64, 1, 0, 0, 0, 66, 67, 1, 0, 0, 0, 67, 77, 1, 0, 0, 0, 68, 69, 5, 1, 0, 0, 69, 70, 3, 0, 0, 0, 70, 71, 5, 2, 0, 0, 71, 77, 1, 0, 0, 0, 72, 73, 3, 10, 5, 0, 73, 74, 3, 4, 2, 0, 74, 77, 1, 0, 0, 0, 75, 77, 3, 6, 3, 0, 76, 60, 1, 0, 0, 0, 76, 61, 1, 0, 0, 0, 76, 62, 1, 0, 0, 0, 76, 64, 1, 0, 0, 0, 76, 68, 1, 0, 0, 0, 76, 72, 1, 0, 0, 0, 76, 75, 1, 0, 0, 0, 77, 5, 1, 0, 0, 0, 78, 83, 5, 47, 0, 0, 79, 80, 5, 1, 0, 0, 80, 81, 3, 8, 4, 0, 81, 82, 5, 2, 0, 0, 82, 84, 1, 0, 0, 0, 83, 79, 1, 0, 0, 0, 83, 84, 1, 0, 0, 0, 84, 123, 1, 0, 0, 0, 85, 90, 5, 48, 0, 0, 86, 87, 5, 1, 0, 0, 87, 88, 3, 8, 4, 0, 88, 89, 5, 2, 0, 0, 89, 91, 1, 0, 0, 0, 90, 86, 1, 0, 0, 0, 90, 91, 1, 0, 0, 0, 91, 123, 1, 0, 0, 0, 92, 97, 5, 49, 0, 0, 93, 94, 5, 1, 0, 0, 94, 95, 3, 8, 4, 0, 95, 96, 5, 2, 0, 0, 96, 98, 1, 0, 0, 0, 97, 93, 1, 0, 0, 0, 97, 98, 1, 0, 0, 0, 98, 123, 1, 0, 0, 0, 99, 104, 5, 50, 0, 0, 100, 101, 5, 1, 0, 0, 101, 102, 3, 8, 4, 0, 102, 103, 5, 2, 0, 0, 103, 105, 1, 0, 0, 0, 104, 100, 1, 0, 0, 0, 104, 105, 1, 0, 0, 0, 105, 123, 1, 0, 0, 0, 106, 111, 5, 51, 0, 0, 107, 108, 5, 1, 0, 0, 108, 109, 3, 8, 4, 0, 109, 110, 5, 2, 0, 0, 110, 112, 1, 0, 0, 0, 111, 107, 1, 0, 0, 0, 111, 112, 1, 0, 0, 0, 112, 123, 1, 0, 0, 0, 113, 114, 5, 52, 0, 0, 114, 115, 5, 1, 0, 0, 115, 116, 3, 8, 4, 0, 116, 117, 5, 2, 0, 0, 117, 123, 1, 0, 0, 0, 118, 120, 5, 52, 0, 0, 119, 121, 3, 8, 4, 0, 120, 119, 1, 0, 0, 0, 120, 121, 1, 0, 0, 0, 121, 123, 1, 0, 0, 0, 122, 78, 1, 0, 0, 0, 122, 85, 1, 0, 0, 0, 122, 92, 1, 0, 0, 0, 122, 99, 1, 0, 0, 0, 122, 106, 1, 0, 0, 0, 122, 113, 1, 0, 0, 0, 122, 118, 1, 0, 0, 0, 123, 7, 1, 0, 0, 0, 124, 125, 7, 0, 0, 0, 125, 9, 1, 0, 0, 0, 126, 127, 7, 1, 0, 0, 127, 11, 1, 0, 0, 0, 128, 133, 3, 4, 2, 0, 129, 130, 5, 28, 0, 0, 130, 132, 3, 4, 2, 0, 131, 129, 1, 0, 0, 0, 132, 135, 1, 0, 0, 0, 133, 131, 1, 0, 0, 0, 133, 134, 1, 0, 0, 0, 134, 13, 1, 0, 0, 0, 135, 133, 1, 0, 0, 0, 136, 141, 3, 12, 6, 0, 137, 138, 7, 2, 0, 0, 138, 140, 3, 12, 6, 0, 139, 137, 1, 0, 0, 0, 140, 143, 1, 0, 0, 0, 141, 139, 1, 0, 0, 0, 141, 142, 1, 0, 0, 0, 142, 15, 1, 0, 0, 0, 143, 141, 1, 0, 0, 0, 144, 149, 3, 14, 7, 0, 145, 146, 7, 3, 0, 0, 146, 148, 3, 14, 7, 0, 147, 145, 1, 0, 0, 0, 148, 151, 1, 0, 0, 0, 149, 147, 1, 0, 0, 0, 149, 150, 1, 0, 0, 0, 150, 17, 1, 0, 0, 0, 151, 149, 1, 0, 0, 0, 152, 157, 3, 16, 8, 0, 153, 154, 7, 4, 0, 0, 154, 156, 3, 16, 8, 0, 155, 153, 1, 0, 0, 0, 156, 159, 1, 0, 0, 0, 157, 155, 1, 0, 0, 0, 157, 158, 1, 0, 0, 0, 158, 19, 1, 0, 0, 0, 159, 157, 1, 0, 0, 0, 160, 165, 3, 18, 9, 0, 161, 162, 7, 5, 0, 0, 162, 164, 3, 18, 9, 0, 163, 161, 1, 0, 0, 0, 164, 167, 1, 0, 0, 0, 165, 163, 1, 0, 0, 0, 165, 166, 1, 0, 0, 0, 166, 21, 1, 0, 0, 0, 167, 165, 1, 0, 0, 0, 168, 173, 3, 20, 10, 0, 169, 170, 7, 6, 0, 0, 170, 172, 3, 20, 10, 0, 171, 169, 1, 0, 0, 0, 172, 175, 1, 0, 0, 0, 173, 171, 1, 0, 0, 0, 173, 174, 1, 0, 0, 0, 174, 23, 1, 0, 0, 0, 175, 173, 1, 0, 0, 0, 176, 181, 3, 22, 11, 0, 177, 178, 5, 20, 0, 0, 178, 180, 3, 22, 11, 0, 179, 177, 1, 0, 0, 0, 180, 183, 1, 0, 0, 0, 181, 179, 1, 0, 0, 0, 181, 182, 1, 0, 0, 0, 182, 25, 1, 0, 0, 0, 183, 181, 1, 0, 0, 0, 184, 189, 3, 24, 12, 0, 185, 186, 5, 24, 0, 0, 186, 188, 3, 24, 12, 0, 187, 185, 1, 0, 0, 0, 188, 191, 1, 0, 0, 0, 189, 187, 1, 0, 0, 0, 189, 190, 1, 0, 0, 0, 190, 27, 1, 0, 0, 0, 191, 189, 1, 0, 0, 0, 192, 197, 3, 26, 13, 0, 193, 194, 5, 21, 0, 0, 194, 196, 3, 26, 13, 0, 195, 193, 1, 0, 0, 0, 196, 199, 1, 0, 0, 0, 197, 195, 1, 0, 0, 0, 197, 198, 1, 0, 0, 0, 198, 29, 1, 0, 0, 0, 199, 197, 1, 0, 0, 0, 200, 205, 3, 34, 17, 0, 201, 202, 5, 22, 0, 0, 202, 204, 3, 34, 17, 0, 203, 201, 1, 0, 0, 0, 204, 207, 1, 0, 0, 0, 205, 203, 1, 0, 0, 0, 205, 206, 1, 0, 0, 0, 206, 31, 1, 0, 0, 0, 207, 205, 1, 0, 0, 0, 208, 213, 3, 30, 15, 0, 209, 210, 5, 23, 0, 0, 210, 212, 3, 30, 15, 0, 211, 209, 1, 0, 0, 0, 212, 215, 1, 0, 0, 0, 213, 211, 1, 0, 0, 0, 213, 214, 1, 0, 0, 0, 214, 33, 1, 0, 0, 0, 215, 213, 1, 0, 0, 0, 216, 217, 3, 28, 14, 0, 217, 35, 1, 0, 0, 0, 218, 219, 5, 53, 0, 0, 219, 221, 5, 1, 0, 0, 220, 222, 3, 38, 19, 0, 221, 220, 1, 0, 0, 0, 221, 222, 1, 0, 0, 0, 222, 223, 1, 0, 0, 0, 223, 224, 5, 2, 0, 0, 224, 37, 1, 0, 0, 0, 225, 230, 3, 40, 20, 0, 226, 227, 5, 30, 0, 0, 227, 229, 3, 40, 20, 0, 228, 226, 1, 0, 0, 0, 229, 232, 1, 0, 0, 0, 230, 228, 1, 0, 0, 0, 230, 231, 1, 0, 0, 0, 231, 241, 1, 0, 0, 0, 232, 230, 1, 0, 0, 0, 233, 237, 3, 40, 20, 0, 234, 236, 3, 40, 20, 0, 235, 234, 1, 0, 0, 0, 236, 239, 1, 0, 0, 0, 237, 235, 1, 0, 0, 0, 237, 238, 1, 0, 0, 0, 238, 241, 1, 0, 0, 0, 239, 237, 1, 0, 0, 0, 240, 225, 1, 0, 0, 0, 240, 233, 1, 0, 0, 0, 241, 39, 1, 0, 0, 0, 242, 251, 3, 2, 1, 0, 243, 251, 5, 55, 0, 0, 244, 251, 5, 57, 0, 0, 245, 251, 5, 56, 0, 0, 246, 247, 3, 4, 2, 0, 247, 248, 3, 42, 21, 0, 248, 249, 3, 40, 20, 0, 249, 251, 1, 0, 0, 0, 250, 242, 1, 0, 0, 0, 250, 243, 1, 0, 0, 0, 250, 244, 1, 0, 0, 0, 250, 245, 1, 0, 0, 0, 250, 246, 1, 0, 0, 0, 251, 41, 1, 0, 0, 0, 252, 253, 7, 7, 0, 0, 253, 43, 1, 0, 0, 0, 27, 49, 58, 66, 76, 83, 90, 97, 104, 111, 120, 122, 133, 141, 149, 157, 165, 173, 181, 189, 197, 205, 213, 221, 230, 237, 240, 250]
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpression.tokens b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpression.tokens
new file mode 100644
index 000000000..c9106f241
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpression.tokens
@@ -0,0 +1,121 @@
+LeftParen=1
+RightParen=2
+LeftBracket=3
+RightBracket=4
+LeftBrace=5
+RightBrace=6
+Less=7
+LessEqual=8
+Greater=9
+GreaterEqual=10
+LeftShift=11
+RightShift=12
+Plus=13
+PlusPlus=14
+Minus=15
+MinusMinus=16
+Star=17
+Div=18
+Mod=19
+And=20
+Or=21
+AndAnd=22
+OrOr=23
+Caret=24
+Not=25
+Tilde=26
+Question=27
+Colon=28
+Semi=29
+Comma=30
+Assign=31
+StarAssign=32
+DivAssign=33
+ModAssign=34
+PlusAssign=35
+MinusAssign=36
+LeftShiftAssign=37
+RightShiftAssign=38
+AndAssign=39
+XorAssign=40
+OrAssign=41
+Equal=42
+NotEqual=43
+Arrow=44
+Dot=45
+Ellipsis=46
+HasAttribute=47
+HasCPPAttribute=48
+HasCAttribute=49
+HasBuiltin=50
+HasInclude=51
+Defined=52
+Identifier=53
+Constant=54
+DigitSequence=55
+StringLiteral=56
+PathLiteral=57
+NumberSign=58
+AtSign=59
+Dollar=60
+AsmBlock=61
+Whitespace=62
+Newline=63
+BlockComment=64
+OpenBlockComment=65
+LineComment=66
+'('=1
+')'=2
+'['=3
+']'=4
+'{'=5
+'}'=6
+'<'=7
+'<='=8
+'>'=9
+'>='=10
+'<<'=11
+'>>'=12
+'+'=13
+'++'=14
+'-'=15
+'--'=16
+'*'=17
+'/'=18
+'%'=19
+'&'=20
+'|'=21
+'&&'=22
+'||'=23
+'^'=24
+'!'=25
+'~'=26
+'?'=27
+':'=28
+';'=29
+','=30
+'='=31
+'*='=32
+'/='=33
+'%='=34
+'+='=35
+'-='=36
+'<<='=37
+'>>='=38
+'&='=39
+'^='=40
+'|='=41
+'=='=42
+'!='=43
+'->'=44
+'.'=45
+'...'=46
+'__has_attribute'=47
+'__has_cpp_attribute'=48
+'__has_c_attribute'=49
+'__has_builtin'=50
+'__has_include'=51
+'defined'=52
+'#'=58
+'@'=59
+'$'=60
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionBaseListener.java b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionBaseListener.java
new file mode 100644
index 000000000..c492439f7
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionBaseListener.java
@@ -0,0 +1,304 @@
+// Generated from /home/alex/programming/DiffDetective/src/main/resources/grammars/CExpression.g4 by ANTLR 4.13.1
+package org.variantsync.diffdetective.feature.antlr;
+
+import org.antlr.v4.runtime.ParserRuleContext;
+import org.antlr.v4.runtime.tree.ErrorNode;
+import org.antlr.v4.runtime.tree.TerminalNode;
+
+/**
+ * This class provides an empty implementation of {@link CExpressionListener},
+ * which can be extended to create a listener which only needs to handle a subset
+ * of the available methods.
+ */
+@SuppressWarnings("CheckReturnValue")
+public class CExpressionBaseListener implements CExpressionListener {
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterExpression(CExpressionParser.ExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitExpression(CExpressionParser.ExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterConditionalExpression(CExpressionParser.ConditionalExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitConditionalExpression(CExpressionParser.ConditionalExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterPrimaryExpression(CExpressionParser.PrimaryExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitPrimaryExpression(CExpressionParser.PrimaryExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterSpecialOperator(CExpressionParser.SpecialOperatorContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitSpecialOperator(CExpressionParser.SpecialOperatorContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterSpecialOperatorArgument(CExpressionParser.SpecialOperatorArgumentContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitSpecialOperatorArgument(CExpressionParser.SpecialOperatorArgumentContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterUnaryOperator(CExpressionParser.UnaryOperatorContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitUnaryOperator(CExpressionParser.UnaryOperatorContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterNamespaceExpression(CExpressionParser.NamespaceExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitNamespaceExpression(CExpressionParser.NamespaceExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterMultiplicativeExpression(CExpressionParser.MultiplicativeExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitMultiplicativeExpression(CExpressionParser.MultiplicativeExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterAdditiveExpression(CExpressionParser.AdditiveExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitAdditiveExpression(CExpressionParser.AdditiveExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterShiftExpression(CExpressionParser.ShiftExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitShiftExpression(CExpressionParser.ShiftExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterRelationalExpression(CExpressionParser.RelationalExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitRelationalExpression(CExpressionParser.RelationalExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterEqualityExpression(CExpressionParser.EqualityExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitEqualityExpression(CExpressionParser.EqualityExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterAndExpression(CExpressionParser.AndExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitAndExpression(CExpressionParser.AndExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterExclusiveOrExpression(CExpressionParser.ExclusiveOrExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitExclusiveOrExpression(CExpressionParser.ExclusiveOrExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterInclusiveOrExpression(CExpressionParser.InclusiveOrExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitInclusiveOrExpression(CExpressionParser.InclusiveOrExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterLogicalAndExpression(CExpressionParser.LogicalAndExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitLogicalAndExpression(CExpressionParser.LogicalAndExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterLogicalOrExpression(CExpressionParser.LogicalOrExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitLogicalOrExpression(CExpressionParser.LogicalOrExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterLogicalOperand(CExpressionParser.LogicalOperandContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitLogicalOperand(CExpressionParser.LogicalOperandContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterMacroExpression(CExpressionParser.MacroExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitMacroExpression(CExpressionParser.MacroExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterArgumentExpressionList(CExpressionParser.ArgumentExpressionListContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitArgumentExpressionList(CExpressionParser.ArgumentExpressionListContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterAssignmentExpression(CExpressionParser.AssignmentExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitAssignmentExpression(CExpressionParser.AssignmentExpressionContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterAssignmentOperator(CExpressionParser.AssignmentOperatorContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitAssignmentOperator(CExpressionParser.AssignmentOperatorContext ctx) { }
+
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void enterEveryRule(ParserRuleContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void exitEveryRule(ParserRuleContext ctx) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void visitTerminal(TerminalNode node) { }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation does nothing.
+ */
+ @Override public void visitErrorNode(ErrorNode node) { }
+}
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionBaseVisitor.java b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionBaseVisitor.java
new file mode 100644
index 000000000..1a9b1e62d
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionBaseVisitor.java
@@ -0,0 +1,169 @@
+// Generated from /home/alex/programming/DiffDetective/src/main/resources/grammars/CExpression.g4 by ANTLR 4.13.1
+package org.variantsync.diffdetective.feature.antlr;
+import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
+
+/**
+ * This class provides an empty implementation of {@link CExpressionVisitor},
+ * which can be extended to create a visitor which only needs to handle a subset
+ * of the available methods.
+ *
+ * @param The return type of the visit operation. Use {@link Void} for
+ * operations with no return type.
+ */
+@SuppressWarnings("CheckReturnValue")
+public class CExpressionBaseVisitor extends AbstractParseTreeVisitor implements CExpressionVisitor {
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitExpression(CExpressionParser.ExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitConditionalExpression(CExpressionParser.ConditionalExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitPrimaryExpression(CExpressionParser.PrimaryExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitSpecialOperator(CExpressionParser.SpecialOperatorContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitSpecialOperatorArgument(CExpressionParser.SpecialOperatorArgumentContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitUnaryOperator(CExpressionParser.UnaryOperatorContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitNamespaceExpression(CExpressionParser.NamespaceExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitMultiplicativeExpression(CExpressionParser.MultiplicativeExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitAdditiveExpression(CExpressionParser.AdditiveExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitShiftExpression(CExpressionParser.ShiftExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitRelationalExpression(CExpressionParser.RelationalExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitEqualityExpression(CExpressionParser.EqualityExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitAndExpression(CExpressionParser.AndExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitExclusiveOrExpression(CExpressionParser.ExclusiveOrExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitInclusiveOrExpression(CExpressionParser.InclusiveOrExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitLogicalAndExpression(CExpressionParser.LogicalAndExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitLogicalOrExpression(CExpressionParser.LogicalOrExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitLogicalOperand(CExpressionParser.LogicalOperandContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitMacroExpression(CExpressionParser.MacroExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitArgumentExpressionList(CExpressionParser.ArgumentExpressionListContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitAssignmentExpression(CExpressionParser.AssignmentExpressionContext ctx) { return visitChildren(ctx); }
+ /**
+ * {@inheritDoc}
+ *
+ * The default implementation returns the result of calling
+ * {@link #visitChildren} on {@code ctx}.
+ */
+ @Override public T visitAssignmentOperator(CExpressionParser.AssignmentOperatorContext ctx) { return visitChildren(ctx); }
+}
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionLexer.interp b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionLexer.interp
new file mode 100644
index 000000000..b1612cf3d
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionLexer.interp
@@ -0,0 +1,253 @@
+token literal names:
+null
+'('
+')'
+'['
+']'
+'{'
+'}'
+'<'
+'<='
+'>'
+'>='
+'<<'
+'>>'
+'+'
+'++'
+'-'
+'--'
+'*'
+'/'
+'%'
+'&'
+'|'
+'&&'
+'||'
+'^'
+'!'
+'~'
+'?'
+':'
+';'
+','
+'='
+'*='
+'/='
+'%='
+'+='
+'-='
+'<<='
+'>>='
+'&='
+'^='
+'|='
+'=='
+'!='
+'->'
+'.'
+'...'
+'__has_attribute'
+'__has_cpp_attribute'
+'__has_c_attribute'
+'__has_builtin'
+'__has_include'
+'defined'
+null
+null
+null
+null
+null
+'#'
+'@'
+'$'
+null
+null
+null
+null
+null
+null
+
+token symbolic names:
+null
+LeftParen
+RightParen
+LeftBracket
+RightBracket
+LeftBrace
+RightBrace
+Less
+LessEqual
+Greater
+GreaterEqual
+LeftShift
+RightShift
+Plus
+PlusPlus
+Minus
+MinusMinus
+Star
+Div
+Mod
+And
+Or
+AndAnd
+OrOr
+Caret
+Not
+Tilde
+Question
+Colon
+Semi
+Comma
+Assign
+StarAssign
+DivAssign
+ModAssign
+PlusAssign
+MinusAssign
+LeftShiftAssign
+RightShiftAssign
+AndAssign
+XorAssign
+OrAssign
+Equal
+NotEqual
+Arrow
+Dot
+Ellipsis
+HasAttribute
+HasCPPAttribute
+HasCAttribute
+HasBuiltin
+HasInclude
+Defined
+Identifier
+Constant
+DigitSequence
+StringLiteral
+PathLiteral
+NumberSign
+AtSign
+Dollar
+AsmBlock
+Whitespace
+Newline
+BlockComment
+OpenBlockComment
+LineComment
+
+rule names:
+LeftParen
+RightParen
+LeftBracket
+RightBracket
+LeftBrace
+RightBrace
+Less
+LessEqual
+Greater
+GreaterEqual
+LeftShift
+RightShift
+Plus
+PlusPlus
+Minus
+MinusMinus
+Star
+Div
+Mod
+And
+Or
+AndAnd
+OrOr
+Caret
+Not
+Tilde
+Question
+Colon
+Semi
+Comma
+Assign
+StarAssign
+DivAssign
+ModAssign
+PlusAssign
+MinusAssign
+LeftShiftAssign
+RightShiftAssign
+AndAssign
+XorAssign
+OrAssign
+Equal
+NotEqual
+Arrow
+Dot
+Ellipsis
+HasAttribute
+HasCPPAttribute
+HasCAttribute
+HasBuiltin
+HasInclude
+Defined
+Identifier
+IdentifierNondigit
+Nondigit
+Digit
+UniversalCharacterName
+HexQuad
+Constant
+IntegerConstant
+BinaryConstant
+DecimalConstant
+OctalConstant
+HexadecimalConstant
+HexadecimalPrefix
+NonzeroDigit
+OctalDigit
+HexadecimalDigit
+IntegerSuffix
+UnsignedSuffix
+LongSuffix
+LongLongSuffix
+FloatingConstant
+DecimalFloatingConstant
+HexadecimalFloatingConstant
+FractionalConstant
+ExponentPart
+Sign
+DigitSequence
+HexadecimalFractionalConstant
+BinaryExponentPart
+HexadecimalDigitSequence
+FloatingSuffix
+CharacterConstant
+CCharSequence
+CChar
+EscapeSequence
+SimpleEscapeSequence
+OctalEscapeSequence
+HexadecimalEscapeSequence
+StringLiteral
+PathLiteral
+EncodingPrefix
+SCharSequence
+SChar
+NumberSign
+AtSign
+Dollar
+AsmBlock
+Whitespace
+Newline
+BlockComment
+OpenBlockComment
+LineComment
+
+channel names:
+DEFAULT_TOKEN_CHANNEL
+HIDDEN
+
+mode names:
+DEFAULT_MODE
+
+atn:
+[4, 0, 66, 785, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 17, 1, 17, 1, 18, 1, 18, 1, 19, 1, 19, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 24, 1, 24, 1, 25, 1, 25, 1, 26, 1, 26, 1, 27, 1, 27, 1, 28, 1, 28, 1, 29, 1, 29, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 3, 52, 418, 8, 52, 1, 52, 1, 52, 4, 52, 422, 8, 52, 11, 52, 12, 52, 423, 1, 53, 1, 53, 3, 53, 428, 8, 53, 1, 54, 1, 54, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 3, 56, 444, 8, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 3, 58, 454, 8, 58, 1, 59, 1, 59, 3, 59, 458, 8, 59, 1, 59, 1, 59, 3, 59, 462, 8, 59, 1, 59, 1, 59, 3, 59, 466, 8, 59, 1, 59, 3, 59, 469, 8, 59, 1, 60, 1, 60, 1, 60, 4, 60, 474, 8, 60, 11, 60, 12, 60, 475, 1, 61, 1, 61, 5, 61, 480, 8, 61, 10, 61, 12, 61, 483, 9, 61, 1, 62, 1, 62, 5, 62, 487, 8, 62, 10, 62, 12, 62, 490, 9, 62, 1, 63, 1, 63, 4, 63, 494, 8, 63, 11, 63, 12, 63, 495, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 66, 1, 66, 1, 67, 1, 67, 1, 68, 1, 68, 3, 68, 509, 8, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 3, 68, 516, 8, 68, 1, 68, 1, 68, 3, 68, 520, 8, 68, 3, 68, 522, 8, 68, 1, 69, 1, 69, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 3, 71, 532, 8, 71, 1, 72, 1, 72, 3, 72, 536, 8, 72, 1, 73, 1, 73, 3, 73, 540, 8, 73, 1, 73, 3, 73, 543, 8, 73, 1, 73, 1, 73, 1, 73, 3, 73, 548, 8, 73, 3, 73, 550, 8, 73, 1, 74, 1, 74, 1, 74, 3, 74, 555, 8, 74, 1, 74, 1, 74, 3, 74, 559, 8, 74, 1, 75, 3, 75, 562, 8, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 3, 75, 569, 8, 75, 1, 76, 1, 76, 3, 76, 573, 8, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 78, 4, 78, 580, 8, 78, 11, 78, 12, 78, 581, 1, 79, 3, 79, 585, 8, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 3, 79, 592, 8, 79, 1, 80, 1, 80, 3, 80, 596, 8, 80, 1, 80, 1, 80, 1, 81, 4, 81, 601, 8, 81, 11, 81, 12, 81, 602, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 3, 83, 629, 8, 83, 1, 84, 4, 84, 632, 8, 84, 11, 84, 12, 84, 633, 1, 85, 1, 85, 3, 85, 638, 8, 85, 1, 86, 1, 86, 1, 86, 1, 86, 3, 86, 644, 8, 86, 1, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 3, 88, 652, 8, 88, 1, 88, 3, 88, 655, 8, 88, 1, 89, 1, 89, 1, 89, 1, 89, 4, 89, 661, 8, 89, 11, 89, 12, 89, 662, 1, 90, 3, 90, 666, 8, 90, 1, 90, 1, 90, 3, 90, 670, 8, 90, 1, 90, 1, 90, 1, 91, 1, 91, 4, 91, 676, 8, 91, 11, 91, 12, 91, 677, 1, 91, 1, 91, 1, 92, 1, 92, 1, 92, 3, 92, 685, 8, 92, 1, 93, 4, 93, 688, 8, 93, 11, 93, 12, 93, 689, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 3, 94, 699, 8, 94, 1, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 5, 98, 718, 8, 98, 10, 98, 12, 98, 721, 9, 98, 1, 98, 1, 98, 5, 98, 725, 8, 98, 10, 98, 12, 98, 728, 9, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 99, 4, 99, 735, 8, 99, 11, 99, 12, 99, 736, 1, 99, 1, 99, 1, 100, 1, 100, 3, 100, 743, 8, 100, 1, 100, 3, 100, 746, 8, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 101, 1, 101, 5, 101, 754, 8, 101, 10, 101, 12, 101, 757, 9, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 102, 1, 102, 1, 102, 1, 102, 5, 102, 768, 8, 102, 10, 102, 12, 102, 771, 9, 102, 1, 102, 1, 102, 1, 103, 1, 103, 1, 103, 1, 103, 5, 103, 779, 8, 103, 10, 103, 12, 103, 782, 9, 103, 1, 103, 1, 103, 1, 755, 0, 104, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 0, 109, 0, 111, 0, 113, 0, 115, 0, 117, 54, 119, 0, 121, 0, 123, 0, 125, 0, 127, 0, 129, 0, 131, 0, 133, 0, 135, 0, 137, 0, 139, 0, 141, 0, 143, 0, 145, 0, 147, 0, 149, 0, 151, 0, 153, 0, 155, 0, 157, 55, 159, 0, 161, 0, 163, 0, 165, 0, 167, 0, 169, 0, 171, 0, 173, 0, 175, 0, 177, 0, 179, 0, 181, 56, 183, 57, 185, 0, 187, 0, 189, 0, 191, 58, 193, 59, 195, 60, 197, 61, 199, 62, 201, 63, 203, 64, 205, 65, 207, 66, 1, 0, 24, 3, 0, 65, 90, 95, 95, 97, 122, 1, 0, 48, 57, 2, 0, 66, 66, 98, 98, 1, 0, 48, 49, 2, 0, 88, 88, 120, 120, 1, 0, 49, 57, 1, 0, 48, 55, 3, 0, 48, 57, 65, 70, 97, 102, 2, 0, 85, 85, 117, 117, 2, 0, 76, 76, 108, 108, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 2, 0, 80, 80, 112, 112, 4, 0, 70, 70, 76, 76, 102, 102, 108, 108, 4, 0, 10, 10, 13, 13, 39, 39, 92, 92, 10, 0, 34, 34, 39, 39, 63, 63, 92, 92, 97, 98, 102, 102, 110, 110, 114, 114, 116, 116, 118, 118, 4, 0, 9, 9, 32, 32, 60, 60, 62, 62, 3, 0, 76, 76, 85, 85, 117, 117, 4, 0, 10, 10, 13, 13, 34, 34, 92, 92, 1, 0, 123, 123, 1, 0, 125, 125, 2, 0, 9, 9, 32, 32, 2, 0, 42, 42, 47, 47, 2, 0, 10, 10, 13, 13, 812, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, 157, 1, 0, 0, 0, 0, 181, 1, 0, 0, 0, 0, 183, 1, 0, 0, 0, 0, 191, 1, 0, 0, 0, 0, 193, 1, 0, 0, 0, 0, 195, 1, 0, 0, 0, 0, 197, 1, 0, 0, 0, 0, 199, 1, 0, 0, 0, 0, 201, 1, 0, 0, 0, 0, 203, 1, 0, 0, 0, 0, 205, 1, 0, 0, 0, 0, 207, 1, 0, 0, 0, 1, 209, 1, 0, 0, 0, 3, 211, 1, 0, 0, 0, 5, 213, 1, 0, 0, 0, 7, 215, 1, 0, 0, 0, 9, 217, 1, 0, 0, 0, 11, 219, 1, 0, 0, 0, 13, 221, 1, 0, 0, 0, 15, 223, 1, 0, 0, 0, 17, 226, 1, 0, 0, 0, 19, 228, 1, 0, 0, 0, 21, 231, 1, 0, 0, 0, 23, 234, 1, 0, 0, 0, 25, 237, 1, 0, 0, 0, 27, 239, 1, 0, 0, 0, 29, 242, 1, 0, 0, 0, 31, 244, 1, 0, 0, 0, 33, 247, 1, 0, 0, 0, 35, 249, 1, 0, 0, 0, 37, 251, 1, 0, 0, 0, 39, 253, 1, 0, 0, 0, 41, 255, 1, 0, 0, 0, 43, 257, 1, 0, 0, 0, 45, 260, 1, 0, 0, 0, 47, 263, 1, 0, 0, 0, 49, 265, 1, 0, 0, 0, 51, 267, 1, 0, 0, 0, 53, 269, 1, 0, 0, 0, 55, 271, 1, 0, 0, 0, 57, 273, 1, 0, 0, 0, 59, 275, 1, 0, 0, 0, 61, 277, 1, 0, 0, 0, 63, 279, 1, 0, 0, 0, 65, 282, 1, 0, 0, 0, 67, 285, 1, 0, 0, 0, 69, 288, 1, 0, 0, 0, 71, 291, 1, 0, 0, 0, 73, 294, 1, 0, 0, 0, 75, 298, 1, 0, 0, 0, 77, 302, 1, 0, 0, 0, 79, 305, 1, 0, 0, 0, 81, 308, 1, 0, 0, 0, 83, 311, 1, 0, 0, 0, 85, 314, 1, 0, 0, 0, 87, 317, 1, 0, 0, 0, 89, 320, 1, 0, 0, 0, 91, 322, 1, 0, 0, 0, 93, 326, 1, 0, 0, 0, 95, 342, 1, 0, 0, 0, 97, 362, 1, 0, 0, 0, 99, 380, 1, 0, 0, 0, 101, 394, 1, 0, 0, 0, 103, 408, 1, 0, 0, 0, 105, 417, 1, 0, 0, 0, 107, 427, 1, 0, 0, 0, 109, 429, 1, 0, 0, 0, 111, 431, 1, 0, 0, 0, 113, 443, 1, 0, 0, 0, 115, 445, 1, 0, 0, 0, 117, 453, 1, 0, 0, 0, 119, 468, 1, 0, 0, 0, 121, 470, 1, 0, 0, 0, 123, 477, 1, 0, 0, 0, 125, 484, 1, 0, 0, 0, 127, 491, 1, 0, 0, 0, 129, 497, 1, 0, 0, 0, 131, 500, 1, 0, 0, 0, 133, 502, 1, 0, 0, 0, 135, 504, 1, 0, 0, 0, 137, 521, 1, 0, 0, 0, 139, 523, 1, 0, 0, 0, 141, 525, 1, 0, 0, 0, 143, 531, 1, 0, 0, 0, 145, 535, 1, 0, 0, 0, 147, 549, 1, 0, 0, 0, 149, 551, 1, 0, 0, 0, 151, 568, 1, 0, 0, 0, 153, 570, 1, 0, 0, 0, 155, 576, 1, 0, 0, 0, 157, 579, 1, 0, 0, 0, 159, 591, 1, 0, 0, 0, 161, 593, 1, 0, 0, 0, 163, 600, 1, 0, 0, 0, 165, 604, 1, 0, 0, 0, 167, 628, 1, 0, 0, 0, 169, 631, 1, 0, 0, 0, 171, 637, 1, 0, 0, 0, 173, 643, 1, 0, 0, 0, 175, 645, 1, 0, 0, 0, 177, 648, 1, 0, 0, 0, 179, 656, 1, 0, 0, 0, 181, 665, 1, 0, 0, 0, 183, 673, 1, 0, 0, 0, 185, 684, 1, 0, 0, 0, 187, 687, 1, 0, 0, 0, 189, 698, 1, 0, 0, 0, 191, 700, 1, 0, 0, 0, 193, 704, 1, 0, 0, 0, 195, 708, 1, 0, 0, 0, 197, 712, 1, 0, 0, 0, 199, 734, 1, 0, 0, 0, 201, 745, 1, 0, 0, 0, 203, 749, 1, 0, 0, 0, 205, 763, 1, 0, 0, 0, 207, 774, 1, 0, 0, 0, 209, 210, 5, 40, 0, 0, 210, 2, 1, 0, 0, 0, 211, 212, 5, 41, 0, 0, 212, 4, 1, 0, 0, 0, 213, 214, 5, 91, 0, 0, 214, 6, 1, 0, 0, 0, 215, 216, 5, 93, 0, 0, 216, 8, 1, 0, 0, 0, 217, 218, 5, 123, 0, 0, 218, 10, 1, 0, 0, 0, 219, 220, 5, 125, 0, 0, 220, 12, 1, 0, 0, 0, 221, 222, 5, 60, 0, 0, 222, 14, 1, 0, 0, 0, 223, 224, 5, 60, 0, 0, 224, 225, 5, 61, 0, 0, 225, 16, 1, 0, 0, 0, 226, 227, 5, 62, 0, 0, 227, 18, 1, 0, 0, 0, 228, 229, 5, 62, 0, 0, 229, 230, 5, 61, 0, 0, 230, 20, 1, 0, 0, 0, 231, 232, 5, 60, 0, 0, 232, 233, 5, 60, 0, 0, 233, 22, 1, 0, 0, 0, 234, 235, 5, 62, 0, 0, 235, 236, 5, 62, 0, 0, 236, 24, 1, 0, 0, 0, 237, 238, 5, 43, 0, 0, 238, 26, 1, 0, 0, 0, 239, 240, 5, 43, 0, 0, 240, 241, 5, 43, 0, 0, 241, 28, 1, 0, 0, 0, 242, 243, 5, 45, 0, 0, 243, 30, 1, 0, 0, 0, 244, 245, 5, 45, 0, 0, 245, 246, 5, 45, 0, 0, 246, 32, 1, 0, 0, 0, 247, 248, 5, 42, 0, 0, 248, 34, 1, 0, 0, 0, 249, 250, 5, 47, 0, 0, 250, 36, 1, 0, 0, 0, 251, 252, 5, 37, 0, 0, 252, 38, 1, 0, 0, 0, 253, 254, 5, 38, 0, 0, 254, 40, 1, 0, 0, 0, 255, 256, 5, 124, 0, 0, 256, 42, 1, 0, 0, 0, 257, 258, 5, 38, 0, 0, 258, 259, 5, 38, 0, 0, 259, 44, 1, 0, 0, 0, 260, 261, 5, 124, 0, 0, 261, 262, 5, 124, 0, 0, 262, 46, 1, 0, 0, 0, 263, 264, 5, 94, 0, 0, 264, 48, 1, 0, 0, 0, 265, 266, 5, 33, 0, 0, 266, 50, 1, 0, 0, 0, 267, 268, 5, 126, 0, 0, 268, 52, 1, 0, 0, 0, 269, 270, 5, 63, 0, 0, 270, 54, 1, 0, 0, 0, 271, 272, 5, 58, 0, 0, 272, 56, 1, 0, 0, 0, 273, 274, 5, 59, 0, 0, 274, 58, 1, 0, 0, 0, 275, 276, 5, 44, 0, 0, 276, 60, 1, 0, 0, 0, 277, 278, 5, 61, 0, 0, 278, 62, 1, 0, 0, 0, 279, 280, 5, 42, 0, 0, 280, 281, 5, 61, 0, 0, 281, 64, 1, 0, 0, 0, 282, 283, 5, 47, 0, 0, 283, 284, 5, 61, 0, 0, 284, 66, 1, 0, 0, 0, 285, 286, 5, 37, 0, 0, 286, 287, 5, 61, 0, 0, 287, 68, 1, 0, 0, 0, 288, 289, 5, 43, 0, 0, 289, 290, 5, 61, 0, 0, 290, 70, 1, 0, 0, 0, 291, 292, 5, 45, 0, 0, 292, 293, 5, 61, 0, 0, 293, 72, 1, 0, 0, 0, 294, 295, 5, 60, 0, 0, 295, 296, 5, 60, 0, 0, 296, 297, 5, 61, 0, 0, 297, 74, 1, 0, 0, 0, 298, 299, 5, 62, 0, 0, 299, 300, 5, 62, 0, 0, 300, 301, 5, 61, 0, 0, 301, 76, 1, 0, 0, 0, 302, 303, 5, 38, 0, 0, 303, 304, 5, 61, 0, 0, 304, 78, 1, 0, 0, 0, 305, 306, 5, 94, 0, 0, 306, 307, 5, 61, 0, 0, 307, 80, 1, 0, 0, 0, 308, 309, 5, 124, 0, 0, 309, 310, 5, 61, 0, 0, 310, 82, 1, 0, 0, 0, 311, 312, 5, 61, 0, 0, 312, 313, 5, 61, 0, 0, 313, 84, 1, 0, 0, 0, 314, 315, 5, 33, 0, 0, 315, 316, 5, 61, 0, 0, 316, 86, 1, 0, 0, 0, 317, 318, 5, 45, 0, 0, 318, 319, 5, 62, 0, 0, 319, 88, 1, 0, 0, 0, 320, 321, 5, 46, 0, 0, 321, 90, 1, 0, 0, 0, 322, 323, 5, 46, 0, 0, 323, 324, 5, 46, 0, 0, 324, 325, 5, 46, 0, 0, 325, 92, 1, 0, 0, 0, 326, 327, 5, 95, 0, 0, 327, 328, 5, 95, 0, 0, 328, 329, 5, 104, 0, 0, 329, 330, 5, 97, 0, 0, 330, 331, 5, 115, 0, 0, 331, 332, 5, 95, 0, 0, 332, 333, 5, 97, 0, 0, 333, 334, 5, 116, 0, 0, 334, 335, 5, 116, 0, 0, 335, 336, 5, 114, 0, 0, 336, 337, 5, 105, 0, 0, 337, 338, 5, 98, 0, 0, 338, 339, 5, 117, 0, 0, 339, 340, 5, 116, 0, 0, 340, 341, 5, 101, 0, 0, 341, 94, 1, 0, 0, 0, 342, 343, 5, 95, 0, 0, 343, 344, 5, 95, 0, 0, 344, 345, 5, 104, 0, 0, 345, 346, 5, 97, 0, 0, 346, 347, 5, 115, 0, 0, 347, 348, 5, 95, 0, 0, 348, 349, 5, 99, 0, 0, 349, 350, 5, 112, 0, 0, 350, 351, 5, 112, 0, 0, 351, 352, 5, 95, 0, 0, 352, 353, 5, 97, 0, 0, 353, 354, 5, 116, 0, 0, 354, 355, 5, 116, 0, 0, 355, 356, 5, 114, 0, 0, 356, 357, 5, 105, 0, 0, 357, 358, 5, 98, 0, 0, 358, 359, 5, 117, 0, 0, 359, 360, 5, 116, 0, 0, 360, 361, 5, 101, 0, 0, 361, 96, 1, 0, 0, 0, 362, 363, 5, 95, 0, 0, 363, 364, 5, 95, 0, 0, 364, 365, 5, 104, 0, 0, 365, 366, 5, 97, 0, 0, 366, 367, 5, 115, 0, 0, 367, 368, 5, 95, 0, 0, 368, 369, 5, 99, 0, 0, 369, 370, 5, 95, 0, 0, 370, 371, 5, 97, 0, 0, 371, 372, 5, 116, 0, 0, 372, 373, 5, 116, 0, 0, 373, 374, 5, 114, 0, 0, 374, 375, 5, 105, 0, 0, 375, 376, 5, 98, 0, 0, 376, 377, 5, 117, 0, 0, 377, 378, 5, 116, 0, 0, 378, 379, 5, 101, 0, 0, 379, 98, 1, 0, 0, 0, 380, 381, 5, 95, 0, 0, 381, 382, 5, 95, 0, 0, 382, 383, 5, 104, 0, 0, 383, 384, 5, 97, 0, 0, 384, 385, 5, 115, 0, 0, 385, 386, 5, 95, 0, 0, 386, 387, 5, 98, 0, 0, 387, 388, 5, 117, 0, 0, 388, 389, 5, 105, 0, 0, 389, 390, 5, 108, 0, 0, 390, 391, 5, 116, 0, 0, 391, 392, 5, 105, 0, 0, 392, 393, 5, 110, 0, 0, 393, 100, 1, 0, 0, 0, 394, 395, 5, 95, 0, 0, 395, 396, 5, 95, 0, 0, 396, 397, 5, 104, 0, 0, 397, 398, 5, 97, 0, 0, 398, 399, 5, 115, 0, 0, 399, 400, 5, 95, 0, 0, 400, 401, 5, 105, 0, 0, 401, 402, 5, 110, 0, 0, 402, 403, 5, 99, 0, 0, 403, 404, 5, 108, 0, 0, 404, 405, 5, 117, 0, 0, 405, 406, 5, 100, 0, 0, 406, 407, 5, 101, 0, 0, 407, 102, 1, 0, 0, 0, 408, 409, 5, 100, 0, 0, 409, 410, 5, 101, 0, 0, 410, 411, 5, 102, 0, 0, 411, 412, 5, 105, 0, 0, 412, 413, 5, 110, 0, 0, 413, 414, 5, 101, 0, 0, 414, 415, 5, 100, 0, 0, 415, 104, 1, 0, 0, 0, 416, 418, 5, 92, 0, 0, 417, 416, 1, 0, 0, 0, 417, 418, 1, 0, 0, 0, 418, 421, 1, 0, 0, 0, 419, 422, 3, 107, 53, 0, 420, 422, 3, 111, 55, 0, 421, 419, 1, 0, 0, 0, 421, 420, 1, 0, 0, 0, 422, 423, 1, 0, 0, 0, 423, 421, 1, 0, 0, 0, 423, 424, 1, 0, 0, 0, 424, 106, 1, 0, 0, 0, 425, 428, 3, 109, 54, 0, 426, 428, 3, 113, 56, 0, 427, 425, 1, 0, 0, 0, 427, 426, 1, 0, 0, 0, 428, 108, 1, 0, 0, 0, 429, 430, 7, 0, 0, 0, 430, 110, 1, 0, 0, 0, 431, 432, 7, 1, 0, 0, 432, 112, 1, 0, 0, 0, 433, 434, 5, 92, 0, 0, 434, 435, 5, 117, 0, 0, 435, 436, 1, 0, 0, 0, 436, 444, 3, 115, 57, 0, 437, 438, 5, 92, 0, 0, 438, 439, 5, 85, 0, 0, 439, 440, 1, 0, 0, 0, 440, 441, 3, 115, 57, 0, 441, 442, 3, 115, 57, 0, 442, 444, 1, 0, 0, 0, 443, 433, 1, 0, 0, 0, 443, 437, 1, 0, 0, 0, 444, 114, 1, 0, 0, 0, 445, 446, 3, 135, 67, 0, 446, 447, 3, 135, 67, 0, 447, 448, 3, 135, 67, 0, 448, 449, 3, 135, 67, 0, 449, 116, 1, 0, 0, 0, 450, 454, 3, 119, 59, 0, 451, 454, 3, 145, 72, 0, 452, 454, 3, 167, 83, 0, 453, 450, 1, 0, 0, 0, 453, 451, 1, 0, 0, 0, 453, 452, 1, 0, 0, 0, 454, 118, 1, 0, 0, 0, 455, 457, 3, 123, 61, 0, 456, 458, 3, 137, 68, 0, 457, 456, 1, 0, 0, 0, 457, 458, 1, 0, 0, 0, 458, 469, 1, 0, 0, 0, 459, 461, 3, 125, 62, 0, 460, 462, 3, 137, 68, 0, 461, 460, 1, 0, 0, 0, 461, 462, 1, 0, 0, 0, 462, 469, 1, 0, 0, 0, 463, 465, 3, 127, 63, 0, 464, 466, 3, 137, 68, 0, 465, 464, 1, 0, 0, 0, 465, 466, 1, 0, 0, 0, 466, 469, 1, 0, 0, 0, 467, 469, 3, 121, 60, 0, 468, 455, 1, 0, 0, 0, 468, 459, 1, 0, 0, 0, 468, 463, 1, 0, 0, 0, 468, 467, 1, 0, 0, 0, 469, 120, 1, 0, 0, 0, 470, 471, 5, 48, 0, 0, 471, 473, 7, 2, 0, 0, 472, 474, 7, 3, 0, 0, 473, 472, 1, 0, 0, 0, 474, 475, 1, 0, 0, 0, 475, 473, 1, 0, 0, 0, 475, 476, 1, 0, 0, 0, 476, 122, 1, 0, 0, 0, 477, 481, 3, 131, 65, 0, 478, 480, 3, 111, 55, 0, 479, 478, 1, 0, 0, 0, 480, 483, 1, 0, 0, 0, 481, 479, 1, 0, 0, 0, 481, 482, 1, 0, 0, 0, 482, 124, 1, 0, 0, 0, 483, 481, 1, 0, 0, 0, 484, 488, 5, 48, 0, 0, 485, 487, 3, 133, 66, 0, 486, 485, 1, 0, 0, 0, 487, 490, 1, 0, 0, 0, 488, 486, 1, 0, 0, 0, 488, 489, 1, 0, 0, 0, 489, 126, 1, 0, 0, 0, 490, 488, 1, 0, 0, 0, 491, 493, 3, 129, 64, 0, 492, 494, 3, 135, 67, 0, 493, 492, 1, 0, 0, 0, 494, 495, 1, 0, 0, 0, 495, 493, 1, 0, 0, 0, 495, 496, 1, 0, 0, 0, 496, 128, 1, 0, 0, 0, 497, 498, 5, 48, 0, 0, 498, 499, 7, 4, 0, 0, 499, 130, 1, 0, 0, 0, 500, 501, 7, 5, 0, 0, 501, 132, 1, 0, 0, 0, 502, 503, 7, 6, 0, 0, 503, 134, 1, 0, 0, 0, 504, 505, 7, 7, 0, 0, 505, 136, 1, 0, 0, 0, 506, 508, 3, 139, 69, 0, 507, 509, 3, 141, 70, 0, 508, 507, 1, 0, 0, 0, 508, 509, 1, 0, 0, 0, 509, 522, 1, 0, 0, 0, 510, 511, 3, 139, 69, 0, 511, 512, 3, 143, 71, 0, 512, 522, 1, 0, 0, 0, 513, 515, 3, 141, 70, 0, 514, 516, 3, 139, 69, 0, 515, 514, 1, 0, 0, 0, 515, 516, 1, 0, 0, 0, 516, 522, 1, 0, 0, 0, 517, 519, 3, 143, 71, 0, 518, 520, 3, 139, 69, 0, 519, 518, 1, 0, 0, 0, 519, 520, 1, 0, 0, 0, 520, 522, 1, 0, 0, 0, 521, 506, 1, 0, 0, 0, 521, 510, 1, 0, 0, 0, 521, 513, 1, 0, 0, 0, 521, 517, 1, 0, 0, 0, 522, 138, 1, 0, 0, 0, 523, 524, 7, 8, 0, 0, 524, 140, 1, 0, 0, 0, 525, 526, 7, 9, 0, 0, 526, 142, 1, 0, 0, 0, 527, 528, 5, 108, 0, 0, 528, 532, 5, 108, 0, 0, 529, 530, 5, 76, 0, 0, 530, 532, 5, 76, 0, 0, 531, 527, 1, 0, 0, 0, 531, 529, 1, 0, 0, 0, 532, 144, 1, 0, 0, 0, 533, 536, 3, 147, 73, 0, 534, 536, 3, 149, 74, 0, 535, 533, 1, 0, 0, 0, 535, 534, 1, 0, 0, 0, 536, 146, 1, 0, 0, 0, 537, 539, 3, 151, 75, 0, 538, 540, 3, 153, 76, 0, 539, 538, 1, 0, 0, 0, 539, 540, 1, 0, 0, 0, 540, 542, 1, 0, 0, 0, 541, 543, 3, 165, 82, 0, 542, 541, 1, 0, 0, 0, 542, 543, 1, 0, 0, 0, 543, 550, 1, 0, 0, 0, 544, 545, 3, 157, 78, 0, 545, 547, 3, 153, 76, 0, 546, 548, 3, 165, 82, 0, 547, 546, 1, 0, 0, 0, 547, 548, 1, 0, 0, 0, 548, 550, 1, 0, 0, 0, 549, 537, 1, 0, 0, 0, 549, 544, 1, 0, 0, 0, 550, 148, 1, 0, 0, 0, 551, 554, 3, 129, 64, 0, 552, 555, 3, 159, 79, 0, 553, 555, 3, 163, 81, 0, 554, 552, 1, 0, 0, 0, 554, 553, 1, 0, 0, 0, 555, 556, 1, 0, 0, 0, 556, 558, 3, 161, 80, 0, 557, 559, 3, 165, 82, 0, 558, 557, 1, 0, 0, 0, 558, 559, 1, 0, 0, 0, 559, 150, 1, 0, 0, 0, 560, 562, 3, 157, 78, 0, 561, 560, 1, 0, 0, 0, 561, 562, 1, 0, 0, 0, 562, 563, 1, 0, 0, 0, 563, 564, 5, 46, 0, 0, 564, 569, 3, 157, 78, 0, 565, 566, 3, 157, 78, 0, 566, 567, 5, 46, 0, 0, 567, 569, 1, 0, 0, 0, 568, 561, 1, 0, 0, 0, 568, 565, 1, 0, 0, 0, 569, 152, 1, 0, 0, 0, 570, 572, 7, 10, 0, 0, 571, 573, 3, 155, 77, 0, 572, 571, 1, 0, 0, 0, 572, 573, 1, 0, 0, 0, 573, 574, 1, 0, 0, 0, 574, 575, 3, 157, 78, 0, 575, 154, 1, 0, 0, 0, 576, 577, 7, 11, 0, 0, 577, 156, 1, 0, 0, 0, 578, 580, 3, 111, 55, 0, 579, 578, 1, 0, 0, 0, 580, 581, 1, 0, 0, 0, 581, 579, 1, 0, 0, 0, 581, 582, 1, 0, 0, 0, 582, 158, 1, 0, 0, 0, 583, 585, 3, 163, 81, 0, 584, 583, 1, 0, 0, 0, 584, 585, 1, 0, 0, 0, 585, 586, 1, 0, 0, 0, 586, 587, 5, 46, 0, 0, 587, 592, 3, 163, 81, 0, 588, 589, 3, 163, 81, 0, 589, 590, 5, 46, 0, 0, 590, 592, 1, 0, 0, 0, 591, 584, 1, 0, 0, 0, 591, 588, 1, 0, 0, 0, 592, 160, 1, 0, 0, 0, 593, 595, 7, 12, 0, 0, 594, 596, 3, 155, 77, 0, 595, 594, 1, 0, 0, 0, 595, 596, 1, 0, 0, 0, 596, 597, 1, 0, 0, 0, 597, 598, 3, 157, 78, 0, 598, 162, 1, 0, 0, 0, 599, 601, 3, 135, 67, 0, 600, 599, 1, 0, 0, 0, 601, 602, 1, 0, 0, 0, 602, 600, 1, 0, 0, 0, 602, 603, 1, 0, 0, 0, 603, 164, 1, 0, 0, 0, 604, 605, 7, 13, 0, 0, 605, 166, 1, 0, 0, 0, 606, 607, 5, 39, 0, 0, 607, 608, 3, 169, 84, 0, 608, 609, 5, 39, 0, 0, 609, 629, 1, 0, 0, 0, 610, 611, 5, 76, 0, 0, 611, 612, 5, 39, 0, 0, 612, 613, 1, 0, 0, 0, 613, 614, 3, 169, 84, 0, 614, 615, 5, 39, 0, 0, 615, 629, 1, 0, 0, 0, 616, 617, 5, 117, 0, 0, 617, 618, 5, 39, 0, 0, 618, 619, 1, 0, 0, 0, 619, 620, 3, 169, 84, 0, 620, 621, 5, 39, 0, 0, 621, 629, 1, 0, 0, 0, 622, 623, 5, 85, 0, 0, 623, 624, 5, 39, 0, 0, 624, 625, 1, 0, 0, 0, 625, 626, 3, 169, 84, 0, 626, 627, 5, 39, 0, 0, 627, 629, 1, 0, 0, 0, 628, 606, 1, 0, 0, 0, 628, 610, 1, 0, 0, 0, 628, 616, 1, 0, 0, 0, 628, 622, 1, 0, 0, 0, 629, 168, 1, 0, 0, 0, 630, 632, 3, 171, 85, 0, 631, 630, 1, 0, 0, 0, 632, 633, 1, 0, 0, 0, 633, 631, 1, 0, 0, 0, 633, 634, 1, 0, 0, 0, 634, 170, 1, 0, 0, 0, 635, 638, 8, 14, 0, 0, 636, 638, 3, 173, 86, 0, 637, 635, 1, 0, 0, 0, 637, 636, 1, 0, 0, 0, 638, 172, 1, 0, 0, 0, 639, 644, 3, 175, 87, 0, 640, 644, 3, 177, 88, 0, 641, 644, 3, 179, 89, 0, 642, 644, 3, 113, 56, 0, 643, 639, 1, 0, 0, 0, 643, 640, 1, 0, 0, 0, 643, 641, 1, 0, 0, 0, 643, 642, 1, 0, 0, 0, 644, 174, 1, 0, 0, 0, 645, 646, 5, 92, 0, 0, 646, 647, 7, 15, 0, 0, 647, 176, 1, 0, 0, 0, 648, 649, 5, 92, 0, 0, 649, 651, 3, 133, 66, 0, 650, 652, 3, 133, 66, 0, 651, 650, 1, 0, 0, 0, 651, 652, 1, 0, 0, 0, 652, 654, 1, 0, 0, 0, 653, 655, 3, 133, 66, 0, 654, 653, 1, 0, 0, 0, 654, 655, 1, 0, 0, 0, 655, 178, 1, 0, 0, 0, 656, 657, 5, 92, 0, 0, 657, 658, 5, 120, 0, 0, 658, 660, 1, 0, 0, 0, 659, 661, 3, 135, 67, 0, 660, 659, 1, 0, 0, 0, 661, 662, 1, 0, 0, 0, 662, 660, 1, 0, 0, 0, 662, 663, 1, 0, 0, 0, 663, 180, 1, 0, 0, 0, 664, 666, 3, 185, 92, 0, 665, 664, 1, 0, 0, 0, 665, 666, 1, 0, 0, 0, 666, 667, 1, 0, 0, 0, 667, 669, 5, 34, 0, 0, 668, 670, 3, 187, 93, 0, 669, 668, 1, 0, 0, 0, 669, 670, 1, 0, 0, 0, 670, 671, 1, 0, 0, 0, 671, 672, 5, 34, 0, 0, 672, 182, 1, 0, 0, 0, 673, 675, 5, 60, 0, 0, 674, 676, 8, 16, 0, 0, 675, 674, 1, 0, 0, 0, 676, 677, 1, 0, 0, 0, 677, 675, 1, 0, 0, 0, 677, 678, 1, 0, 0, 0, 678, 679, 1, 0, 0, 0, 679, 680, 5, 62, 0, 0, 680, 184, 1, 0, 0, 0, 681, 682, 5, 117, 0, 0, 682, 685, 5, 56, 0, 0, 683, 685, 7, 17, 0, 0, 684, 681, 1, 0, 0, 0, 684, 683, 1, 0, 0, 0, 685, 186, 1, 0, 0, 0, 686, 688, 3, 189, 94, 0, 687, 686, 1, 0, 0, 0, 688, 689, 1, 0, 0, 0, 689, 687, 1, 0, 0, 0, 689, 690, 1, 0, 0, 0, 690, 188, 1, 0, 0, 0, 691, 699, 8, 18, 0, 0, 692, 699, 3, 173, 86, 0, 693, 694, 5, 92, 0, 0, 694, 699, 5, 10, 0, 0, 695, 696, 5, 92, 0, 0, 696, 697, 5, 13, 0, 0, 697, 699, 5, 10, 0, 0, 698, 691, 1, 0, 0, 0, 698, 692, 1, 0, 0, 0, 698, 693, 1, 0, 0, 0, 698, 695, 1, 0, 0, 0, 699, 190, 1, 0, 0, 0, 700, 701, 5, 35, 0, 0, 701, 702, 1, 0, 0, 0, 702, 703, 6, 95, 0, 0, 703, 192, 1, 0, 0, 0, 704, 705, 5, 64, 0, 0, 705, 706, 1, 0, 0, 0, 706, 707, 6, 96, 0, 0, 707, 194, 1, 0, 0, 0, 708, 709, 5, 36, 0, 0, 709, 710, 1, 0, 0, 0, 710, 711, 6, 97, 0, 0, 711, 196, 1, 0, 0, 0, 712, 713, 5, 97, 0, 0, 713, 714, 5, 115, 0, 0, 714, 715, 5, 109, 0, 0, 715, 719, 1, 0, 0, 0, 716, 718, 8, 19, 0, 0, 717, 716, 1, 0, 0, 0, 718, 721, 1, 0, 0, 0, 719, 717, 1, 0, 0, 0, 719, 720, 1, 0, 0, 0, 720, 722, 1, 0, 0, 0, 721, 719, 1, 0, 0, 0, 722, 726, 5, 123, 0, 0, 723, 725, 8, 20, 0, 0, 724, 723, 1, 0, 0, 0, 725, 728, 1, 0, 0, 0, 726, 724, 1, 0, 0, 0, 726, 727, 1, 0, 0, 0, 727, 729, 1, 0, 0, 0, 728, 726, 1, 0, 0, 0, 729, 730, 5, 125, 0, 0, 730, 731, 1, 0, 0, 0, 731, 732, 6, 98, 0, 0, 732, 198, 1, 0, 0, 0, 733, 735, 7, 21, 0, 0, 734, 733, 1, 0, 0, 0, 735, 736, 1, 0, 0, 0, 736, 734, 1, 0, 0, 0, 736, 737, 1, 0, 0, 0, 737, 738, 1, 0, 0, 0, 738, 739, 6, 99, 0, 0, 739, 200, 1, 0, 0, 0, 740, 742, 5, 13, 0, 0, 741, 743, 5, 10, 0, 0, 742, 741, 1, 0, 0, 0, 742, 743, 1, 0, 0, 0, 743, 746, 1, 0, 0, 0, 744, 746, 5, 10, 0, 0, 745, 740, 1, 0, 0, 0, 745, 744, 1, 0, 0, 0, 746, 747, 1, 0, 0, 0, 747, 748, 6, 100, 0, 0, 748, 202, 1, 0, 0, 0, 749, 750, 5, 47, 0, 0, 750, 751, 5, 42, 0, 0, 751, 755, 1, 0, 0, 0, 752, 754, 9, 0, 0, 0, 753, 752, 1, 0, 0, 0, 754, 757, 1, 0, 0, 0, 755, 756, 1, 0, 0, 0, 755, 753, 1, 0, 0, 0, 756, 758, 1, 0, 0, 0, 757, 755, 1, 0, 0, 0, 758, 759, 5, 42, 0, 0, 759, 760, 5, 47, 0, 0, 760, 761, 1, 0, 0, 0, 761, 762, 6, 101, 0, 0, 762, 204, 1, 0, 0, 0, 763, 764, 5, 47, 0, 0, 764, 765, 5, 42, 0, 0, 765, 769, 1, 0, 0, 0, 766, 768, 8, 22, 0, 0, 767, 766, 1, 0, 0, 0, 768, 771, 1, 0, 0, 0, 769, 767, 1, 0, 0, 0, 769, 770, 1, 0, 0, 0, 770, 772, 1, 0, 0, 0, 771, 769, 1, 0, 0, 0, 772, 773, 6, 102, 0, 0, 773, 206, 1, 0, 0, 0, 774, 775, 5, 47, 0, 0, 775, 776, 5, 47, 0, 0, 776, 780, 1, 0, 0, 0, 777, 779, 8, 23, 0, 0, 778, 777, 1, 0, 0, 0, 779, 782, 1, 0, 0, 0, 780, 778, 1, 0, 0, 0, 780, 781, 1, 0, 0, 0, 781, 783, 1, 0, 0, 0, 782, 780, 1, 0, 0, 0, 783, 784, 6, 103, 0, 0, 784, 208, 1, 0, 0, 0, 56, 0, 417, 421, 423, 427, 443, 453, 457, 461, 465, 468, 475, 481, 488, 495, 508, 515, 519, 521, 531, 535, 539, 542, 547, 549, 554, 558, 561, 568, 572, 581, 584, 591, 595, 602, 628, 633, 637, 643, 651, 654, 662, 665, 669, 677, 684, 689, 698, 719, 726, 736, 742, 745, 755, 769, 780, 1, 0, 1, 0]
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionLexer.java b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionLexer.java
new file mode 100644
index 000000000..ff6281f7c
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionLexer.java
@@ -0,0 +1,643 @@
+// Generated from /home/alex/programming/DiffDetective/src/main/resources/grammars/CExpression.g4 by ANTLR 4.13.1
+package org.variantsync.diffdetective.feature.antlr;
+import org.antlr.v4.runtime.Lexer;
+import org.antlr.v4.runtime.CharStream;
+import org.antlr.v4.runtime.Token;
+import org.antlr.v4.runtime.TokenStream;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.misc.*;
+
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue", "this-escape"})
+public class CExpressionLexer extends Lexer {
+ static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); }
+
+ protected static final DFA[] _decisionToDFA;
+ protected static final PredictionContextCache _sharedContextCache =
+ new PredictionContextCache();
+ public static final int
+ LeftParen=1, RightParen=2, LeftBracket=3, RightBracket=4, LeftBrace=5,
+ RightBrace=6, Less=7, LessEqual=8, Greater=9, GreaterEqual=10, LeftShift=11,
+ RightShift=12, Plus=13, PlusPlus=14, Minus=15, MinusMinus=16, Star=17,
+ Div=18, Mod=19, And=20, Or=21, AndAnd=22, OrOr=23, Caret=24, Not=25, Tilde=26,
+ Question=27, Colon=28, Semi=29, Comma=30, Assign=31, StarAssign=32, DivAssign=33,
+ ModAssign=34, PlusAssign=35, MinusAssign=36, LeftShiftAssign=37, RightShiftAssign=38,
+ AndAssign=39, XorAssign=40, OrAssign=41, Equal=42, NotEqual=43, Arrow=44,
+ Dot=45, Ellipsis=46, HasAttribute=47, HasCPPAttribute=48, HasCAttribute=49,
+ HasBuiltin=50, HasInclude=51, Defined=52, Identifier=53, Constant=54,
+ DigitSequence=55, StringLiteral=56, PathLiteral=57, NumberSign=58, AtSign=59,
+ Dollar=60, AsmBlock=61, Whitespace=62, Newline=63, BlockComment=64, OpenBlockComment=65,
+ LineComment=66;
+ public static String[] channelNames = {
+ "DEFAULT_TOKEN_CHANNEL", "HIDDEN"
+ };
+
+ public static String[] modeNames = {
+ "DEFAULT_MODE"
+ };
+
+ private static String[] makeRuleNames() {
+ return new String[] {
+ "LeftParen", "RightParen", "LeftBracket", "RightBracket", "LeftBrace",
+ "RightBrace", "Less", "LessEqual", "Greater", "GreaterEqual", "LeftShift",
+ "RightShift", "Plus", "PlusPlus", "Minus", "MinusMinus", "Star", "Div",
+ "Mod", "And", "Or", "AndAnd", "OrOr", "Caret", "Not", "Tilde", "Question",
+ "Colon", "Semi", "Comma", "Assign", "StarAssign", "DivAssign", "ModAssign",
+ "PlusAssign", "MinusAssign", "LeftShiftAssign", "RightShiftAssign", "AndAssign",
+ "XorAssign", "OrAssign", "Equal", "NotEqual", "Arrow", "Dot", "Ellipsis",
+ "HasAttribute", "HasCPPAttribute", "HasCAttribute", "HasBuiltin", "HasInclude",
+ "Defined", "Identifier", "IdentifierNondigit", "Nondigit", "Digit", "UniversalCharacterName",
+ "HexQuad", "Constant", "IntegerConstant", "BinaryConstant", "DecimalConstant",
+ "OctalConstant", "HexadecimalConstant", "HexadecimalPrefix", "NonzeroDigit",
+ "OctalDigit", "HexadecimalDigit", "IntegerSuffix", "UnsignedSuffix",
+ "LongSuffix", "LongLongSuffix", "FloatingConstant", "DecimalFloatingConstant",
+ "HexadecimalFloatingConstant", "FractionalConstant", "ExponentPart",
+ "Sign", "DigitSequence", "HexadecimalFractionalConstant", "BinaryExponentPart",
+ "HexadecimalDigitSequence", "FloatingSuffix", "CharacterConstant", "CCharSequence",
+ "CChar", "EscapeSequence", "SimpleEscapeSequence", "OctalEscapeSequence",
+ "HexadecimalEscapeSequence", "StringLiteral", "PathLiteral", "EncodingPrefix",
+ "SCharSequence", "SChar", "NumberSign", "AtSign", "Dollar", "AsmBlock",
+ "Whitespace", "Newline", "BlockComment", "OpenBlockComment", "LineComment"
+ };
+ }
+ public static final String[] ruleNames = makeRuleNames();
+
+ private static String[] makeLiteralNames() {
+ return new String[] {
+ null, "'('", "')'", "'['", "']'", "'{'", "'}'", "'<'", "'<='", "'>'",
+ "'>='", "'<<'", "'>>'", "'+'", "'++'", "'-'", "'--'", "'*'", "'/'", "'%'",
+ "'&'", "'|'", "'&&'", "'||'", "'^'", "'!'", "'~'", "'?'", "':'", "';'",
+ "','", "'='", "'*='", "'/='", "'%='", "'+='", "'-='", "'<<='", "'>>='",
+ "'&='", "'^='", "'|='", "'=='", "'!='", "'->'", "'.'", "'...'", "'__has_attribute'",
+ "'__has_cpp_attribute'", "'__has_c_attribute'", "'__has_builtin'", "'__has_include'",
+ "'defined'", null, null, null, null, null, "'#'", "'@'", "'$'"
+ };
+ }
+ private static final String[] _LITERAL_NAMES = makeLiteralNames();
+ private static String[] makeSymbolicNames() {
+ return new String[] {
+ null, "LeftParen", "RightParen", "LeftBracket", "RightBracket", "LeftBrace",
+ "RightBrace", "Less", "LessEqual", "Greater", "GreaterEqual", "LeftShift",
+ "RightShift", "Plus", "PlusPlus", "Minus", "MinusMinus", "Star", "Div",
+ "Mod", "And", "Or", "AndAnd", "OrOr", "Caret", "Not", "Tilde", "Question",
+ "Colon", "Semi", "Comma", "Assign", "StarAssign", "DivAssign", "ModAssign",
+ "PlusAssign", "MinusAssign", "LeftShiftAssign", "RightShiftAssign", "AndAssign",
+ "XorAssign", "OrAssign", "Equal", "NotEqual", "Arrow", "Dot", "Ellipsis",
+ "HasAttribute", "HasCPPAttribute", "HasCAttribute", "HasBuiltin", "HasInclude",
+ "Defined", "Identifier", "Constant", "DigitSequence", "StringLiteral",
+ "PathLiteral", "NumberSign", "AtSign", "Dollar", "AsmBlock", "Whitespace",
+ "Newline", "BlockComment", "OpenBlockComment", "LineComment"
+ };
+ }
+ private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
+ public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+ /**
+ * @deprecated Use {@link #VOCABULARY} instead.
+ */
+ @Deprecated
+ public static final String[] tokenNames;
+ static {
+ tokenNames = new String[_SYMBOLIC_NAMES.length];
+ for (int i = 0; i < tokenNames.length; i++) {
+ tokenNames[i] = VOCABULARY.getLiteralName(i);
+ if (tokenNames[i] == null) {
+ tokenNames[i] = VOCABULARY.getSymbolicName(i);
+ }
+
+ if (tokenNames[i] == null) {
+ tokenNames[i] = "";
+ }
+ }
+ }
+
+ @Override
+ @Deprecated
+ public String[] getTokenNames() {
+ return tokenNames;
+ }
+
+ @Override
+
+ public Vocabulary getVocabulary() {
+ return VOCABULARY;
+ }
+
+
+ public CExpressionLexer(CharStream input) {
+ super(input);
+ _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
+ }
+
+ @Override
+ public String getGrammarFileName() { return "CExpression.g4"; }
+
+ @Override
+ public String[] getRuleNames() { return ruleNames; }
+
+ @Override
+ public String getSerializedATN() { return _serializedATN; }
+
+ @Override
+ public String[] getChannelNames() { return channelNames; }
+
+ @Override
+ public String[] getModeNames() { return modeNames; }
+
+ @Override
+ public ATN getATN() { return _ATN; }
+
+ public static final String _serializedATN =
+ "\u0004\u0000B\u0311\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+
+ "\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+
+ "\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007"+
+ "\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b"+
+ "\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002"+
+ "\u000f\u0007\u000f\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002"+
+ "\u0012\u0007\u0012\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002"+
+ "\u0015\u0007\u0015\u0002\u0016\u0007\u0016\u0002\u0017\u0007\u0017\u0002"+
+ "\u0018\u0007\u0018\u0002\u0019\u0007\u0019\u0002\u001a\u0007\u001a\u0002"+
+ "\u001b\u0007\u001b\u0002\u001c\u0007\u001c\u0002\u001d\u0007\u001d\u0002"+
+ "\u001e\u0007\u001e\u0002\u001f\u0007\u001f\u0002 \u0007 \u0002!\u0007"+
+ "!\u0002\"\u0007\"\u0002#\u0007#\u0002$\u0007$\u0002%\u0007%\u0002&\u0007"+
+ "&\u0002\'\u0007\'\u0002(\u0007(\u0002)\u0007)\u0002*\u0007*\u0002+\u0007"+
+ "+\u0002,\u0007,\u0002-\u0007-\u0002.\u0007.\u0002/\u0007/\u00020\u0007"+
+ "0\u00021\u00071\u00022\u00072\u00023\u00073\u00024\u00074\u00025\u0007"+
+ "5\u00026\u00076\u00027\u00077\u00028\u00078\u00029\u00079\u0002:\u0007"+
+ ":\u0002;\u0007;\u0002<\u0007<\u0002=\u0007=\u0002>\u0007>\u0002?\u0007"+
+ "?\u0002@\u0007@\u0002A\u0007A\u0002B\u0007B\u0002C\u0007C\u0002D\u0007"+
+ "D\u0002E\u0007E\u0002F\u0007F\u0002G\u0007G\u0002H\u0007H\u0002I\u0007"+
+ "I\u0002J\u0007J\u0002K\u0007K\u0002L\u0007L\u0002M\u0007M\u0002N\u0007"+
+ "N\u0002O\u0007O\u0002P\u0007P\u0002Q\u0007Q\u0002R\u0007R\u0002S\u0007"+
+ "S\u0002T\u0007T\u0002U\u0007U\u0002V\u0007V\u0002W\u0007W\u0002X\u0007"+
+ "X\u0002Y\u0007Y\u0002Z\u0007Z\u0002[\u0007[\u0002\\\u0007\\\u0002]\u0007"+
+ "]\u0002^\u0007^\u0002_\u0007_\u0002`\u0007`\u0002a\u0007a\u0002b\u0007"+
+ "b\u0002c\u0007c\u0002d\u0007d\u0002e\u0007e\u0002f\u0007f\u0002g\u0007"+
+ "g\u0001\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002"+
+ "\u0001\u0003\u0001\u0003\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005"+
+ "\u0001\u0006\u0001\u0006\u0001\u0007\u0001\u0007\u0001\u0007\u0001\b\u0001"+
+ "\b\u0001\t\u0001\t\u0001\t\u0001\n\u0001\n\u0001\n\u0001\u000b\u0001\u000b"+
+ "\u0001\u000b\u0001\f\u0001\f\u0001\r\u0001\r\u0001\r\u0001\u000e\u0001"+
+ "\u000e\u0001\u000f\u0001\u000f\u0001\u000f\u0001\u0010\u0001\u0010\u0001"+
+ "\u0011\u0001\u0011\u0001\u0012\u0001\u0012\u0001\u0013\u0001\u0013\u0001"+
+ "\u0014\u0001\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0001\u0016\u0001"+
+ "\u0016\u0001\u0016\u0001\u0017\u0001\u0017\u0001\u0018\u0001\u0018\u0001"+
+ "\u0019\u0001\u0019\u0001\u001a\u0001\u001a\u0001\u001b\u0001\u001b\u0001"+
+ "\u001c\u0001\u001c\u0001\u001d\u0001\u001d\u0001\u001e\u0001\u001e\u0001"+
+ "\u001f\u0001\u001f\u0001\u001f\u0001 \u0001 \u0001 \u0001!\u0001!\u0001"+
+ "!\u0001\"\u0001\"\u0001\"\u0001#\u0001#\u0001#\u0001$\u0001$\u0001$\u0001"+
+ "$\u0001%\u0001%\u0001%\u0001%\u0001&\u0001&\u0001&\u0001\'\u0001\'\u0001"+
+ "\'\u0001(\u0001(\u0001(\u0001)\u0001)\u0001)\u0001*\u0001*\u0001*\u0001"+
+ "+\u0001+\u0001+\u0001,\u0001,\u0001-\u0001-\u0001-\u0001-\u0001.\u0001"+
+ ".\u0001.\u0001.\u0001.\u0001.\u0001.\u0001.\u0001.\u0001.\u0001.\u0001"+
+ ".\u0001.\u0001.\u0001.\u0001.\u0001/\u0001/\u0001/\u0001/\u0001/\u0001"+
+ "/\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u0001/\u0001"+
+ "/\u0001/\u0001/\u0001/\u0001/\u00010\u00010\u00010\u00010\u00010\u0001"+
+ "0\u00010\u00010\u00010\u00010\u00010\u00010\u00010\u00010\u00010\u0001"+
+ "0\u00010\u00010\u00011\u00011\u00011\u00011\u00011\u00011\u00011\u0001"+
+ "1\u00011\u00011\u00011\u00011\u00011\u00011\u00012\u00012\u00012\u0001"+
+ "2\u00012\u00012\u00012\u00012\u00012\u00012\u00012\u00012\u00012\u0001"+
+ "2\u00013\u00013\u00013\u00013\u00013\u00013\u00013\u00013\u00014\u0003"+
+ "4\u01a2\b4\u00014\u00014\u00044\u01a6\b4\u000b4\f4\u01a7\u00015\u0001"+
+ "5\u00035\u01ac\b5\u00016\u00016\u00017\u00017\u00018\u00018\u00018\u0001"+
+ "8\u00018\u00018\u00018\u00018\u00018\u00018\u00038\u01bc\b8\u00019\u0001"+
+ "9\u00019\u00019\u00019\u0001:\u0001:\u0001:\u0003:\u01c6\b:\u0001;\u0001"+
+ ";\u0003;\u01ca\b;\u0001;\u0001;\u0003;\u01ce\b;\u0001;\u0001;\u0003;\u01d2"+
+ "\b;\u0001;\u0003;\u01d5\b;\u0001<\u0001<\u0001<\u0004<\u01da\b<\u000b"+
+ "<\f<\u01db\u0001=\u0001=\u0005=\u01e0\b=\n=\f=\u01e3\t=\u0001>\u0001>"+
+ "\u0005>\u01e7\b>\n>\f>\u01ea\t>\u0001?\u0001?\u0004?\u01ee\b?\u000b?\f"+
+ "?\u01ef\u0001@\u0001@\u0001@\u0001A\u0001A\u0001B\u0001B\u0001C\u0001"+
+ "C\u0001D\u0001D\u0003D\u01fd\bD\u0001D\u0001D\u0001D\u0001D\u0001D\u0003"+
+ "D\u0204\bD\u0001D\u0001D\u0003D\u0208\bD\u0003D\u020a\bD\u0001E\u0001"+
+ "E\u0001F\u0001F\u0001G\u0001G\u0001G\u0001G\u0003G\u0214\bG\u0001H\u0001"+
+ "H\u0003H\u0218\bH\u0001I\u0001I\u0003I\u021c\bI\u0001I\u0003I\u021f\b"+
+ "I\u0001I\u0001I\u0001I\u0003I\u0224\bI\u0003I\u0226\bI\u0001J\u0001J\u0001"+
+ "J\u0003J\u022b\bJ\u0001J\u0001J\u0003J\u022f\bJ\u0001K\u0003K\u0232\b"+
+ "K\u0001K\u0001K\u0001K\u0001K\u0001K\u0003K\u0239\bK\u0001L\u0001L\u0003"+
+ "L\u023d\bL\u0001L\u0001L\u0001M\u0001M\u0001N\u0004N\u0244\bN\u000bN\f"+
+ "N\u0245\u0001O\u0003O\u0249\bO\u0001O\u0001O\u0001O\u0001O\u0001O\u0003"+
+ "O\u0250\bO\u0001P\u0001P\u0003P\u0254\bP\u0001P\u0001P\u0001Q\u0004Q\u0259"+
+ "\bQ\u000bQ\fQ\u025a\u0001R\u0001R\u0001S\u0001S\u0001S\u0001S\u0001S\u0001"+
+ "S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001"+
+ "S\u0001S\u0001S\u0001S\u0001S\u0001S\u0001S\u0003S\u0275\bS\u0001T\u0004"+
+ "T\u0278\bT\u000bT\fT\u0279\u0001U\u0001U\u0003U\u027e\bU\u0001V\u0001"+
+ "V\u0001V\u0001V\u0003V\u0284\bV\u0001W\u0001W\u0001W\u0001X\u0001X\u0001"+
+ "X\u0003X\u028c\bX\u0001X\u0003X\u028f\bX\u0001Y\u0001Y\u0001Y\u0001Y\u0004"+
+ "Y\u0295\bY\u000bY\fY\u0296\u0001Z\u0003Z\u029a\bZ\u0001Z\u0001Z\u0003"+
+ "Z\u029e\bZ\u0001Z\u0001Z\u0001[\u0001[\u0004[\u02a4\b[\u000b[\f[\u02a5"+
+ "\u0001[\u0001[\u0001\\\u0001\\\u0001\\\u0003\\\u02ad\b\\\u0001]\u0004"+
+ "]\u02b0\b]\u000b]\f]\u02b1\u0001^\u0001^\u0001^\u0001^\u0001^\u0001^\u0001"+
+ "^\u0003^\u02bb\b^\u0001_\u0001_\u0001_\u0001_\u0001`\u0001`\u0001`\u0001"+
+ "`\u0001a\u0001a\u0001a\u0001a\u0001b\u0001b\u0001b\u0001b\u0001b\u0005"+
+ "b\u02ce\bb\nb\fb\u02d1\tb\u0001b\u0001b\u0005b\u02d5\bb\nb\fb\u02d8\t"+
+ "b\u0001b\u0001b\u0001b\u0001b\u0001c\u0004c\u02df\bc\u000bc\fc\u02e0\u0001"+
+ "c\u0001c\u0001d\u0001d\u0003d\u02e7\bd\u0001d\u0003d\u02ea\bd\u0001d\u0001"+
+ "d\u0001e\u0001e\u0001e\u0001e\u0005e\u02f2\be\ne\fe\u02f5\te\u0001e\u0001"+
+ "e\u0001e\u0001e\u0001e\u0001f\u0001f\u0001f\u0001f\u0005f\u0300\bf\nf"+
+ "\ff\u0303\tf\u0001f\u0001f\u0001g\u0001g\u0001g\u0001g\u0005g\u030b\b"+
+ "g\ng\fg\u030e\tg\u0001g\u0001g\u0001\u02f3\u0000h\u0001\u0001\u0003\u0002"+
+ "\u0005\u0003\u0007\u0004\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013"+
+ "\n\u0015\u000b\u0017\f\u0019\r\u001b\u000e\u001d\u000f\u001f\u0010!\u0011"+
+ "#\u0012%\u0013\'\u0014)\u0015+\u0016-\u0017/\u00181\u00193\u001a5\u001b"+
+ "7\u001c9\u001d;\u001e=\u001f? A!C\"E#G$I%K&M\'O(Q)S*U+W,Y-[.]/_0a1c2e"+
+ "3g4i5k\u0000m\u0000o\u0000q\u0000s\u0000u6w\u0000y\u0000{\u0000}\u0000"+
+ "\u007f\u0000\u0081\u0000\u0083\u0000\u0085\u0000\u0087\u0000\u0089\u0000"+
+ "\u008b\u0000\u008d\u0000\u008f\u0000\u0091\u0000\u0093\u0000\u0095\u0000"+
+ "\u0097\u0000\u0099\u0000\u009b\u0000\u009d7\u009f\u0000\u00a1\u0000\u00a3"+
+ "\u0000\u00a5\u0000\u00a7\u0000\u00a9\u0000\u00ab\u0000\u00ad\u0000\u00af"+
+ "\u0000\u00b1\u0000\u00b3\u0000\u00b58\u00b79\u00b9\u0000\u00bb\u0000\u00bd"+
+ "\u0000\u00bf:\u00c1;\u00c3<\u00c5=\u00c7>\u00c9?\u00cb@\u00cdA\u00cfB"+
+ "\u0001\u0000\u0018\u0003\u0000AZ__az\u0001\u000009\u0002\u0000BBbb\u0001"+
+ "\u000001\u0002\u0000XXxx\u0001\u000019\u0001\u000007\u0003\u000009AFa"+
+ "f\u0002\u0000UUuu\u0002\u0000LLll\u0002\u0000EEee\u0002\u0000++--\u0002"+
+ "\u0000PPpp\u0004\u0000FFLLffll\u0004\u0000\n\n\r\r\'\'\\\\\n\u0000\"\""+
+ "\'\'??\\\\abffnnrrttvv\u0004\u0000\t\t <<>>\u0003\u0000LLUUuu\u0004\u0000"+
+ "\n\n\r\r\"\"\\\\\u0001\u0000{{\u0001\u0000}}\u0002\u0000\t\t \u0002\u0000"+
+ "**//\u0002\u0000\n\n\r\r\u032c\u0000\u0001\u0001\u0000\u0000\u0000\u0000"+
+ "\u0003\u0001\u0000\u0000\u0000\u0000\u0005\u0001\u0000\u0000\u0000\u0000"+
+ "\u0007\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000\u0000\u0000\u0000\u000b"+
+ "\u0001\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000\u0000\u0000\u000f\u0001"+
+ "\u0000\u0000\u0000\u0000\u0011\u0001\u0000\u0000\u0000\u0000\u0013\u0001"+
+ "\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000\u0000\u0000\u0017\u0001"+
+ "\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000\u0000\u0000\u001b\u0001"+
+ "\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000\u0000\u0000\u001f\u0001"+
+ "\u0000\u0000\u0000\u0000!\u0001\u0000\u0000\u0000\u0000#\u0001\u0000\u0000"+
+ "\u0000\u0000%\u0001\u0000\u0000\u0000\u0000\'\u0001\u0000\u0000\u0000"+
+ "\u0000)\u0001\u0000\u0000\u0000\u0000+\u0001\u0000\u0000\u0000\u0000-"+
+ "\u0001\u0000\u0000\u0000\u0000/\u0001\u0000\u0000\u0000\u00001\u0001\u0000"+
+ "\u0000\u0000\u00003\u0001\u0000\u0000\u0000\u00005\u0001\u0000\u0000\u0000"+
+ "\u00007\u0001\u0000\u0000\u0000\u00009\u0001\u0000\u0000\u0000\u0000;"+
+ "\u0001\u0000\u0000\u0000\u0000=\u0001\u0000\u0000\u0000\u0000?\u0001\u0000"+
+ "\u0000\u0000\u0000A\u0001\u0000\u0000\u0000\u0000C\u0001\u0000\u0000\u0000"+
+ "\u0000E\u0001\u0000\u0000\u0000\u0000G\u0001\u0000\u0000\u0000\u0000I"+
+ "\u0001\u0000\u0000\u0000\u0000K\u0001\u0000\u0000\u0000\u0000M\u0001\u0000"+
+ "\u0000\u0000\u0000O\u0001\u0000\u0000\u0000\u0000Q\u0001\u0000\u0000\u0000"+
+ "\u0000S\u0001\u0000\u0000\u0000\u0000U\u0001\u0000\u0000\u0000\u0000W"+
+ "\u0001\u0000\u0000\u0000\u0000Y\u0001\u0000\u0000\u0000\u0000[\u0001\u0000"+
+ "\u0000\u0000\u0000]\u0001\u0000\u0000\u0000\u0000_\u0001\u0000\u0000\u0000"+
+ "\u0000a\u0001\u0000\u0000\u0000\u0000c\u0001\u0000\u0000\u0000\u0000e"+
+ "\u0001\u0000\u0000\u0000\u0000g\u0001\u0000\u0000\u0000\u0000i\u0001\u0000"+
+ "\u0000\u0000\u0000u\u0001\u0000\u0000\u0000\u0000\u009d\u0001\u0000\u0000"+
+ "\u0000\u0000\u00b5\u0001\u0000\u0000\u0000\u0000\u00b7\u0001\u0000\u0000"+
+ "\u0000\u0000\u00bf\u0001\u0000\u0000\u0000\u0000\u00c1\u0001\u0000\u0000"+
+ "\u0000\u0000\u00c3\u0001\u0000\u0000\u0000\u0000\u00c5\u0001\u0000\u0000"+
+ "\u0000\u0000\u00c7\u0001\u0000\u0000\u0000\u0000\u00c9\u0001\u0000\u0000"+
+ "\u0000\u0000\u00cb\u0001\u0000\u0000\u0000\u0000\u00cd\u0001\u0000\u0000"+
+ "\u0000\u0000\u00cf\u0001\u0000\u0000\u0000\u0001\u00d1\u0001\u0000\u0000"+
+ "\u0000\u0003\u00d3\u0001\u0000\u0000\u0000\u0005\u00d5\u0001\u0000\u0000"+
+ "\u0000\u0007\u00d7\u0001\u0000\u0000\u0000\t\u00d9\u0001\u0000\u0000\u0000"+
+ "\u000b\u00db\u0001\u0000\u0000\u0000\r\u00dd\u0001\u0000\u0000\u0000\u000f"+
+ "\u00df\u0001\u0000\u0000\u0000\u0011\u00e2\u0001\u0000\u0000\u0000\u0013"+
+ "\u00e4\u0001\u0000\u0000\u0000\u0015\u00e7\u0001\u0000\u0000\u0000\u0017"+
+ "\u00ea\u0001\u0000\u0000\u0000\u0019\u00ed\u0001\u0000\u0000\u0000\u001b"+
+ "\u00ef\u0001\u0000\u0000\u0000\u001d\u00f2\u0001\u0000\u0000\u0000\u001f"+
+ "\u00f4\u0001\u0000\u0000\u0000!\u00f7\u0001\u0000\u0000\u0000#\u00f9\u0001"+
+ "\u0000\u0000\u0000%\u00fb\u0001\u0000\u0000\u0000\'\u00fd\u0001\u0000"+
+ "\u0000\u0000)\u00ff\u0001\u0000\u0000\u0000+\u0101\u0001\u0000\u0000\u0000"+
+ "-\u0104\u0001\u0000\u0000\u0000/\u0107\u0001\u0000\u0000\u00001\u0109"+
+ "\u0001\u0000\u0000\u00003\u010b\u0001\u0000\u0000\u00005\u010d\u0001\u0000"+
+ "\u0000\u00007\u010f\u0001\u0000\u0000\u00009\u0111\u0001\u0000\u0000\u0000"+
+ ";\u0113\u0001\u0000\u0000\u0000=\u0115\u0001\u0000\u0000\u0000?\u0117"+
+ "\u0001\u0000\u0000\u0000A\u011a\u0001\u0000\u0000\u0000C\u011d\u0001\u0000"+
+ "\u0000\u0000E\u0120\u0001\u0000\u0000\u0000G\u0123\u0001\u0000\u0000\u0000"+
+ "I\u0126\u0001\u0000\u0000\u0000K\u012a\u0001\u0000\u0000\u0000M\u012e"+
+ "\u0001\u0000\u0000\u0000O\u0131\u0001\u0000\u0000\u0000Q\u0134\u0001\u0000"+
+ "\u0000\u0000S\u0137\u0001\u0000\u0000\u0000U\u013a\u0001\u0000\u0000\u0000"+
+ "W\u013d\u0001\u0000\u0000\u0000Y\u0140\u0001\u0000\u0000\u0000[\u0142"+
+ "\u0001\u0000\u0000\u0000]\u0146\u0001\u0000\u0000\u0000_\u0156\u0001\u0000"+
+ "\u0000\u0000a\u016a\u0001\u0000\u0000\u0000c\u017c\u0001\u0000\u0000\u0000"+
+ "e\u018a\u0001\u0000\u0000\u0000g\u0198\u0001\u0000\u0000\u0000i\u01a1"+
+ "\u0001\u0000\u0000\u0000k\u01ab\u0001\u0000\u0000\u0000m\u01ad\u0001\u0000"+
+ "\u0000\u0000o\u01af\u0001\u0000\u0000\u0000q\u01bb\u0001\u0000\u0000\u0000"+
+ "s\u01bd\u0001\u0000\u0000\u0000u\u01c5\u0001\u0000\u0000\u0000w\u01d4"+
+ "\u0001\u0000\u0000\u0000y\u01d6\u0001\u0000\u0000\u0000{\u01dd\u0001\u0000"+
+ "\u0000\u0000}\u01e4\u0001\u0000\u0000\u0000\u007f\u01eb\u0001\u0000\u0000"+
+ "\u0000\u0081\u01f1\u0001\u0000\u0000\u0000\u0083\u01f4\u0001\u0000\u0000"+
+ "\u0000\u0085\u01f6\u0001\u0000\u0000\u0000\u0087\u01f8\u0001\u0000\u0000"+
+ "\u0000\u0089\u0209\u0001\u0000\u0000\u0000\u008b\u020b\u0001\u0000\u0000"+
+ "\u0000\u008d\u020d\u0001\u0000\u0000\u0000\u008f\u0213\u0001\u0000\u0000"+
+ "\u0000\u0091\u0217\u0001\u0000\u0000\u0000\u0093\u0225\u0001\u0000\u0000"+
+ "\u0000\u0095\u0227\u0001\u0000\u0000\u0000\u0097\u0238\u0001\u0000\u0000"+
+ "\u0000\u0099\u023a\u0001\u0000\u0000\u0000\u009b\u0240\u0001\u0000\u0000"+
+ "\u0000\u009d\u0243\u0001\u0000\u0000\u0000\u009f\u024f\u0001\u0000\u0000"+
+ "\u0000\u00a1\u0251\u0001\u0000\u0000\u0000\u00a3\u0258\u0001\u0000\u0000"+
+ "\u0000\u00a5\u025c\u0001\u0000\u0000\u0000\u00a7\u0274\u0001\u0000\u0000"+
+ "\u0000\u00a9\u0277\u0001\u0000\u0000\u0000\u00ab\u027d\u0001\u0000\u0000"+
+ "\u0000\u00ad\u0283\u0001\u0000\u0000\u0000\u00af\u0285\u0001\u0000\u0000"+
+ "\u0000\u00b1\u0288\u0001\u0000\u0000\u0000\u00b3\u0290\u0001\u0000\u0000"+
+ "\u0000\u00b5\u0299\u0001\u0000\u0000\u0000\u00b7\u02a1\u0001\u0000\u0000"+
+ "\u0000\u00b9\u02ac\u0001\u0000\u0000\u0000\u00bb\u02af\u0001\u0000\u0000"+
+ "\u0000\u00bd\u02ba\u0001\u0000\u0000\u0000\u00bf\u02bc\u0001\u0000\u0000"+
+ "\u0000\u00c1\u02c0\u0001\u0000\u0000\u0000\u00c3\u02c4\u0001\u0000\u0000"+
+ "\u0000\u00c5\u02c8\u0001\u0000\u0000\u0000\u00c7\u02de\u0001\u0000\u0000"+
+ "\u0000\u00c9\u02e9\u0001\u0000\u0000\u0000\u00cb\u02ed\u0001\u0000\u0000"+
+ "\u0000\u00cd\u02fb\u0001\u0000\u0000\u0000\u00cf\u0306\u0001\u0000\u0000"+
+ "\u0000\u00d1\u00d2\u0005(\u0000\u0000\u00d2\u0002\u0001\u0000\u0000\u0000"+
+ "\u00d3\u00d4\u0005)\u0000\u0000\u00d4\u0004\u0001\u0000\u0000\u0000\u00d5"+
+ "\u00d6\u0005[\u0000\u0000\u00d6\u0006\u0001\u0000\u0000\u0000\u00d7\u00d8"+
+ "\u0005]\u0000\u0000\u00d8\b\u0001\u0000\u0000\u0000\u00d9\u00da\u0005"+
+ "{\u0000\u0000\u00da\n\u0001\u0000\u0000\u0000\u00db\u00dc\u0005}\u0000"+
+ "\u0000\u00dc\f\u0001\u0000\u0000\u0000\u00dd\u00de\u0005<\u0000\u0000"+
+ "\u00de\u000e\u0001\u0000\u0000\u0000\u00df\u00e0\u0005<\u0000\u0000\u00e0"+
+ "\u00e1\u0005=\u0000\u0000\u00e1\u0010\u0001\u0000\u0000\u0000\u00e2\u00e3"+
+ "\u0005>\u0000\u0000\u00e3\u0012\u0001\u0000\u0000\u0000\u00e4\u00e5\u0005"+
+ ">\u0000\u0000\u00e5\u00e6\u0005=\u0000\u0000\u00e6\u0014\u0001\u0000\u0000"+
+ "\u0000\u00e7\u00e8\u0005<\u0000\u0000\u00e8\u00e9\u0005<\u0000\u0000\u00e9"+
+ "\u0016\u0001\u0000\u0000\u0000\u00ea\u00eb\u0005>\u0000\u0000\u00eb\u00ec"+
+ "\u0005>\u0000\u0000\u00ec\u0018\u0001\u0000\u0000\u0000\u00ed\u00ee\u0005"+
+ "+\u0000\u0000\u00ee\u001a\u0001\u0000\u0000\u0000\u00ef\u00f0\u0005+\u0000"+
+ "\u0000\u00f0\u00f1\u0005+\u0000\u0000\u00f1\u001c\u0001\u0000\u0000\u0000"+
+ "\u00f2\u00f3\u0005-\u0000\u0000\u00f3\u001e\u0001\u0000\u0000\u0000\u00f4"+
+ "\u00f5\u0005-\u0000\u0000\u00f5\u00f6\u0005-\u0000\u0000\u00f6 \u0001"+
+ "\u0000\u0000\u0000\u00f7\u00f8\u0005*\u0000\u0000\u00f8\"\u0001\u0000"+
+ "\u0000\u0000\u00f9\u00fa\u0005/\u0000\u0000\u00fa$\u0001\u0000\u0000\u0000"+
+ "\u00fb\u00fc\u0005%\u0000\u0000\u00fc&\u0001\u0000\u0000\u0000\u00fd\u00fe"+
+ "\u0005&\u0000\u0000\u00fe(\u0001\u0000\u0000\u0000\u00ff\u0100\u0005|"+
+ "\u0000\u0000\u0100*\u0001\u0000\u0000\u0000\u0101\u0102\u0005&\u0000\u0000"+
+ "\u0102\u0103\u0005&\u0000\u0000\u0103,\u0001\u0000\u0000\u0000\u0104\u0105"+
+ "\u0005|\u0000\u0000\u0105\u0106\u0005|\u0000\u0000\u0106.\u0001\u0000"+
+ "\u0000\u0000\u0107\u0108\u0005^\u0000\u0000\u01080\u0001\u0000\u0000\u0000"+
+ "\u0109\u010a\u0005!\u0000\u0000\u010a2\u0001\u0000\u0000\u0000\u010b\u010c"+
+ "\u0005~\u0000\u0000\u010c4\u0001\u0000\u0000\u0000\u010d\u010e\u0005?"+
+ "\u0000\u0000\u010e6\u0001\u0000\u0000\u0000\u010f\u0110\u0005:\u0000\u0000"+
+ "\u01108\u0001\u0000\u0000\u0000\u0111\u0112\u0005;\u0000\u0000\u0112:"+
+ "\u0001\u0000\u0000\u0000\u0113\u0114\u0005,\u0000\u0000\u0114<\u0001\u0000"+
+ "\u0000\u0000\u0115\u0116\u0005=\u0000\u0000\u0116>\u0001\u0000\u0000\u0000"+
+ "\u0117\u0118\u0005*\u0000\u0000\u0118\u0119\u0005=\u0000\u0000\u0119@"+
+ "\u0001\u0000\u0000\u0000\u011a\u011b\u0005/\u0000\u0000\u011b\u011c\u0005"+
+ "=\u0000\u0000\u011cB\u0001\u0000\u0000\u0000\u011d\u011e\u0005%\u0000"+
+ "\u0000\u011e\u011f\u0005=\u0000\u0000\u011fD\u0001\u0000\u0000\u0000\u0120"+
+ "\u0121\u0005+\u0000\u0000\u0121\u0122\u0005=\u0000\u0000\u0122F\u0001"+
+ "\u0000\u0000\u0000\u0123\u0124\u0005-\u0000\u0000\u0124\u0125\u0005=\u0000"+
+ "\u0000\u0125H\u0001\u0000\u0000\u0000\u0126\u0127\u0005<\u0000\u0000\u0127"+
+ "\u0128\u0005<\u0000\u0000\u0128\u0129\u0005=\u0000\u0000\u0129J\u0001"+
+ "\u0000\u0000\u0000\u012a\u012b\u0005>\u0000\u0000\u012b\u012c\u0005>\u0000"+
+ "\u0000\u012c\u012d\u0005=\u0000\u0000\u012dL\u0001\u0000\u0000\u0000\u012e"+
+ "\u012f\u0005&\u0000\u0000\u012f\u0130\u0005=\u0000\u0000\u0130N\u0001"+
+ "\u0000\u0000\u0000\u0131\u0132\u0005^\u0000\u0000\u0132\u0133\u0005=\u0000"+
+ "\u0000\u0133P\u0001\u0000\u0000\u0000\u0134\u0135\u0005|\u0000\u0000\u0135"+
+ "\u0136\u0005=\u0000\u0000\u0136R\u0001\u0000\u0000\u0000\u0137\u0138\u0005"+
+ "=\u0000\u0000\u0138\u0139\u0005=\u0000\u0000\u0139T\u0001\u0000\u0000"+
+ "\u0000\u013a\u013b\u0005!\u0000\u0000\u013b\u013c\u0005=\u0000\u0000\u013c"+
+ "V\u0001\u0000\u0000\u0000\u013d\u013e\u0005-\u0000\u0000\u013e\u013f\u0005"+
+ ">\u0000\u0000\u013fX\u0001\u0000\u0000\u0000\u0140\u0141\u0005.\u0000"+
+ "\u0000\u0141Z\u0001\u0000\u0000\u0000\u0142\u0143\u0005.\u0000\u0000\u0143"+
+ "\u0144\u0005.\u0000\u0000\u0144\u0145\u0005.\u0000\u0000\u0145\\\u0001"+
+ "\u0000\u0000\u0000\u0146\u0147\u0005_\u0000\u0000\u0147\u0148\u0005_\u0000"+
+ "\u0000\u0148\u0149\u0005h\u0000\u0000\u0149\u014a\u0005a\u0000\u0000\u014a"+
+ "\u014b\u0005s\u0000\u0000\u014b\u014c\u0005_\u0000\u0000\u014c\u014d\u0005"+
+ "a\u0000\u0000\u014d\u014e\u0005t\u0000\u0000\u014e\u014f\u0005t\u0000"+
+ "\u0000\u014f\u0150\u0005r\u0000\u0000\u0150\u0151\u0005i\u0000\u0000\u0151"+
+ "\u0152\u0005b\u0000\u0000\u0152\u0153\u0005u\u0000\u0000\u0153\u0154\u0005"+
+ "t\u0000\u0000\u0154\u0155\u0005e\u0000\u0000\u0155^\u0001\u0000\u0000"+
+ "\u0000\u0156\u0157\u0005_\u0000\u0000\u0157\u0158\u0005_\u0000\u0000\u0158"+
+ "\u0159\u0005h\u0000\u0000\u0159\u015a\u0005a\u0000\u0000\u015a\u015b\u0005"+
+ "s\u0000\u0000\u015b\u015c\u0005_\u0000\u0000\u015c\u015d\u0005c\u0000"+
+ "\u0000\u015d\u015e\u0005p\u0000\u0000\u015e\u015f\u0005p\u0000\u0000\u015f"+
+ "\u0160\u0005_\u0000\u0000\u0160\u0161\u0005a\u0000\u0000\u0161\u0162\u0005"+
+ "t\u0000\u0000\u0162\u0163\u0005t\u0000\u0000\u0163\u0164\u0005r\u0000"+
+ "\u0000\u0164\u0165\u0005i\u0000\u0000\u0165\u0166\u0005b\u0000\u0000\u0166"+
+ "\u0167\u0005u\u0000\u0000\u0167\u0168\u0005t\u0000\u0000\u0168\u0169\u0005"+
+ "e\u0000\u0000\u0169`\u0001\u0000\u0000\u0000\u016a\u016b\u0005_\u0000"+
+ "\u0000\u016b\u016c\u0005_\u0000\u0000\u016c\u016d\u0005h\u0000\u0000\u016d"+
+ "\u016e\u0005a\u0000\u0000\u016e\u016f\u0005s\u0000\u0000\u016f\u0170\u0005"+
+ "_\u0000\u0000\u0170\u0171\u0005c\u0000\u0000\u0171\u0172\u0005_\u0000"+
+ "\u0000\u0172\u0173\u0005a\u0000\u0000\u0173\u0174\u0005t\u0000\u0000\u0174"+
+ "\u0175\u0005t\u0000\u0000\u0175\u0176\u0005r\u0000\u0000\u0176\u0177\u0005"+
+ "i\u0000\u0000\u0177\u0178\u0005b\u0000\u0000\u0178\u0179\u0005u\u0000"+
+ "\u0000\u0179\u017a\u0005t\u0000\u0000\u017a\u017b\u0005e\u0000\u0000\u017b"+
+ "b\u0001\u0000\u0000\u0000\u017c\u017d\u0005_\u0000\u0000\u017d\u017e\u0005"+
+ "_\u0000\u0000\u017e\u017f\u0005h\u0000\u0000\u017f\u0180\u0005a\u0000"+
+ "\u0000\u0180\u0181\u0005s\u0000\u0000\u0181\u0182\u0005_\u0000\u0000\u0182"+
+ "\u0183\u0005b\u0000\u0000\u0183\u0184\u0005u\u0000\u0000\u0184\u0185\u0005"+
+ "i\u0000\u0000\u0185\u0186\u0005l\u0000\u0000\u0186\u0187\u0005t\u0000"+
+ "\u0000\u0187\u0188\u0005i\u0000\u0000\u0188\u0189\u0005n\u0000\u0000\u0189"+
+ "d\u0001\u0000\u0000\u0000\u018a\u018b\u0005_\u0000\u0000\u018b\u018c\u0005"+
+ "_\u0000\u0000\u018c\u018d\u0005h\u0000\u0000\u018d\u018e\u0005a\u0000"+
+ "\u0000\u018e\u018f\u0005s\u0000\u0000\u018f\u0190\u0005_\u0000\u0000\u0190"+
+ "\u0191\u0005i\u0000\u0000\u0191\u0192\u0005n\u0000\u0000\u0192\u0193\u0005"+
+ "c\u0000\u0000\u0193\u0194\u0005l\u0000\u0000\u0194\u0195\u0005u\u0000"+
+ "\u0000\u0195\u0196\u0005d\u0000\u0000\u0196\u0197\u0005e\u0000\u0000\u0197"+
+ "f\u0001\u0000\u0000\u0000\u0198\u0199\u0005d\u0000\u0000\u0199\u019a\u0005"+
+ "e\u0000\u0000\u019a\u019b\u0005f\u0000\u0000\u019b\u019c\u0005i\u0000"+
+ "\u0000\u019c\u019d\u0005n\u0000\u0000\u019d\u019e\u0005e\u0000\u0000\u019e"+
+ "\u019f\u0005d\u0000\u0000\u019fh\u0001\u0000\u0000\u0000\u01a0\u01a2\u0005"+
+ "\\\u0000\u0000\u01a1\u01a0\u0001\u0000\u0000\u0000\u01a1\u01a2\u0001\u0000"+
+ "\u0000\u0000\u01a2\u01a5\u0001\u0000\u0000\u0000\u01a3\u01a6\u0003k5\u0000"+
+ "\u01a4\u01a6\u0003o7\u0000\u01a5\u01a3\u0001\u0000\u0000\u0000\u01a5\u01a4"+
+ "\u0001\u0000\u0000\u0000\u01a6\u01a7\u0001\u0000\u0000\u0000\u01a7\u01a5"+
+ "\u0001\u0000\u0000\u0000\u01a7\u01a8\u0001\u0000\u0000\u0000\u01a8j\u0001"+
+ "\u0000\u0000\u0000\u01a9\u01ac\u0003m6\u0000\u01aa\u01ac\u0003q8\u0000"+
+ "\u01ab\u01a9\u0001\u0000\u0000\u0000\u01ab\u01aa\u0001\u0000\u0000\u0000"+
+ "\u01acl\u0001\u0000\u0000\u0000\u01ad\u01ae\u0007\u0000\u0000\u0000\u01ae"+
+ "n\u0001\u0000\u0000\u0000\u01af\u01b0\u0007\u0001\u0000\u0000\u01b0p\u0001"+
+ "\u0000\u0000\u0000\u01b1\u01b2\u0005\\\u0000\u0000\u01b2\u01b3\u0005u"+
+ "\u0000\u0000\u01b3\u01b4\u0001\u0000\u0000\u0000\u01b4\u01bc\u0003s9\u0000"+
+ "\u01b5\u01b6\u0005\\\u0000\u0000\u01b6\u01b7\u0005U\u0000\u0000\u01b7"+
+ "\u01b8\u0001\u0000\u0000\u0000\u01b8\u01b9\u0003s9\u0000\u01b9\u01ba\u0003"+
+ "s9\u0000\u01ba\u01bc\u0001\u0000\u0000\u0000\u01bb\u01b1\u0001\u0000\u0000"+
+ "\u0000\u01bb\u01b5\u0001\u0000\u0000\u0000\u01bcr\u0001\u0000\u0000\u0000"+
+ "\u01bd\u01be\u0003\u0087C\u0000\u01be\u01bf\u0003\u0087C\u0000\u01bf\u01c0"+
+ "\u0003\u0087C\u0000\u01c0\u01c1\u0003\u0087C\u0000\u01c1t\u0001\u0000"+
+ "\u0000\u0000\u01c2\u01c6\u0003w;\u0000\u01c3\u01c6\u0003\u0091H\u0000"+
+ "\u01c4\u01c6\u0003\u00a7S\u0000\u01c5\u01c2\u0001\u0000\u0000\u0000\u01c5"+
+ "\u01c3\u0001\u0000\u0000\u0000\u01c5\u01c4\u0001\u0000\u0000\u0000\u01c6"+
+ "v\u0001\u0000\u0000\u0000\u01c7\u01c9\u0003{=\u0000\u01c8\u01ca\u0003"+
+ "\u0089D\u0000\u01c9\u01c8\u0001\u0000\u0000\u0000\u01c9\u01ca\u0001\u0000"+
+ "\u0000\u0000\u01ca\u01d5\u0001\u0000\u0000\u0000\u01cb\u01cd\u0003}>\u0000"+
+ "\u01cc\u01ce\u0003\u0089D\u0000\u01cd\u01cc\u0001\u0000\u0000\u0000\u01cd"+
+ "\u01ce\u0001\u0000\u0000\u0000\u01ce\u01d5\u0001\u0000\u0000\u0000\u01cf"+
+ "\u01d1\u0003\u007f?\u0000\u01d0\u01d2\u0003\u0089D\u0000\u01d1\u01d0\u0001"+
+ "\u0000\u0000\u0000\u01d1\u01d2\u0001\u0000\u0000\u0000\u01d2\u01d5\u0001"+
+ "\u0000\u0000\u0000\u01d3\u01d5\u0003y<\u0000\u01d4\u01c7\u0001\u0000\u0000"+
+ "\u0000\u01d4\u01cb\u0001\u0000\u0000\u0000\u01d4\u01cf\u0001\u0000\u0000"+
+ "\u0000\u01d4\u01d3\u0001\u0000\u0000\u0000\u01d5x\u0001\u0000\u0000\u0000"+
+ "\u01d6\u01d7\u00050\u0000\u0000\u01d7\u01d9\u0007\u0002\u0000\u0000\u01d8"+
+ "\u01da\u0007\u0003\u0000\u0000\u01d9\u01d8\u0001\u0000\u0000\u0000\u01da"+
+ "\u01db\u0001\u0000\u0000\u0000\u01db\u01d9\u0001\u0000\u0000\u0000\u01db"+
+ "\u01dc\u0001\u0000\u0000\u0000\u01dcz\u0001\u0000\u0000\u0000\u01dd\u01e1"+
+ "\u0003\u0083A\u0000\u01de\u01e0\u0003o7\u0000\u01df\u01de\u0001\u0000"+
+ "\u0000\u0000\u01e0\u01e3\u0001\u0000\u0000\u0000\u01e1\u01df\u0001\u0000"+
+ "\u0000\u0000\u01e1\u01e2\u0001\u0000\u0000\u0000\u01e2|\u0001\u0000\u0000"+
+ "\u0000\u01e3\u01e1\u0001\u0000\u0000\u0000\u01e4\u01e8\u00050\u0000\u0000"+
+ "\u01e5\u01e7\u0003\u0085B\u0000\u01e6\u01e5\u0001\u0000\u0000\u0000\u01e7"+
+ "\u01ea\u0001\u0000\u0000\u0000\u01e8\u01e6\u0001\u0000\u0000\u0000\u01e8"+
+ "\u01e9\u0001\u0000\u0000\u0000\u01e9~\u0001\u0000\u0000\u0000\u01ea\u01e8"+
+ "\u0001\u0000\u0000\u0000\u01eb\u01ed\u0003\u0081@\u0000\u01ec\u01ee\u0003"+
+ "\u0087C\u0000\u01ed\u01ec\u0001\u0000\u0000\u0000\u01ee\u01ef\u0001\u0000"+
+ "\u0000\u0000\u01ef\u01ed\u0001\u0000\u0000\u0000\u01ef\u01f0\u0001\u0000"+
+ "\u0000\u0000\u01f0\u0080\u0001\u0000\u0000\u0000\u01f1\u01f2\u00050\u0000"+
+ "\u0000\u01f2\u01f3\u0007\u0004\u0000\u0000\u01f3\u0082\u0001\u0000\u0000"+
+ "\u0000\u01f4\u01f5\u0007\u0005\u0000\u0000\u01f5\u0084\u0001\u0000\u0000"+
+ "\u0000\u01f6\u01f7\u0007\u0006\u0000\u0000\u01f7\u0086\u0001\u0000\u0000"+
+ "\u0000\u01f8\u01f9\u0007\u0007\u0000\u0000\u01f9\u0088\u0001\u0000\u0000"+
+ "\u0000\u01fa\u01fc\u0003\u008bE\u0000\u01fb\u01fd\u0003\u008dF\u0000\u01fc"+
+ "\u01fb\u0001\u0000\u0000\u0000\u01fc\u01fd\u0001\u0000\u0000\u0000\u01fd"+
+ "\u020a\u0001\u0000\u0000\u0000\u01fe\u01ff\u0003\u008bE\u0000\u01ff\u0200"+
+ "\u0003\u008fG\u0000\u0200\u020a\u0001\u0000\u0000\u0000\u0201\u0203\u0003"+
+ "\u008dF\u0000\u0202\u0204\u0003\u008bE\u0000\u0203\u0202\u0001\u0000\u0000"+
+ "\u0000\u0203\u0204\u0001\u0000\u0000\u0000\u0204\u020a\u0001\u0000\u0000"+
+ "\u0000\u0205\u0207\u0003\u008fG\u0000\u0206\u0208\u0003\u008bE\u0000\u0207"+
+ "\u0206\u0001\u0000\u0000\u0000\u0207\u0208\u0001\u0000\u0000\u0000\u0208"+
+ "\u020a\u0001\u0000\u0000\u0000\u0209\u01fa\u0001\u0000\u0000\u0000\u0209"+
+ "\u01fe\u0001\u0000\u0000\u0000\u0209\u0201\u0001\u0000\u0000\u0000\u0209"+
+ "\u0205\u0001\u0000\u0000\u0000\u020a\u008a\u0001\u0000\u0000\u0000\u020b"+
+ "\u020c\u0007\b\u0000\u0000\u020c\u008c\u0001\u0000\u0000\u0000\u020d\u020e"+
+ "\u0007\t\u0000\u0000\u020e\u008e\u0001\u0000\u0000\u0000\u020f\u0210\u0005"+
+ "l\u0000\u0000\u0210\u0214\u0005l\u0000\u0000\u0211\u0212\u0005L\u0000"+
+ "\u0000\u0212\u0214\u0005L\u0000\u0000\u0213\u020f\u0001\u0000\u0000\u0000"+
+ "\u0213\u0211\u0001\u0000\u0000\u0000\u0214\u0090\u0001\u0000\u0000\u0000"+
+ "\u0215\u0218\u0003\u0093I\u0000\u0216\u0218\u0003\u0095J\u0000\u0217\u0215"+
+ "\u0001\u0000\u0000\u0000\u0217\u0216\u0001\u0000\u0000\u0000\u0218\u0092"+
+ "\u0001\u0000\u0000\u0000\u0219\u021b\u0003\u0097K\u0000\u021a\u021c\u0003"+
+ "\u0099L\u0000\u021b\u021a\u0001\u0000\u0000\u0000\u021b\u021c\u0001\u0000"+
+ "\u0000\u0000\u021c\u021e\u0001\u0000\u0000\u0000\u021d\u021f\u0003\u00a5"+
+ "R\u0000\u021e\u021d\u0001\u0000\u0000\u0000\u021e\u021f\u0001\u0000\u0000"+
+ "\u0000\u021f\u0226\u0001\u0000\u0000\u0000\u0220\u0221\u0003\u009dN\u0000"+
+ "\u0221\u0223\u0003\u0099L\u0000\u0222\u0224\u0003\u00a5R\u0000\u0223\u0222"+
+ "\u0001\u0000\u0000\u0000\u0223\u0224\u0001\u0000\u0000\u0000\u0224\u0226"+
+ "\u0001\u0000\u0000\u0000\u0225\u0219\u0001\u0000\u0000\u0000\u0225\u0220"+
+ "\u0001\u0000\u0000\u0000\u0226\u0094\u0001\u0000\u0000\u0000\u0227\u022a"+
+ "\u0003\u0081@\u0000\u0228\u022b\u0003\u009fO\u0000\u0229\u022b\u0003\u00a3"+
+ "Q\u0000\u022a\u0228\u0001\u0000\u0000\u0000\u022a\u0229\u0001\u0000\u0000"+
+ "\u0000\u022b\u022c\u0001\u0000\u0000\u0000\u022c\u022e\u0003\u00a1P\u0000"+
+ "\u022d\u022f\u0003\u00a5R\u0000\u022e\u022d\u0001\u0000\u0000\u0000\u022e"+
+ "\u022f\u0001\u0000\u0000\u0000\u022f\u0096\u0001\u0000\u0000\u0000\u0230"+
+ "\u0232\u0003\u009dN\u0000\u0231\u0230\u0001\u0000\u0000\u0000\u0231\u0232"+
+ "\u0001\u0000\u0000\u0000\u0232\u0233\u0001\u0000\u0000\u0000\u0233\u0234"+
+ "\u0005.\u0000\u0000\u0234\u0239\u0003\u009dN\u0000\u0235\u0236\u0003\u009d"+
+ "N\u0000\u0236\u0237\u0005.\u0000\u0000\u0237\u0239\u0001\u0000\u0000\u0000"+
+ "\u0238\u0231\u0001\u0000\u0000\u0000\u0238\u0235\u0001\u0000\u0000\u0000"+
+ "\u0239\u0098\u0001\u0000\u0000\u0000\u023a\u023c\u0007\n\u0000\u0000\u023b"+
+ "\u023d\u0003\u009bM\u0000\u023c\u023b\u0001\u0000\u0000\u0000\u023c\u023d"+
+ "\u0001\u0000\u0000\u0000\u023d\u023e\u0001\u0000\u0000\u0000\u023e\u023f"+
+ "\u0003\u009dN\u0000\u023f\u009a\u0001\u0000\u0000\u0000\u0240\u0241\u0007"+
+ "\u000b\u0000\u0000\u0241\u009c\u0001\u0000\u0000\u0000\u0242\u0244\u0003"+
+ "o7\u0000\u0243\u0242\u0001\u0000\u0000\u0000\u0244\u0245\u0001\u0000\u0000"+
+ "\u0000\u0245\u0243\u0001\u0000\u0000\u0000\u0245\u0246\u0001\u0000\u0000"+
+ "\u0000\u0246\u009e\u0001\u0000\u0000\u0000\u0247\u0249\u0003\u00a3Q\u0000"+
+ "\u0248\u0247\u0001\u0000\u0000\u0000\u0248\u0249\u0001\u0000\u0000\u0000"+
+ "\u0249\u024a\u0001\u0000\u0000\u0000\u024a\u024b\u0005.\u0000\u0000\u024b"+
+ "\u0250\u0003\u00a3Q\u0000\u024c\u024d\u0003\u00a3Q\u0000\u024d\u024e\u0005"+
+ ".\u0000\u0000\u024e\u0250\u0001\u0000\u0000\u0000\u024f\u0248\u0001\u0000"+
+ "\u0000\u0000\u024f\u024c\u0001\u0000\u0000\u0000\u0250\u00a0\u0001\u0000"+
+ "\u0000\u0000\u0251\u0253\u0007\f\u0000\u0000\u0252\u0254\u0003\u009bM"+
+ "\u0000\u0253\u0252\u0001\u0000\u0000\u0000\u0253\u0254\u0001\u0000\u0000"+
+ "\u0000\u0254\u0255\u0001\u0000\u0000\u0000\u0255\u0256\u0003\u009dN\u0000"+
+ "\u0256\u00a2\u0001\u0000\u0000\u0000\u0257\u0259\u0003\u0087C\u0000\u0258"+
+ "\u0257\u0001\u0000\u0000\u0000\u0259\u025a\u0001\u0000\u0000\u0000\u025a"+
+ "\u0258\u0001\u0000\u0000\u0000\u025a\u025b\u0001\u0000\u0000\u0000\u025b"+
+ "\u00a4\u0001\u0000\u0000\u0000\u025c\u025d\u0007\r\u0000\u0000\u025d\u00a6"+
+ "\u0001\u0000\u0000\u0000\u025e\u025f\u0005\'\u0000\u0000\u025f\u0260\u0003"+
+ "\u00a9T\u0000\u0260\u0261\u0005\'\u0000\u0000\u0261\u0275\u0001\u0000"+
+ "\u0000\u0000\u0262\u0263\u0005L\u0000\u0000\u0263\u0264\u0005\'\u0000"+
+ "\u0000\u0264\u0265\u0001\u0000\u0000\u0000\u0265\u0266\u0003\u00a9T\u0000"+
+ "\u0266\u0267\u0005\'\u0000\u0000\u0267\u0275\u0001\u0000\u0000\u0000\u0268"+
+ "\u0269\u0005u\u0000\u0000\u0269\u026a\u0005\'\u0000\u0000\u026a\u026b"+
+ "\u0001\u0000\u0000\u0000\u026b\u026c\u0003\u00a9T\u0000\u026c\u026d\u0005"+
+ "\'\u0000\u0000\u026d\u0275\u0001\u0000\u0000\u0000\u026e\u026f\u0005U"+
+ "\u0000\u0000\u026f\u0270\u0005\'\u0000\u0000\u0270\u0271\u0001\u0000\u0000"+
+ "\u0000\u0271\u0272\u0003\u00a9T\u0000\u0272\u0273\u0005\'\u0000\u0000"+
+ "\u0273\u0275\u0001\u0000\u0000\u0000\u0274\u025e\u0001\u0000\u0000\u0000"+
+ "\u0274\u0262\u0001\u0000\u0000\u0000\u0274\u0268\u0001\u0000\u0000\u0000"+
+ "\u0274\u026e\u0001\u0000\u0000\u0000\u0275\u00a8\u0001\u0000\u0000\u0000"+
+ "\u0276\u0278\u0003\u00abU\u0000\u0277\u0276\u0001\u0000\u0000\u0000\u0278"+
+ "\u0279\u0001\u0000\u0000\u0000\u0279\u0277\u0001\u0000\u0000\u0000\u0279"+
+ "\u027a\u0001\u0000\u0000\u0000\u027a\u00aa\u0001\u0000\u0000\u0000\u027b"+
+ "\u027e\b\u000e\u0000\u0000\u027c\u027e\u0003\u00adV\u0000\u027d\u027b"+
+ "\u0001\u0000\u0000\u0000\u027d\u027c\u0001\u0000\u0000\u0000\u027e\u00ac"+
+ "\u0001\u0000\u0000\u0000\u027f\u0284\u0003\u00afW\u0000\u0280\u0284\u0003"+
+ "\u00b1X\u0000\u0281\u0284\u0003\u00b3Y\u0000\u0282\u0284\u0003q8\u0000"+
+ "\u0283\u027f\u0001\u0000\u0000\u0000\u0283\u0280\u0001\u0000\u0000\u0000"+
+ "\u0283\u0281\u0001\u0000\u0000\u0000\u0283\u0282\u0001\u0000\u0000\u0000"+
+ "\u0284\u00ae\u0001\u0000\u0000\u0000\u0285\u0286\u0005\\\u0000\u0000\u0286"+
+ "\u0287\u0007\u000f\u0000\u0000\u0287\u00b0\u0001\u0000\u0000\u0000\u0288"+
+ "\u0289\u0005\\\u0000\u0000\u0289\u028b\u0003\u0085B\u0000\u028a\u028c"+
+ "\u0003\u0085B\u0000\u028b\u028a\u0001\u0000\u0000\u0000\u028b\u028c\u0001"+
+ "\u0000\u0000\u0000\u028c\u028e\u0001\u0000\u0000\u0000\u028d\u028f\u0003"+
+ "\u0085B\u0000\u028e\u028d\u0001\u0000\u0000\u0000\u028e\u028f\u0001\u0000"+
+ "\u0000\u0000\u028f\u00b2\u0001\u0000\u0000\u0000\u0290\u0291\u0005\\\u0000"+
+ "\u0000\u0291\u0292\u0005x\u0000\u0000\u0292\u0294\u0001\u0000\u0000\u0000"+
+ "\u0293\u0295\u0003\u0087C\u0000\u0294\u0293\u0001\u0000\u0000\u0000\u0295"+
+ "\u0296\u0001\u0000\u0000\u0000\u0296\u0294\u0001\u0000\u0000\u0000\u0296"+
+ "\u0297\u0001\u0000\u0000\u0000\u0297\u00b4\u0001\u0000\u0000\u0000\u0298"+
+ "\u029a\u0003\u00b9\\\u0000\u0299\u0298\u0001\u0000\u0000\u0000\u0299\u029a"+
+ "\u0001\u0000\u0000\u0000\u029a\u029b\u0001\u0000\u0000\u0000\u029b\u029d"+
+ "\u0005\"\u0000\u0000\u029c\u029e\u0003\u00bb]\u0000\u029d\u029c\u0001"+
+ "\u0000\u0000\u0000\u029d\u029e\u0001\u0000\u0000\u0000\u029e\u029f\u0001"+
+ "\u0000\u0000\u0000\u029f\u02a0\u0005\"\u0000\u0000\u02a0\u00b6\u0001\u0000"+
+ "\u0000\u0000\u02a1\u02a3\u0005<\u0000\u0000\u02a2\u02a4\b\u0010\u0000"+
+ "\u0000\u02a3\u02a2\u0001\u0000\u0000\u0000\u02a4\u02a5\u0001\u0000\u0000"+
+ "\u0000\u02a5\u02a3\u0001\u0000\u0000\u0000\u02a5\u02a6\u0001\u0000\u0000"+
+ "\u0000\u02a6\u02a7\u0001\u0000\u0000\u0000\u02a7\u02a8\u0005>\u0000\u0000"+
+ "\u02a8\u00b8\u0001\u0000\u0000\u0000\u02a9\u02aa\u0005u\u0000\u0000\u02aa"+
+ "\u02ad\u00058\u0000\u0000\u02ab\u02ad\u0007\u0011\u0000\u0000\u02ac\u02a9"+
+ "\u0001\u0000\u0000\u0000\u02ac\u02ab\u0001\u0000\u0000\u0000\u02ad\u00ba"+
+ "\u0001\u0000\u0000\u0000\u02ae\u02b0\u0003\u00bd^\u0000\u02af\u02ae\u0001"+
+ "\u0000\u0000\u0000\u02b0\u02b1\u0001\u0000\u0000\u0000\u02b1\u02af\u0001"+
+ "\u0000\u0000\u0000\u02b1\u02b2\u0001\u0000\u0000\u0000\u02b2\u00bc\u0001"+
+ "\u0000\u0000\u0000\u02b3\u02bb\b\u0012\u0000\u0000\u02b4\u02bb\u0003\u00ad"+
+ "V\u0000\u02b5\u02b6\u0005\\\u0000\u0000\u02b6\u02bb\u0005\n\u0000\u0000"+
+ "\u02b7\u02b8\u0005\\\u0000\u0000\u02b8\u02b9\u0005\r\u0000\u0000\u02b9"+
+ "\u02bb\u0005\n\u0000\u0000\u02ba\u02b3\u0001\u0000\u0000\u0000\u02ba\u02b4"+
+ "\u0001\u0000\u0000\u0000\u02ba\u02b5\u0001\u0000\u0000\u0000\u02ba\u02b7"+
+ "\u0001\u0000\u0000\u0000\u02bb\u00be\u0001\u0000\u0000\u0000\u02bc\u02bd"+
+ "\u0005#\u0000\u0000\u02bd\u02be\u0001\u0000\u0000\u0000\u02be\u02bf\u0006"+
+ "_\u0000\u0000\u02bf\u00c0\u0001\u0000\u0000\u0000\u02c0\u02c1\u0005@\u0000"+
+ "\u0000\u02c1\u02c2\u0001\u0000\u0000\u0000\u02c2\u02c3\u0006`\u0000\u0000"+
+ "\u02c3\u00c2\u0001\u0000\u0000\u0000\u02c4\u02c5\u0005$\u0000\u0000\u02c5"+
+ "\u02c6\u0001\u0000\u0000\u0000\u02c6\u02c7\u0006a\u0000\u0000\u02c7\u00c4"+
+ "\u0001\u0000\u0000\u0000\u02c8\u02c9\u0005a\u0000\u0000\u02c9\u02ca\u0005"+
+ "s\u0000\u0000\u02ca\u02cb\u0005m\u0000\u0000\u02cb\u02cf\u0001\u0000\u0000"+
+ "\u0000\u02cc\u02ce\b\u0013\u0000\u0000\u02cd\u02cc\u0001\u0000\u0000\u0000"+
+ "\u02ce\u02d1\u0001\u0000\u0000\u0000\u02cf\u02cd\u0001\u0000\u0000\u0000"+
+ "\u02cf\u02d0\u0001\u0000\u0000\u0000\u02d0\u02d2\u0001\u0000\u0000\u0000"+
+ "\u02d1\u02cf\u0001\u0000\u0000\u0000\u02d2\u02d6\u0005{\u0000\u0000\u02d3"+
+ "\u02d5\b\u0014\u0000\u0000\u02d4\u02d3\u0001\u0000\u0000\u0000\u02d5\u02d8"+
+ "\u0001\u0000\u0000\u0000\u02d6\u02d4\u0001\u0000\u0000\u0000\u02d6\u02d7"+
+ "\u0001\u0000\u0000\u0000\u02d7\u02d9\u0001\u0000\u0000\u0000\u02d8\u02d6"+
+ "\u0001\u0000\u0000\u0000\u02d9\u02da\u0005}\u0000\u0000\u02da\u02db\u0001"+
+ "\u0000\u0000\u0000\u02db\u02dc\u0006b\u0000\u0000\u02dc\u00c6\u0001\u0000"+
+ "\u0000\u0000\u02dd\u02df\u0007\u0015\u0000\u0000\u02de\u02dd\u0001\u0000"+
+ "\u0000\u0000\u02df\u02e0\u0001\u0000\u0000\u0000\u02e0\u02de\u0001\u0000"+
+ "\u0000\u0000\u02e0\u02e1\u0001\u0000\u0000\u0000\u02e1\u02e2\u0001\u0000"+
+ "\u0000\u0000\u02e2\u02e3\u0006c\u0000\u0000\u02e3\u00c8\u0001\u0000\u0000"+
+ "\u0000\u02e4\u02e6\u0005\r\u0000\u0000\u02e5\u02e7\u0005\n\u0000\u0000"+
+ "\u02e6\u02e5\u0001\u0000\u0000\u0000\u02e6\u02e7\u0001\u0000\u0000\u0000"+
+ "\u02e7\u02ea\u0001\u0000\u0000\u0000\u02e8\u02ea\u0005\n\u0000\u0000\u02e9"+
+ "\u02e4\u0001\u0000\u0000\u0000\u02e9\u02e8\u0001\u0000\u0000\u0000\u02ea"+
+ "\u02eb\u0001\u0000\u0000\u0000\u02eb\u02ec\u0006d\u0000\u0000\u02ec\u00ca"+
+ "\u0001\u0000\u0000\u0000\u02ed\u02ee\u0005/\u0000\u0000\u02ee\u02ef\u0005"+
+ "*\u0000\u0000\u02ef\u02f3\u0001\u0000\u0000\u0000\u02f0\u02f2\t\u0000"+
+ "\u0000\u0000\u02f1\u02f0\u0001\u0000\u0000\u0000\u02f2\u02f5\u0001\u0000"+
+ "\u0000\u0000\u02f3\u02f4\u0001\u0000\u0000\u0000\u02f3\u02f1\u0001\u0000"+
+ "\u0000\u0000\u02f4\u02f6\u0001\u0000\u0000\u0000\u02f5\u02f3\u0001\u0000"+
+ "\u0000\u0000\u02f6\u02f7\u0005*\u0000\u0000\u02f7\u02f8\u0005/\u0000\u0000"+
+ "\u02f8\u02f9\u0001\u0000\u0000\u0000\u02f9\u02fa\u0006e\u0000\u0000\u02fa"+
+ "\u00cc\u0001\u0000\u0000\u0000\u02fb\u02fc\u0005/\u0000\u0000\u02fc\u02fd"+
+ "\u0005*\u0000\u0000\u02fd\u0301\u0001\u0000\u0000\u0000\u02fe\u0300\b"+
+ "\u0016\u0000\u0000\u02ff\u02fe\u0001\u0000\u0000\u0000\u0300\u0303\u0001"+
+ "\u0000\u0000\u0000\u0301\u02ff\u0001\u0000\u0000\u0000\u0301\u0302\u0001"+
+ "\u0000\u0000\u0000\u0302\u0304\u0001\u0000\u0000\u0000\u0303\u0301\u0001"+
+ "\u0000\u0000\u0000\u0304\u0305\u0006f\u0000\u0000\u0305\u00ce\u0001\u0000"+
+ "\u0000\u0000\u0306\u0307\u0005/\u0000\u0000\u0307\u0308\u0005/\u0000\u0000"+
+ "\u0308\u030c\u0001\u0000\u0000\u0000\u0309\u030b\b\u0017\u0000\u0000\u030a"+
+ "\u0309\u0001\u0000\u0000\u0000\u030b\u030e\u0001\u0000\u0000\u0000\u030c"+
+ "\u030a\u0001\u0000\u0000\u0000\u030c\u030d\u0001\u0000\u0000\u0000\u030d"+
+ "\u030f\u0001\u0000\u0000\u0000\u030e\u030c\u0001\u0000\u0000\u0000\u030f"+
+ "\u0310\u0006g\u0000\u0000\u0310\u00d0\u0001\u0000\u0000\u00008\u0000\u01a1"+
+ "\u01a5\u01a7\u01ab\u01bb\u01c5\u01c9\u01cd\u01d1\u01d4\u01db\u01e1\u01e8"+
+ "\u01ef\u01fc\u0203\u0207\u0209\u0213\u0217\u021b\u021e\u0223\u0225\u022a"+
+ "\u022e\u0231\u0238\u023c\u0245\u0248\u024f\u0253\u025a\u0274\u0279\u027d"+
+ "\u0283\u028b\u028e\u0296\u0299\u029d\u02a5\u02ac\u02b1\u02ba\u02cf\u02d6"+
+ "\u02e0\u02e6\u02e9\u02f3\u0301\u030c\u0001\u0000\u0001\u0000";
+ public static final ATN _ATN =
+ new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+ static {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionLexer.tokens b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionLexer.tokens
new file mode 100644
index 000000000..c9106f241
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionLexer.tokens
@@ -0,0 +1,121 @@
+LeftParen=1
+RightParen=2
+LeftBracket=3
+RightBracket=4
+LeftBrace=5
+RightBrace=6
+Less=7
+LessEqual=8
+Greater=9
+GreaterEqual=10
+LeftShift=11
+RightShift=12
+Plus=13
+PlusPlus=14
+Minus=15
+MinusMinus=16
+Star=17
+Div=18
+Mod=19
+And=20
+Or=21
+AndAnd=22
+OrOr=23
+Caret=24
+Not=25
+Tilde=26
+Question=27
+Colon=28
+Semi=29
+Comma=30
+Assign=31
+StarAssign=32
+DivAssign=33
+ModAssign=34
+PlusAssign=35
+MinusAssign=36
+LeftShiftAssign=37
+RightShiftAssign=38
+AndAssign=39
+XorAssign=40
+OrAssign=41
+Equal=42
+NotEqual=43
+Arrow=44
+Dot=45
+Ellipsis=46
+HasAttribute=47
+HasCPPAttribute=48
+HasCAttribute=49
+HasBuiltin=50
+HasInclude=51
+Defined=52
+Identifier=53
+Constant=54
+DigitSequence=55
+StringLiteral=56
+PathLiteral=57
+NumberSign=58
+AtSign=59
+Dollar=60
+AsmBlock=61
+Whitespace=62
+Newline=63
+BlockComment=64
+OpenBlockComment=65
+LineComment=66
+'('=1
+')'=2
+'['=3
+']'=4
+'{'=5
+'}'=6
+'<'=7
+'<='=8
+'>'=9
+'>='=10
+'<<'=11
+'>>'=12
+'+'=13
+'++'=14
+'-'=15
+'--'=16
+'*'=17
+'/'=18
+'%'=19
+'&'=20
+'|'=21
+'&&'=22
+'||'=23
+'^'=24
+'!'=25
+'~'=26
+'?'=27
+':'=28
+';'=29
+','=30
+'='=31
+'*='=32
+'/='=33
+'%='=34
+'+='=35
+'-='=36
+'<<='=37
+'>>='=38
+'&='=39
+'^='=40
+'|='=41
+'=='=42
+'!='=43
+'->'=44
+'.'=45
+'...'=46
+'__has_attribute'=47
+'__has_cpp_attribute'=48
+'__has_c_attribute'=49
+'__has_builtin'=50
+'__has_include'=51
+'defined'=52
+'#'=58
+'@'=59
+'$'=60
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionListener.java b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionListener.java
new file mode 100644
index 000000000..8ef371937
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionListener.java
@@ -0,0 +1,230 @@
+// Generated from /home/alex/programming/DiffDetective/src/main/resources/grammars/CExpression.g4 by ANTLR 4.13.1
+package org.variantsync.diffdetective.feature.antlr;
+import org.antlr.v4.runtime.tree.ParseTreeListener;
+
+/**
+ * This interface defines a complete listener for a parse tree produced by
+ * {@link CExpressionParser}.
+ */
+public interface CExpressionListener extends ParseTreeListener {
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#expression}.
+ * @param ctx the parse tree
+ */
+ void enterExpression(CExpressionParser.ExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#expression}.
+ * @param ctx the parse tree
+ */
+ void exitExpression(CExpressionParser.ExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#conditionalExpression}.
+ * @param ctx the parse tree
+ */
+ void enterConditionalExpression(CExpressionParser.ConditionalExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#conditionalExpression}.
+ * @param ctx the parse tree
+ */
+ void exitConditionalExpression(CExpressionParser.ConditionalExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#primaryExpression}.
+ * @param ctx the parse tree
+ */
+ void enterPrimaryExpression(CExpressionParser.PrimaryExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#primaryExpression}.
+ * @param ctx the parse tree
+ */
+ void exitPrimaryExpression(CExpressionParser.PrimaryExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#specialOperator}.
+ * @param ctx the parse tree
+ */
+ void enterSpecialOperator(CExpressionParser.SpecialOperatorContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#specialOperator}.
+ * @param ctx the parse tree
+ */
+ void exitSpecialOperator(CExpressionParser.SpecialOperatorContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#specialOperatorArgument}.
+ * @param ctx the parse tree
+ */
+ void enterSpecialOperatorArgument(CExpressionParser.SpecialOperatorArgumentContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#specialOperatorArgument}.
+ * @param ctx the parse tree
+ */
+ void exitSpecialOperatorArgument(CExpressionParser.SpecialOperatorArgumentContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#unaryOperator}.
+ * @param ctx the parse tree
+ */
+ void enterUnaryOperator(CExpressionParser.UnaryOperatorContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#unaryOperator}.
+ * @param ctx the parse tree
+ */
+ void exitUnaryOperator(CExpressionParser.UnaryOperatorContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#namespaceExpression}.
+ * @param ctx the parse tree
+ */
+ void enterNamespaceExpression(CExpressionParser.NamespaceExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#namespaceExpression}.
+ * @param ctx the parse tree
+ */
+ void exitNamespaceExpression(CExpressionParser.NamespaceExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#multiplicativeExpression}.
+ * @param ctx the parse tree
+ */
+ void enterMultiplicativeExpression(CExpressionParser.MultiplicativeExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#multiplicativeExpression}.
+ * @param ctx the parse tree
+ */
+ void exitMultiplicativeExpression(CExpressionParser.MultiplicativeExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#additiveExpression}.
+ * @param ctx the parse tree
+ */
+ void enterAdditiveExpression(CExpressionParser.AdditiveExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#additiveExpression}.
+ * @param ctx the parse tree
+ */
+ void exitAdditiveExpression(CExpressionParser.AdditiveExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#shiftExpression}.
+ * @param ctx the parse tree
+ */
+ void enterShiftExpression(CExpressionParser.ShiftExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#shiftExpression}.
+ * @param ctx the parse tree
+ */
+ void exitShiftExpression(CExpressionParser.ShiftExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#relationalExpression}.
+ * @param ctx the parse tree
+ */
+ void enterRelationalExpression(CExpressionParser.RelationalExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#relationalExpression}.
+ * @param ctx the parse tree
+ */
+ void exitRelationalExpression(CExpressionParser.RelationalExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#equalityExpression}.
+ * @param ctx the parse tree
+ */
+ void enterEqualityExpression(CExpressionParser.EqualityExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#equalityExpression}.
+ * @param ctx the parse tree
+ */
+ void exitEqualityExpression(CExpressionParser.EqualityExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#andExpression}.
+ * @param ctx the parse tree
+ */
+ void enterAndExpression(CExpressionParser.AndExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#andExpression}.
+ * @param ctx the parse tree
+ */
+ void exitAndExpression(CExpressionParser.AndExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#exclusiveOrExpression}.
+ * @param ctx the parse tree
+ */
+ void enterExclusiveOrExpression(CExpressionParser.ExclusiveOrExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#exclusiveOrExpression}.
+ * @param ctx the parse tree
+ */
+ void exitExclusiveOrExpression(CExpressionParser.ExclusiveOrExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#inclusiveOrExpression}.
+ * @param ctx the parse tree
+ */
+ void enterInclusiveOrExpression(CExpressionParser.InclusiveOrExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#inclusiveOrExpression}.
+ * @param ctx the parse tree
+ */
+ void exitInclusiveOrExpression(CExpressionParser.InclusiveOrExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#logicalAndExpression}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalAndExpression(CExpressionParser.LogicalAndExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#logicalAndExpression}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalAndExpression(CExpressionParser.LogicalAndExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#logicalOrExpression}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalOrExpression(CExpressionParser.LogicalOrExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#logicalOrExpression}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalOrExpression(CExpressionParser.LogicalOrExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#logicalOperand}.
+ * @param ctx the parse tree
+ */
+ void enterLogicalOperand(CExpressionParser.LogicalOperandContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#logicalOperand}.
+ * @param ctx the parse tree
+ */
+ void exitLogicalOperand(CExpressionParser.LogicalOperandContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#macroExpression}.
+ * @param ctx the parse tree
+ */
+ void enterMacroExpression(CExpressionParser.MacroExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#macroExpression}.
+ * @param ctx the parse tree
+ */
+ void exitMacroExpression(CExpressionParser.MacroExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#argumentExpressionList}.
+ * @param ctx the parse tree
+ */
+ void enterArgumentExpressionList(CExpressionParser.ArgumentExpressionListContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#argumentExpressionList}.
+ * @param ctx the parse tree
+ */
+ void exitArgumentExpressionList(CExpressionParser.ArgumentExpressionListContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#assignmentExpression}.
+ * @param ctx the parse tree
+ */
+ void enterAssignmentExpression(CExpressionParser.AssignmentExpressionContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#assignmentExpression}.
+ * @param ctx the parse tree
+ */
+ void exitAssignmentExpression(CExpressionParser.AssignmentExpressionContext ctx);
+ /**
+ * Enter a parse tree produced by {@link CExpressionParser#assignmentOperator}.
+ * @param ctx the parse tree
+ */
+ void enterAssignmentOperator(CExpressionParser.AssignmentOperatorContext ctx);
+ /**
+ * Exit a parse tree produced by {@link CExpressionParser#assignmentOperator}.
+ * @param ctx the parse tree
+ */
+ void exitAssignmentOperator(CExpressionParser.AssignmentOperatorContext ctx);
+}
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionParser.java b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionParser.java
new file mode 100644
index 000000000..9ec96f811
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionParser.java
@@ -0,0 +1,2088 @@
+// Generated from /home/alex/programming/DiffDetective/src/main/resources/grammars/CExpression.g4 by ANTLR 4.13.1
+package org.variantsync.diffdetective.feature.antlr;
+import org.antlr.v4.runtime.atn.*;
+import org.antlr.v4.runtime.dfa.DFA;
+import org.antlr.v4.runtime.*;
+import org.antlr.v4.runtime.misc.*;
+import org.antlr.v4.runtime.tree.*;
+import java.util.List;
+import java.util.Iterator;
+import java.util.ArrayList;
+
+@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"})
+public class CExpressionParser extends Parser {
+ static { RuntimeMetaData.checkVersion("4.13.1", RuntimeMetaData.VERSION); }
+
+ protected static final DFA[] _decisionToDFA;
+ protected static final PredictionContextCache _sharedContextCache =
+ new PredictionContextCache();
+ public static final int
+ LeftParen=1, RightParen=2, LeftBracket=3, RightBracket=4, LeftBrace=5,
+ RightBrace=6, Less=7, LessEqual=8, Greater=9, GreaterEqual=10, LeftShift=11,
+ RightShift=12, Plus=13, PlusPlus=14, Minus=15, MinusMinus=16, Star=17,
+ Div=18, Mod=19, And=20, Or=21, AndAnd=22, OrOr=23, Caret=24, Not=25, Tilde=26,
+ Question=27, Colon=28, Semi=29, Comma=30, Assign=31, StarAssign=32, DivAssign=33,
+ ModAssign=34, PlusAssign=35, MinusAssign=36, LeftShiftAssign=37, RightShiftAssign=38,
+ AndAssign=39, XorAssign=40, OrAssign=41, Equal=42, NotEqual=43, Arrow=44,
+ Dot=45, Ellipsis=46, HasAttribute=47, HasCPPAttribute=48, HasCAttribute=49,
+ HasBuiltin=50, HasInclude=51, Defined=52, Identifier=53, Constant=54,
+ DigitSequence=55, StringLiteral=56, PathLiteral=57, NumberSign=58, AtSign=59,
+ Dollar=60, AsmBlock=61, Whitespace=62, Newline=63, BlockComment=64, OpenBlockComment=65,
+ LineComment=66;
+ public static final int
+ RULE_expression = 0, RULE_conditionalExpression = 1, RULE_primaryExpression = 2,
+ RULE_specialOperator = 3, RULE_specialOperatorArgument = 4, RULE_unaryOperator = 5,
+ RULE_namespaceExpression = 6, RULE_multiplicativeExpression = 7, RULE_additiveExpression = 8,
+ RULE_shiftExpression = 9, RULE_relationalExpression = 10, RULE_equalityExpression = 11,
+ RULE_andExpression = 12, RULE_exclusiveOrExpression = 13, RULE_inclusiveOrExpression = 14,
+ RULE_logicalAndExpression = 15, RULE_logicalOrExpression = 16, RULE_logicalOperand = 17,
+ RULE_macroExpression = 18, RULE_argumentExpressionList = 19, RULE_assignmentExpression = 20,
+ RULE_assignmentOperator = 21;
+ private static String[] makeRuleNames() {
+ return new String[] {
+ "expression", "conditionalExpression", "primaryExpression", "specialOperator",
+ "specialOperatorArgument", "unaryOperator", "namespaceExpression", "multiplicativeExpression",
+ "additiveExpression", "shiftExpression", "relationalExpression", "equalityExpression",
+ "andExpression", "exclusiveOrExpression", "inclusiveOrExpression", "logicalAndExpression",
+ "logicalOrExpression", "logicalOperand", "macroExpression", "argumentExpressionList",
+ "assignmentExpression", "assignmentOperator"
+ };
+ }
+ public static final String[] ruleNames = makeRuleNames();
+
+ private static String[] makeLiteralNames() {
+ return new String[] {
+ null, "'('", "')'", "'['", "']'", "'{'", "'}'", "'<'", "'<='", "'>'",
+ "'>='", "'<<'", "'>>'", "'+'", "'++'", "'-'", "'--'", "'*'", "'/'", "'%'",
+ "'&'", "'|'", "'&&'", "'||'", "'^'", "'!'", "'~'", "'?'", "':'", "';'",
+ "','", "'='", "'*='", "'/='", "'%='", "'+='", "'-='", "'<<='", "'>>='",
+ "'&='", "'^='", "'|='", "'=='", "'!='", "'->'", "'.'", "'...'", "'__has_attribute'",
+ "'__has_cpp_attribute'", "'__has_c_attribute'", "'__has_builtin'", "'__has_include'",
+ "'defined'", null, null, null, null, null, "'#'", "'@'", "'$'"
+ };
+ }
+ private static final String[] _LITERAL_NAMES = makeLiteralNames();
+ private static String[] makeSymbolicNames() {
+ return new String[] {
+ null, "LeftParen", "RightParen", "LeftBracket", "RightBracket", "LeftBrace",
+ "RightBrace", "Less", "LessEqual", "Greater", "GreaterEqual", "LeftShift",
+ "RightShift", "Plus", "PlusPlus", "Minus", "MinusMinus", "Star", "Div",
+ "Mod", "And", "Or", "AndAnd", "OrOr", "Caret", "Not", "Tilde", "Question",
+ "Colon", "Semi", "Comma", "Assign", "StarAssign", "DivAssign", "ModAssign",
+ "PlusAssign", "MinusAssign", "LeftShiftAssign", "RightShiftAssign", "AndAssign",
+ "XorAssign", "OrAssign", "Equal", "NotEqual", "Arrow", "Dot", "Ellipsis",
+ "HasAttribute", "HasCPPAttribute", "HasCAttribute", "HasBuiltin", "HasInclude",
+ "Defined", "Identifier", "Constant", "DigitSequence", "StringLiteral",
+ "PathLiteral", "NumberSign", "AtSign", "Dollar", "AsmBlock", "Whitespace",
+ "Newline", "BlockComment", "OpenBlockComment", "LineComment"
+ };
+ }
+ private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
+ public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
+
+ /**
+ * @deprecated Use {@link #VOCABULARY} instead.
+ */
+ @Deprecated
+ public static final String[] tokenNames;
+ static {
+ tokenNames = new String[_SYMBOLIC_NAMES.length];
+ for (int i = 0; i < tokenNames.length; i++) {
+ tokenNames[i] = VOCABULARY.getLiteralName(i);
+ if (tokenNames[i] == null) {
+ tokenNames[i] = VOCABULARY.getSymbolicName(i);
+ }
+
+ if (tokenNames[i] == null) {
+ tokenNames[i] = "";
+ }
+ }
+ }
+
+ @Override
+ @Deprecated
+ public String[] getTokenNames() {
+ return tokenNames;
+ }
+
+ @Override
+
+ public Vocabulary getVocabulary() {
+ return VOCABULARY;
+ }
+
+ @Override
+ public String getGrammarFileName() { return "CExpression.g4"; }
+
+ @Override
+ public String[] getRuleNames() { return ruleNames; }
+
+ @Override
+ public String getSerializedATN() { return _serializedATN; }
+
+ @Override
+ public ATN getATN() { return _ATN; }
+
+ public CExpressionParser(TokenStream input) {
+ super(input);
+ _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class ExpressionContext extends ParserRuleContext {
+ public List assignmentExpression() {
+ return getRuleContexts(AssignmentExpressionContext.class);
+ }
+ public AssignmentExpressionContext assignmentExpression(int i) {
+ return getRuleContext(AssignmentExpressionContext.class,i);
+ }
+ public List Comma() { return getTokens(CExpressionParser.Comma); }
+ public TerminalNode Comma(int i) {
+ return getToken(CExpressionParser.Comma, i);
+ }
+ public ExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_expression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final ExpressionContext expression() throws RecognitionException {
+ ExpressionContext _localctx = new ExpressionContext(_ctx, getState());
+ enterRule(_localctx, 0, RULE_expression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(44);
+ assignmentExpression();
+ setState(49);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==Comma) {
+ {
+ {
+ setState(45);
+ match(Comma);
+ setState(46);
+ assignmentExpression();
+ }
+ }
+ setState(51);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class ConditionalExpressionContext extends ParserRuleContext {
+ public LogicalOrExpressionContext logicalOrExpression() {
+ return getRuleContext(LogicalOrExpressionContext.class,0);
+ }
+ public TerminalNode Question() { return getToken(CExpressionParser.Question, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public TerminalNode Colon() { return getToken(CExpressionParser.Colon, 0); }
+ public ConditionalExpressionContext conditionalExpression() {
+ return getRuleContext(ConditionalExpressionContext.class,0);
+ }
+ public ConditionalExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_conditionalExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterConditionalExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitConditionalExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitConditionalExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final ConditionalExpressionContext conditionalExpression() throws RecognitionException {
+ ConditionalExpressionContext _localctx = new ConditionalExpressionContext(_ctx, getState());
+ enterRule(_localctx, 2, RULE_conditionalExpression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(52);
+ logicalOrExpression();
+ setState(58);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ if (_la==Question) {
+ {
+ setState(53);
+ match(Question);
+ setState(54);
+ expression();
+ setState(55);
+ match(Colon);
+ setState(56);
+ conditionalExpression();
+ }
+ }
+
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class PrimaryExpressionContext extends ParserRuleContext {
+ public MacroExpressionContext macroExpression() {
+ return getRuleContext(MacroExpressionContext.class,0);
+ }
+ public TerminalNode Identifier() { return getToken(CExpressionParser.Identifier, 0); }
+ public TerminalNode Constant() { return getToken(CExpressionParser.Constant, 0); }
+ public List StringLiteral() { return getTokens(CExpressionParser.StringLiteral); }
+ public TerminalNode StringLiteral(int i) {
+ return getToken(CExpressionParser.StringLiteral, i);
+ }
+ public TerminalNode LeftParen() { return getToken(CExpressionParser.LeftParen, 0); }
+ public ExpressionContext expression() {
+ return getRuleContext(ExpressionContext.class,0);
+ }
+ public TerminalNode RightParen() { return getToken(CExpressionParser.RightParen, 0); }
+ public UnaryOperatorContext unaryOperator() {
+ return getRuleContext(UnaryOperatorContext.class,0);
+ }
+ public PrimaryExpressionContext primaryExpression() {
+ return getRuleContext(PrimaryExpressionContext.class,0);
+ }
+ public SpecialOperatorContext specialOperator() {
+ return getRuleContext(SpecialOperatorContext.class,0);
+ }
+ public PrimaryExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_primaryExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterPrimaryExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitPrimaryExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitPrimaryExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final PrimaryExpressionContext primaryExpression() throws RecognitionException {
+ PrimaryExpressionContext _localctx = new PrimaryExpressionContext(_ctx, getState());
+ enterRule(_localctx, 4, RULE_primaryExpression);
+ try {
+ int _alt;
+ setState(76);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,3,_ctx) ) {
+ case 1:
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(60);
+ macroExpression();
+ }
+ break;
+ case 2:
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(61);
+ match(Identifier);
+ }
+ break;
+ case 3:
+ enterOuterAlt(_localctx, 3);
+ {
+ setState(62);
+ match(Constant);
+ }
+ break;
+ case 4:
+ enterOuterAlt(_localctx, 4);
+ {
+ setState(64);
+ _errHandler.sync(this);
+ _alt = 1;
+ do {
+ switch (_alt) {
+ case 1:
+ {
+ {
+ setState(63);
+ match(StringLiteral);
+ }
+ }
+ break;
+ default:
+ throw new NoViableAltException(this);
+ }
+ setState(66);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,2,_ctx);
+ } while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER );
+ }
+ break;
+ case 5:
+ enterOuterAlt(_localctx, 5);
+ {
+ setState(68);
+ match(LeftParen);
+ setState(69);
+ expression();
+ setState(70);
+ match(RightParen);
+ }
+ break;
+ case 6:
+ enterOuterAlt(_localctx, 6);
+ {
+ setState(72);
+ unaryOperator();
+ setState(73);
+ primaryExpression();
+ }
+ break;
+ case 7:
+ enterOuterAlt(_localctx, 7);
+ {
+ setState(75);
+ specialOperator();
+ }
+ break;
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class SpecialOperatorContext extends ParserRuleContext {
+ public TerminalNode HasAttribute() { return getToken(CExpressionParser.HasAttribute, 0); }
+ public TerminalNode LeftParen() { return getToken(CExpressionParser.LeftParen, 0); }
+ public SpecialOperatorArgumentContext specialOperatorArgument() {
+ return getRuleContext(SpecialOperatorArgumentContext.class,0);
+ }
+ public TerminalNode RightParen() { return getToken(CExpressionParser.RightParen, 0); }
+ public TerminalNode HasCPPAttribute() { return getToken(CExpressionParser.HasCPPAttribute, 0); }
+ public TerminalNode HasCAttribute() { return getToken(CExpressionParser.HasCAttribute, 0); }
+ public TerminalNode HasBuiltin() { return getToken(CExpressionParser.HasBuiltin, 0); }
+ public TerminalNode HasInclude() { return getToken(CExpressionParser.HasInclude, 0); }
+ public TerminalNode Defined() { return getToken(CExpressionParser.Defined, 0); }
+ public SpecialOperatorContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_specialOperator; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterSpecialOperator(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitSpecialOperator(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitSpecialOperator(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final SpecialOperatorContext specialOperator() throws RecognitionException {
+ SpecialOperatorContext _localctx = new SpecialOperatorContext(_ctx, getState());
+ enterRule(_localctx, 6, RULE_specialOperator);
+ try {
+ setState(122);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,10,_ctx) ) {
+ case 1:
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(78);
+ match(HasAttribute);
+ setState(83);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,4,_ctx) ) {
+ case 1:
+ {
+ setState(79);
+ match(LeftParen);
+ setState(80);
+ specialOperatorArgument();
+ setState(81);
+ match(RightParen);
+ }
+ break;
+ }
+ }
+ break;
+ case 2:
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(85);
+ match(HasCPPAttribute);
+ setState(90);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,5,_ctx) ) {
+ case 1:
+ {
+ setState(86);
+ match(LeftParen);
+ setState(87);
+ specialOperatorArgument();
+ setState(88);
+ match(RightParen);
+ }
+ break;
+ }
+ }
+ break;
+ case 3:
+ enterOuterAlt(_localctx, 3);
+ {
+ setState(92);
+ match(HasCAttribute);
+ setState(97);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,6,_ctx) ) {
+ case 1:
+ {
+ setState(93);
+ match(LeftParen);
+ setState(94);
+ specialOperatorArgument();
+ setState(95);
+ match(RightParen);
+ }
+ break;
+ }
+ }
+ break;
+ case 4:
+ enterOuterAlt(_localctx, 4);
+ {
+ setState(99);
+ match(HasBuiltin);
+ setState(104);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,7,_ctx) ) {
+ case 1:
+ {
+ setState(100);
+ match(LeftParen);
+ setState(101);
+ specialOperatorArgument();
+ setState(102);
+ match(RightParen);
+ }
+ break;
+ }
+ }
+ break;
+ case 5:
+ enterOuterAlt(_localctx, 5);
+ {
+ setState(106);
+ match(HasInclude);
+ setState(111);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,8,_ctx) ) {
+ case 1:
+ {
+ setState(107);
+ match(LeftParen);
+ setState(108);
+ specialOperatorArgument();
+ setState(109);
+ match(RightParen);
+ }
+ break;
+ }
+ }
+ break;
+ case 6:
+ enterOuterAlt(_localctx, 6);
+ {
+ setState(113);
+ match(Defined);
+ {
+ setState(114);
+ match(LeftParen);
+ setState(115);
+ specialOperatorArgument();
+ setState(116);
+ match(RightParen);
+ }
+ }
+ break;
+ case 7:
+ enterOuterAlt(_localctx, 7);
+ {
+ setState(118);
+ match(Defined);
+ setState(120);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,9,_ctx) ) {
+ case 1:
+ {
+ setState(119);
+ specialOperatorArgument();
+ }
+ break;
+ }
+ }
+ break;
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class SpecialOperatorArgumentContext extends ParserRuleContext {
+ public TerminalNode HasAttribute() { return getToken(CExpressionParser.HasAttribute, 0); }
+ public TerminalNode HasCPPAttribute() { return getToken(CExpressionParser.HasCPPAttribute, 0); }
+ public TerminalNode HasCAttribute() { return getToken(CExpressionParser.HasCAttribute, 0); }
+ public TerminalNode HasBuiltin() { return getToken(CExpressionParser.HasBuiltin, 0); }
+ public TerminalNode HasInclude() { return getToken(CExpressionParser.HasInclude, 0); }
+ public TerminalNode Defined() { return getToken(CExpressionParser.Defined, 0); }
+ public TerminalNode Identifier() { return getToken(CExpressionParser.Identifier, 0); }
+ public TerminalNode PathLiteral() { return getToken(CExpressionParser.PathLiteral, 0); }
+ public TerminalNode StringLiteral() { return getToken(CExpressionParser.StringLiteral, 0); }
+ public SpecialOperatorArgumentContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_specialOperatorArgument; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterSpecialOperatorArgument(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitSpecialOperatorArgument(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitSpecialOperatorArgument(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final SpecialOperatorArgumentContext specialOperatorArgument() throws RecognitionException {
+ SpecialOperatorArgumentContext _localctx = new SpecialOperatorArgumentContext(_ctx, getState());
+ enterRule(_localctx, 8, RULE_specialOperatorArgument);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(124);
+ _la = _input.LA(1);
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 234046443134910464L) != 0)) ) {
+ _errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class UnaryOperatorContext extends ParserRuleContext {
+ public TerminalNode And() { return getToken(CExpressionParser.And, 0); }
+ public TerminalNode Star() { return getToken(CExpressionParser.Star, 0); }
+ public TerminalNode Plus() { return getToken(CExpressionParser.Plus, 0); }
+ public TerminalNode Minus() { return getToken(CExpressionParser.Minus, 0); }
+ public TerminalNode Tilde() { return getToken(CExpressionParser.Tilde, 0); }
+ public TerminalNode Not() { return getToken(CExpressionParser.Not, 0); }
+ public UnaryOperatorContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_unaryOperator; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterUnaryOperator(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitUnaryOperator(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitUnaryOperator(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final UnaryOperatorContext unaryOperator() throws RecognitionException {
+ UnaryOperatorContext _localctx = new UnaryOperatorContext(_ctx, getState());
+ enterRule(_localctx, 10, RULE_unaryOperator);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(126);
+ _la = _input.LA(1);
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 101883904L) != 0)) ) {
+ _errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class NamespaceExpressionContext extends ParserRuleContext {
+ public List primaryExpression() {
+ return getRuleContexts(PrimaryExpressionContext.class);
+ }
+ public PrimaryExpressionContext primaryExpression(int i) {
+ return getRuleContext(PrimaryExpressionContext.class,i);
+ }
+ public List Colon() { return getTokens(CExpressionParser.Colon); }
+ public TerminalNode Colon(int i) {
+ return getToken(CExpressionParser.Colon, i);
+ }
+ public NamespaceExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_namespaceExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterNamespaceExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitNamespaceExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitNamespaceExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final NamespaceExpressionContext namespaceExpression() throws RecognitionException {
+ NamespaceExpressionContext _localctx = new NamespaceExpressionContext(_ctx, getState());
+ enterRule(_localctx, 12, RULE_namespaceExpression);
+ try {
+ int _alt;
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(128);
+ primaryExpression();
+ setState(133);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,11,_ctx);
+ while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+ if ( _alt==1 ) {
+ {
+ {
+ setState(129);
+ match(Colon);
+ setState(130);
+ primaryExpression();
+ }
+ }
+ }
+ setState(135);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,11,_ctx);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class MultiplicativeExpressionContext extends ParserRuleContext {
+ public List namespaceExpression() {
+ return getRuleContexts(NamespaceExpressionContext.class);
+ }
+ public NamespaceExpressionContext namespaceExpression(int i) {
+ return getRuleContext(NamespaceExpressionContext.class,i);
+ }
+ public List Star() { return getTokens(CExpressionParser.Star); }
+ public TerminalNode Star(int i) {
+ return getToken(CExpressionParser.Star, i);
+ }
+ public List Div() { return getTokens(CExpressionParser.Div); }
+ public TerminalNode Div(int i) {
+ return getToken(CExpressionParser.Div, i);
+ }
+ public List Mod() { return getTokens(CExpressionParser.Mod); }
+ public TerminalNode Mod(int i) {
+ return getToken(CExpressionParser.Mod, i);
+ }
+ public MultiplicativeExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_multiplicativeExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterMultiplicativeExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitMultiplicativeExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitMultiplicativeExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final MultiplicativeExpressionContext multiplicativeExpression() throws RecognitionException {
+ MultiplicativeExpressionContext _localctx = new MultiplicativeExpressionContext(_ctx, getState());
+ enterRule(_localctx, 14, RULE_multiplicativeExpression);
+ int _la;
+ try {
+ int _alt;
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(136);
+ namespaceExpression();
+ setState(141);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,12,_ctx);
+ while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+ if ( _alt==1 ) {
+ {
+ {
+ setState(137);
+ _la = _input.LA(1);
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 917504L) != 0)) ) {
+ _errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ setState(138);
+ namespaceExpression();
+ }
+ }
+ }
+ setState(143);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,12,_ctx);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class AdditiveExpressionContext extends ParserRuleContext {
+ public List multiplicativeExpression() {
+ return getRuleContexts(MultiplicativeExpressionContext.class);
+ }
+ public MultiplicativeExpressionContext multiplicativeExpression(int i) {
+ return getRuleContext(MultiplicativeExpressionContext.class,i);
+ }
+ public List Plus() { return getTokens(CExpressionParser.Plus); }
+ public TerminalNode Plus(int i) {
+ return getToken(CExpressionParser.Plus, i);
+ }
+ public List Minus() { return getTokens(CExpressionParser.Minus); }
+ public TerminalNode Minus(int i) {
+ return getToken(CExpressionParser.Minus, i);
+ }
+ public AdditiveExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_additiveExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterAdditiveExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitAdditiveExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitAdditiveExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final AdditiveExpressionContext additiveExpression() throws RecognitionException {
+ AdditiveExpressionContext _localctx = new AdditiveExpressionContext(_ctx, getState());
+ enterRule(_localctx, 16, RULE_additiveExpression);
+ int _la;
+ try {
+ int _alt;
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(144);
+ multiplicativeExpression();
+ setState(149);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,13,_ctx);
+ while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+ if ( _alt==1 ) {
+ {
+ {
+ setState(145);
+ _la = _input.LA(1);
+ if ( !(_la==Plus || _la==Minus) ) {
+ _errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ setState(146);
+ multiplicativeExpression();
+ }
+ }
+ }
+ setState(151);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,13,_ctx);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class ShiftExpressionContext extends ParserRuleContext {
+ public List additiveExpression() {
+ return getRuleContexts(AdditiveExpressionContext.class);
+ }
+ public AdditiveExpressionContext additiveExpression(int i) {
+ return getRuleContext(AdditiveExpressionContext.class,i);
+ }
+ public List LeftShift() { return getTokens(CExpressionParser.LeftShift); }
+ public TerminalNode LeftShift(int i) {
+ return getToken(CExpressionParser.LeftShift, i);
+ }
+ public List RightShift() { return getTokens(CExpressionParser.RightShift); }
+ public TerminalNode RightShift(int i) {
+ return getToken(CExpressionParser.RightShift, i);
+ }
+ public ShiftExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_shiftExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterShiftExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitShiftExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitShiftExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final ShiftExpressionContext shiftExpression() throws RecognitionException {
+ ShiftExpressionContext _localctx = new ShiftExpressionContext(_ctx, getState());
+ enterRule(_localctx, 18, RULE_shiftExpression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(152);
+ additiveExpression();
+ setState(157);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==LeftShift || _la==RightShift) {
+ {
+ {
+ setState(153);
+ _la = _input.LA(1);
+ if ( !(_la==LeftShift || _la==RightShift) ) {
+ _errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ setState(154);
+ additiveExpression();
+ }
+ }
+ setState(159);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class RelationalExpressionContext extends ParserRuleContext {
+ public List shiftExpression() {
+ return getRuleContexts(ShiftExpressionContext.class);
+ }
+ public ShiftExpressionContext shiftExpression(int i) {
+ return getRuleContext(ShiftExpressionContext.class,i);
+ }
+ public List Less() { return getTokens(CExpressionParser.Less); }
+ public TerminalNode Less(int i) {
+ return getToken(CExpressionParser.Less, i);
+ }
+ public List Greater() { return getTokens(CExpressionParser.Greater); }
+ public TerminalNode Greater(int i) {
+ return getToken(CExpressionParser.Greater, i);
+ }
+ public List LessEqual() { return getTokens(CExpressionParser.LessEqual); }
+ public TerminalNode LessEqual(int i) {
+ return getToken(CExpressionParser.LessEqual, i);
+ }
+ public List GreaterEqual() { return getTokens(CExpressionParser.GreaterEqual); }
+ public TerminalNode GreaterEqual(int i) {
+ return getToken(CExpressionParser.GreaterEqual, i);
+ }
+ public RelationalExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_relationalExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterRelationalExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitRelationalExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitRelationalExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final RelationalExpressionContext relationalExpression() throws RecognitionException {
+ RelationalExpressionContext _localctx = new RelationalExpressionContext(_ctx, getState());
+ enterRule(_localctx, 20, RULE_relationalExpression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(160);
+ shiftExpression();
+ setState(165);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while ((((_la) & ~0x3f) == 0 && ((1L << _la) & 1920L) != 0)) {
+ {
+ {
+ setState(161);
+ _la = _input.LA(1);
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 1920L) != 0)) ) {
+ _errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ setState(162);
+ shiftExpression();
+ }
+ }
+ setState(167);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class EqualityExpressionContext extends ParserRuleContext {
+ public List relationalExpression() {
+ return getRuleContexts(RelationalExpressionContext.class);
+ }
+ public RelationalExpressionContext relationalExpression(int i) {
+ return getRuleContext(RelationalExpressionContext.class,i);
+ }
+ public List Equal() { return getTokens(CExpressionParser.Equal); }
+ public TerminalNode Equal(int i) {
+ return getToken(CExpressionParser.Equal, i);
+ }
+ public List NotEqual() { return getTokens(CExpressionParser.NotEqual); }
+ public TerminalNode NotEqual(int i) {
+ return getToken(CExpressionParser.NotEqual, i);
+ }
+ public EqualityExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_equalityExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterEqualityExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitEqualityExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitEqualityExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final EqualityExpressionContext equalityExpression() throws RecognitionException {
+ EqualityExpressionContext _localctx = new EqualityExpressionContext(_ctx, getState());
+ enterRule(_localctx, 22, RULE_equalityExpression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(168);
+ relationalExpression();
+ setState(173);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==Equal || _la==NotEqual) {
+ {
+ {
+ setState(169);
+ _la = _input.LA(1);
+ if ( !(_la==Equal || _la==NotEqual) ) {
+ _errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ setState(170);
+ relationalExpression();
+ }
+ }
+ setState(175);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class AndExpressionContext extends ParserRuleContext {
+ public List equalityExpression() {
+ return getRuleContexts(EqualityExpressionContext.class);
+ }
+ public EqualityExpressionContext equalityExpression(int i) {
+ return getRuleContext(EqualityExpressionContext.class,i);
+ }
+ public List And() { return getTokens(CExpressionParser.And); }
+ public TerminalNode And(int i) {
+ return getToken(CExpressionParser.And, i);
+ }
+ public AndExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_andExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterAndExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitAndExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitAndExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final AndExpressionContext andExpression() throws RecognitionException {
+ AndExpressionContext _localctx = new AndExpressionContext(_ctx, getState());
+ enterRule(_localctx, 24, RULE_andExpression);
+ try {
+ int _alt;
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(176);
+ equalityExpression();
+ setState(181);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,17,_ctx);
+ while ( _alt!=2 && _alt!=org.antlr.v4.runtime.atn.ATN.INVALID_ALT_NUMBER ) {
+ if ( _alt==1 ) {
+ {
+ {
+ setState(177);
+ match(And);
+ setState(178);
+ equalityExpression();
+ }
+ }
+ }
+ setState(183);
+ _errHandler.sync(this);
+ _alt = getInterpreter().adaptivePredict(_input,17,_ctx);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class ExclusiveOrExpressionContext extends ParserRuleContext {
+ public List andExpression() {
+ return getRuleContexts(AndExpressionContext.class);
+ }
+ public AndExpressionContext andExpression(int i) {
+ return getRuleContext(AndExpressionContext.class,i);
+ }
+ public List Caret() { return getTokens(CExpressionParser.Caret); }
+ public TerminalNode Caret(int i) {
+ return getToken(CExpressionParser.Caret, i);
+ }
+ public ExclusiveOrExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_exclusiveOrExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterExclusiveOrExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitExclusiveOrExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitExclusiveOrExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final ExclusiveOrExpressionContext exclusiveOrExpression() throws RecognitionException {
+ ExclusiveOrExpressionContext _localctx = new ExclusiveOrExpressionContext(_ctx, getState());
+ enterRule(_localctx, 26, RULE_exclusiveOrExpression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(184);
+ andExpression();
+ setState(189);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==Caret) {
+ {
+ {
+ setState(185);
+ match(Caret);
+ setState(186);
+ andExpression();
+ }
+ }
+ setState(191);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class InclusiveOrExpressionContext extends ParserRuleContext {
+ public List exclusiveOrExpression() {
+ return getRuleContexts(ExclusiveOrExpressionContext.class);
+ }
+ public ExclusiveOrExpressionContext exclusiveOrExpression(int i) {
+ return getRuleContext(ExclusiveOrExpressionContext.class,i);
+ }
+ public List Or() { return getTokens(CExpressionParser.Or); }
+ public TerminalNode Or(int i) {
+ return getToken(CExpressionParser.Or, i);
+ }
+ public InclusiveOrExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_inclusiveOrExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterInclusiveOrExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitInclusiveOrExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitInclusiveOrExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final InclusiveOrExpressionContext inclusiveOrExpression() throws RecognitionException {
+ InclusiveOrExpressionContext _localctx = new InclusiveOrExpressionContext(_ctx, getState());
+ enterRule(_localctx, 28, RULE_inclusiveOrExpression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(192);
+ exclusiveOrExpression();
+ setState(197);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==Or) {
+ {
+ {
+ setState(193);
+ match(Or);
+ setState(194);
+ exclusiveOrExpression();
+ }
+ }
+ setState(199);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class LogicalAndExpressionContext extends ParserRuleContext {
+ public List logicalOperand() {
+ return getRuleContexts(LogicalOperandContext.class);
+ }
+ public LogicalOperandContext logicalOperand(int i) {
+ return getRuleContext(LogicalOperandContext.class,i);
+ }
+ public List AndAnd() { return getTokens(CExpressionParser.AndAnd); }
+ public TerminalNode AndAnd(int i) {
+ return getToken(CExpressionParser.AndAnd, i);
+ }
+ public LogicalAndExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_logicalAndExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterLogicalAndExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitLogicalAndExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitLogicalAndExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final LogicalAndExpressionContext logicalAndExpression() throws RecognitionException {
+ LogicalAndExpressionContext _localctx = new LogicalAndExpressionContext(_ctx, getState());
+ enterRule(_localctx, 30, RULE_logicalAndExpression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(200);
+ logicalOperand();
+ setState(205);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==AndAnd) {
+ {
+ {
+ setState(201);
+ match(AndAnd);
+ setState(202);
+ logicalOperand();
+ }
+ }
+ setState(207);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class LogicalOrExpressionContext extends ParserRuleContext {
+ public List logicalAndExpression() {
+ return getRuleContexts(LogicalAndExpressionContext.class);
+ }
+ public LogicalAndExpressionContext logicalAndExpression(int i) {
+ return getRuleContext(LogicalAndExpressionContext.class,i);
+ }
+ public List OrOr() { return getTokens(CExpressionParser.OrOr); }
+ public TerminalNode OrOr(int i) {
+ return getToken(CExpressionParser.OrOr, i);
+ }
+ public LogicalOrExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_logicalOrExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterLogicalOrExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitLogicalOrExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitLogicalOrExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final LogicalOrExpressionContext logicalOrExpression() throws RecognitionException {
+ LogicalOrExpressionContext _localctx = new LogicalOrExpressionContext(_ctx, getState());
+ enterRule(_localctx, 32, RULE_logicalOrExpression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(208);
+ logicalAndExpression();
+ setState(213);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==OrOr) {
+ {
+ {
+ setState(209);
+ match(OrOr);
+ setState(210);
+ logicalAndExpression();
+ }
+ }
+ setState(215);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class LogicalOperandContext extends ParserRuleContext {
+ public InclusiveOrExpressionContext inclusiveOrExpression() {
+ return getRuleContext(InclusiveOrExpressionContext.class,0);
+ }
+ public LogicalOperandContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_logicalOperand; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterLogicalOperand(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitLogicalOperand(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitLogicalOperand(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final LogicalOperandContext logicalOperand() throws RecognitionException {
+ LogicalOperandContext _localctx = new LogicalOperandContext(_ctx, getState());
+ enterRule(_localctx, 34, RULE_logicalOperand);
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(216);
+ inclusiveOrExpression();
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class MacroExpressionContext extends ParserRuleContext {
+ public TerminalNode Identifier() { return getToken(CExpressionParser.Identifier, 0); }
+ public TerminalNode LeftParen() { return getToken(CExpressionParser.LeftParen, 0); }
+ public TerminalNode RightParen() { return getToken(CExpressionParser.RightParen, 0); }
+ public ArgumentExpressionListContext argumentExpressionList() {
+ return getRuleContext(ArgumentExpressionListContext.class,0);
+ }
+ public MacroExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_macroExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterMacroExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitMacroExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitMacroExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final MacroExpressionContext macroExpression() throws RecognitionException {
+ MacroExpressionContext _localctx = new MacroExpressionContext(_ctx, getState());
+ enterRule(_localctx, 36, RULE_macroExpression);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(218);
+ match(Identifier);
+ setState(219);
+ match(LeftParen);
+ setState(221);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ if ((((_la) & ~0x3f) == 0 && ((1L << _la) & 288089638765240322L) != 0)) {
+ {
+ setState(220);
+ argumentExpressionList();
+ }
+ }
+
+ setState(223);
+ match(RightParen);
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class ArgumentExpressionListContext extends ParserRuleContext {
+ public List assignmentExpression() {
+ return getRuleContexts(AssignmentExpressionContext.class);
+ }
+ public AssignmentExpressionContext assignmentExpression(int i) {
+ return getRuleContext(AssignmentExpressionContext.class,i);
+ }
+ public List Comma() { return getTokens(CExpressionParser.Comma); }
+ public TerminalNode Comma(int i) {
+ return getToken(CExpressionParser.Comma, i);
+ }
+ public ArgumentExpressionListContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_argumentExpressionList; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterArgumentExpressionList(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitArgumentExpressionList(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitArgumentExpressionList(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final ArgumentExpressionListContext argumentExpressionList() throws RecognitionException {
+ ArgumentExpressionListContext _localctx = new ArgumentExpressionListContext(_ctx, getState());
+ enterRule(_localctx, 38, RULE_argumentExpressionList);
+ int _la;
+ try {
+ setState(240);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,25,_ctx) ) {
+ case 1:
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(225);
+ assignmentExpression();
+ setState(230);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while (_la==Comma) {
+ {
+ {
+ setState(226);
+ match(Comma);
+ setState(227);
+ assignmentExpression();
+ }
+ }
+ setState(232);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ break;
+ case 2:
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(233);
+ assignmentExpression();
+ setState(237);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ while ((((_la) & ~0x3f) == 0 && ((1L << _la) & 288089638765240322L) != 0)) {
+ {
+ {
+ setState(234);
+ assignmentExpression();
+ }
+ }
+ setState(239);
+ _errHandler.sync(this);
+ _la = _input.LA(1);
+ }
+ }
+ break;
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class AssignmentExpressionContext extends ParserRuleContext {
+ public ConditionalExpressionContext conditionalExpression() {
+ return getRuleContext(ConditionalExpressionContext.class,0);
+ }
+ public TerminalNode DigitSequence() { return getToken(CExpressionParser.DigitSequence, 0); }
+ public TerminalNode PathLiteral() { return getToken(CExpressionParser.PathLiteral, 0); }
+ public TerminalNode StringLiteral() { return getToken(CExpressionParser.StringLiteral, 0); }
+ public PrimaryExpressionContext primaryExpression() {
+ return getRuleContext(PrimaryExpressionContext.class,0);
+ }
+ public AssignmentOperatorContext assignmentOperator() {
+ return getRuleContext(AssignmentOperatorContext.class,0);
+ }
+ public AssignmentExpressionContext assignmentExpression() {
+ return getRuleContext(AssignmentExpressionContext.class,0);
+ }
+ public AssignmentExpressionContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_assignmentExpression; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterAssignmentExpression(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitAssignmentExpression(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitAssignmentExpression(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final AssignmentExpressionContext assignmentExpression() throws RecognitionException {
+ AssignmentExpressionContext _localctx = new AssignmentExpressionContext(_ctx, getState());
+ enterRule(_localctx, 40, RULE_assignmentExpression);
+ try {
+ setState(250);
+ _errHandler.sync(this);
+ switch ( getInterpreter().adaptivePredict(_input,26,_ctx) ) {
+ case 1:
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(242);
+ conditionalExpression();
+ }
+ break;
+ case 2:
+ enterOuterAlt(_localctx, 2);
+ {
+ setState(243);
+ match(DigitSequence);
+ }
+ break;
+ case 3:
+ enterOuterAlt(_localctx, 3);
+ {
+ setState(244);
+ match(PathLiteral);
+ }
+ break;
+ case 4:
+ enterOuterAlt(_localctx, 4);
+ {
+ setState(245);
+ match(StringLiteral);
+ }
+ break;
+ case 5:
+ enterOuterAlt(_localctx, 5);
+ {
+ setState(246);
+ primaryExpression();
+ setState(247);
+ assignmentOperator();
+ setState(248);
+ assignmentExpression();
+ }
+ break;
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ @SuppressWarnings("CheckReturnValue")
+ public static class AssignmentOperatorContext extends ParserRuleContext {
+ public TerminalNode Assign() { return getToken(CExpressionParser.Assign, 0); }
+ public TerminalNode StarAssign() { return getToken(CExpressionParser.StarAssign, 0); }
+ public TerminalNode DivAssign() { return getToken(CExpressionParser.DivAssign, 0); }
+ public TerminalNode ModAssign() { return getToken(CExpressionParser.ModAssign, 0); }
+ public TerminalNode PlusAssign() { return getToken(CExpressionParser.PlusAssign, 0); }
+ public TerminalNode MinusAssign() { return getToken(CExpressionParser.MinusAssign, 0); }
+ public TerminalNode LeftShiftAssign() { return getToken(CExpressionParser.LeftShiftAssign, 0); }
+ public TerminalNode RightShiftAssign() { return getToken(CExpressionParser.RightShiftAssign, 0); }
+ public TerminalNode AndAssign() { return getToken(CExpressionParser.AndAssign, 0); }
+ public TerminalNode XorAssign() { return getToken(CExpressionParser.XorAssign, 0); }
+ public TerminalNode OrAssign() { return getToken(CExpressionParser.OrAssign, 0); }
+ public AssignmentOperatorContext(ParserRuleContext parent, int invokingState) {
+ super(parent, invokingState);
+ }
+ @Override public int getRuleIndex() { return RULE_assignmentOperator; }
+ @Override
+ public void enterRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).enterAssignmentOperator(this);
+ }
+ @Override
+ public void exitRule(ParseTreeListener listener) {
+ if ( listener instanceof CExpressionListener ) ((CExpressionListener)listener).exitAssignmentOperator(this);
+ }
+ @Override
+ public T accept(ParseTreeVisitor extends T> visitor) {
+ if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor extends T>)visitor).visitAssignmentOperator(this);
+ else return visitor.visitChildren(this);
+ }
+ }
+
+ public final AssignmentOperatorContext assignmentOperator() throws RecognitionException {
+ AssignmentOperatorContext _localctx = new AssignmentOperatorContext(_ctx, getState());
+ enterRule(_localctx, 42, RULE_assignmentOperator);
+ int _la;
+ try {
+ enterOuterAlt(_localctx, 1);
+ {
+ setState(252);
+ _la = _input.LA(1);
+ if ( !((((_la) & ~0x3f) == 0 && ((1L << _la) & 4395899027456L) != 0)) ) {
+ _errHandler.recoverInline(this);
+ }
+ else {
+ if ( _input.LA(1)==Token.EOF ) matchedEOF = true;
+ _errHandler.reportMatch(this);
+ consume();
+ }
+ }
+ }
+ catch (RecognitionException re) {
+ _localctx.exception = re;
+ _errHandler.reportError(this, re);
+ _errHandler.recover(this, re);
+ }
+ finally {
+ exitRule();
+ }
+ return _localctx;
+ }
+
+ public static final String _serializedATN =
+ "\u0004\u0001B\u00ff\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+
+ "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004\u0007\u0004\u0002"+
+ "\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007\u0007\u0007\u0002"+
+ "\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b\u0007\u000b\u0002"+
+ "\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0002\u000f\u0007\u000f"+
+ "\u0002\u0010\u0007\u0010\u0002\u0011\u0007\u0011\u0002\u0012\u0007\u0012"+
+ "\u0002\u0013\u0007\u0013\u0002\u0014\u0007\u0014\u0002\u0015\u0007\u0015"+
+ "\u0001\u0000\u0001\u0000\u0001\u0000\u0005\u00000\b\u0000\n\u0000\f\u0000"+
+ "3\t\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+
+ "\u0001\u0001\u0003\u0001;\b\u0001\u0001\u0002\u0001\u0002\u0001\u0002"+
+ "\u0001\u0002\u0004\u0002A\b\u0002\u000b\u0002\f\u0002B\u0001\u0002\u0001"+
+ "\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001\u0002\u0001"+
+ "\u0002\u0003\u0002M\b\u0002\u0001\u0003\u0001\u0003\u0001\u0003\u0001"+
+ "\u0003\u0001\u0003\u0003\u0003T\b\u0003\u0001\u0003\u0001\u0003\u0001"+
+ "\u0003\u0001\u0003\u0001\u0003\u0003\u0003[\b\u0003\u0001\u0003\u0001"+
+ "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0003\u0003b\b\u0003\u0001"+
+ "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0003\u0003i\b"+
+ "\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0003"+
+ "\u0003p\b\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001\u0003\u0001"+
+ "\u0003\u0001\u0003\u0001\u0003\u0003\u0003y\b\u0003\u0003\u0003{\b\u0003"+
+ "\u0001\u0004\u0001\u0004\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006"+
+ "\u0001\u0006\u0005\u0006\u0084\b\u0006\n\u0006\f\u0006\u0087\t\u0006\u0001"+
+ "\u0007\u0001\u0007\u0001\u0007\u0005\u0007\u008c\b\u0007\n\u0007\f\u0007"+
+ "\u008f\t\u0007\u0001\b\u0001\b\u0001\b\u0005\b\u0094\b\b\n\b\f\b\u0097"+
+ "\t\b\u0001\t\u0001\t\u0001\t\u0005\t\u009c\b\t\n\t\f\t\u009f\t\t\u0001"+
+ "\n\u0001\n\u0001\n\u0005\n\u00a4\b\n\n\n\f\n\u00a7\t\n\u0001\u000b\u0001"+
+ "\u000b\u0001\u000b\u0005\u000b\u00ac\b\u000b\n\u000b\f\u000b\u00af\t\u000b"+
+ "\u0001\f\u0001\f\u0001\f\u0005\f\u00b4\b\f\n\f\f\f\u00b7\t\f\u0001\r\u0001"+
+ "\r\u0001\r\u0005\r\u00bc\b\r\n\r\f\r\u00bf\t\r\u0001\u000e\u0001\u000e"+
+ "\u0001\u000e\u0005\u000e\u00c4\b\u000e\n\u000e\f\u000e\u00c7\t\u000e\u0001"+
+ "\u000f\u0001\u000f\u0001\u000f\u0005\u000f\u00cc\b\u000f\n\u000f\f\u000f"+
+ "\u00cf\t\u000f\u0001\u0010\u0001\u0010\u0001\u0010\u0005\u0010\u00d4\b"+
+ "\u0010\n\u0010\f\u0010\u00d7\t\u0010\u0001\u0011\u0001\u0011\u0001\u0012"+
+ "\u0001\u0012\u0001\u0012\u0003\u0012\u00de\b\u0012\u0001\u0012\u0001\u0012"+
+ "\u0001\u0013\u0001\u0013\u0001\u0013\u0005\u0013\u00e5\b\u0013\n\u0013"+
+ "\f\u0013\u00e8\t\u0013\u0001\u0013\u0001\u0013\u0005\u0013\u00ec\b\u0013"+
+ "\n\u0013\f\u0013\u00ef\t\u0013\u0003\u0013\u00f1\b\u0013\u0001\u0014\u0001"+
+ "\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001\u0014\u0001"+
+ "\u0014\u0003\u0014\u00fb\b\u0014\u0001\u0015\u0001\u0015\u0001\u0015\u0000"+
+ "\u0000\u0016\u0000\u0002\u0004\u0006\b\n\f\u000e\u0010\u0012\u0014\u0016"+
+ "\u0018\u001a\u001c\u001e \"$&(*\u0000\b\u0002\u0000/589\u0005\u0000\r"+
+ "\r\u000f\u000f\u0011\u0011\u0014\u0014\u0019\u001a\u0001\u0000\u0011\u0013"+
+ "\u0002\u0000\r\r\u000f\u000f\u0001\u0000\u000b\f\u0001\u0000\u0007\n\u0001"+
+ "\u0000*+\u0001\u0000\u001f)\u0110\u0000,\u0001\u0000\u0000\u0000\u0002"+
+ "4\u0001\u0000\u0000\u0000\u0004L\u0001\u0000\u0000\u0000\u0006z\u0001"+
+ "\u0000\u0000\u0000\b|\u0001\u0000\u0000\u0000\n~\u0001\u0000\u0000\u0000"+
+ "\f\u0080\u0001\u0000\u0000\u0000\u000e\u0088\u0001\u0000\u0000\u0000\u0010"+
+ "\u0090\u0001\u0000\u0000\u0000\u0012\u0098\u0001\u0000\u0000\u0000\u0014"+
+ "\u00a0\u0001\u0000\u0000\u0000\u0016\u00a8\u0001\u0000\u0000\u0000\u0018"+
+ "\u00b0\u0001\u0000\u0000\u0000\u001a\u00b8\u0001\u0000\u0000\u0000\u001c"+
+ "\u00c0\u0001\u0000\u0000\u0000\u001e\u00c8\u0001\u0000\u0000\u0000 \u00d0"+
+ "\u0001\u0000\u0000\u0000\"\u00d8\u0001\u0000\u0000\u0000$\u00da\u0001"+
+ "\u0000\u0000\u0000&\u00f0\u0001\u0000\u0000\u0000(\u00fa\u0001\u0000\u0000"+
+ "\u0000*\u00fc\u0001\u0000\u0000\u0000,1\u0003(\u0014\u0000-.\u0005\u001e"+
+ "\u0000\u0000.0\u0003(\u0014\u0000/-\u0001\u0000\u0000\u000003\u0001\u0000"+
+ "\u0000\u00001/\u0001\u0000\u0000\u000012\u0001\u0000\u0000\u00002\u0001"+
+ "\u0001\u0000\u0000\u000031\u0001\u0000\u0000\u00004:\u0003 \u0010\u0000"+
+ "56\u0005\u001b\u0000\u000067\u0003\u0000\u0000\u000078\u0005\u001c\u0000"+
+ "\u000089\u0003\u0002\u0001\u00009;\u0001\u0000\u0000\u0000:5\u0001\u0000"+
+ "\u0000\u0000:;\u0001\u0000\u0000\u0000;\u0003\u0001\u0000\u0000\u0000"+
+ "M\u00056\u0000\u0000?A\u0005"+
+ "8\u0000\u0000@?\u0001\u0000\u0000\u0000AB\u0001\u0000\u0000\u0000B@\u0001"+
+ "\u0000\u0000\u0000BC\u0001\u0000\u0000\u0000CM\u0001\u0000\u0000\u0000"+
+ "DE\u0005\u0001\u0000\u0000EF\u0003\u0000\u0000\u0000FG\u0005\u0002\u0000"+
+ "\u0000GM\u0001\u0000\u0000\u0000HI\u0003\n\u0005\u0000IJ\u0003\u0004\u0002"+
+ "\u0000JM\u0001\u0000\u0000\u0000KM\u0003\u0006\u0003\u0000L<\u0001\u0000"+
+ "\u0000\u0000L=\u0001\u0000\u0000\u0000L>\u0001\u0000\u0000\u0000L@\u0001"+
+ "\u0000\u0000\u0000LD\u0001\u0000\u0000\u0000LH\u0001\u0000\u0000\u0000"+
+ "LK\u0001\u0000\u0000\u0000M\u0005\u0001\u0000\u0000\u0000NS\u0005/\u0000"+
+ "\u0000OP\u0005\u0001\u0000\u0000PQ\u0003\b\u0004\u0000QR\u0005\u0002\u0000"+
+ "\u0000RT\u0001\u0000\u0000\u0000SO\u0001\u0000\u0000\u0000ST\u0001\u0000"+
+ "\u0000\u0000T{\u0001\u0000\u0000\u0000UZ\u00050\u0000\u0000VW\u0005\u0001"+
+ "\u0000\u0000WX\u0003\b\u0004\u0000XY\u0005\u0002\u0000\u0000Y[\u0001\u0000"+
+ "\u0000\u0000ZV\u0001\u0000\u0000\u0000Z[\u0001\u0000\u0000\u0000[{\u0001"+
+ "\u0000\u0000\u0000\\a\u00051\u0000\u0000]^\u0005\u0001\u0000\u0000^_\u0003"+
+ "\b\u0004\u0000_`\u0005\u0002\u0000\u0000`b\u0001\u0000\u0000\u0000a]\u0001"+
+ "\u0000\u0000\u0000ab\u0001\u0000\u0000\u0000b{\u0001\u0000\u0000\u0000"+
+ "ch\u00052\u0000\u0000de\u0005\u0001\u0000\u0000ef\u0003\b\u0004\u0000"+
+ "fg\u0005\u0002\u0000\u0000gi\u0001\u0000\u0000\u0000hd\u0001\u0000\u0000"+
+ "\u0000hi\u0001\u0000\u0000\u0000i{\u0001\u0000\u0000\u0000jo\u00053\u0000"+
+ "\u0000kl\u0005\u0001\u0000\u0000lm\u0003\b\u0004\u0000mn\u0005\u0002\u0000"+
+ "\u0000np\u0001\u0000\u0000\u0000ok\u0001\u0000\u0000\u0000op\u0001\u0000"+
+ "\u0000\u0000p{\u0001\u0000\u0000\u0000qr\u00054\u0000\u0000rs\u0005\u0001"+
+ "\u0000\u0000st\u0003\b\u0004\u0000tu\u0005\u0002\u0000\u0000u{\u0001\u0000"+
+ "\u0000\u0000vx\u00054\u0000\u0000wy\u0003\b\u0004\u0000xw\u0001\u0000"+
+ "\u0000\u0000xy\u0001\u0000\u0000\u0000y{\u0001\u0000\u0000\u0000zN\u0001"+
+ "\u0000\u0000\u0000zU\u0001\u0000\u0000\u0000z\\\u0001\u0000\u0000\u0000"+
+ "zc\u0001\u0000\u0000\u0000zj\u0001\u0000\u0000\u0000zq\u0001\u0000\u0000"+
+ "\u0000zv\u0001\u0000\u0000\u0000{\u0007\u0001\u0000\u0000\u0000|}\u0007"+
+ "\u0000\u0000\u0000}\t\u0001\u0000\u0000\u0000~\u007f\u0007\u0001\u0000"+
+ "\u0000\u007f\u000b\u0001\u0000\u0000\u0000\u0080\u0085\u0003\u0004\u0002"+
+ "\u0000\u0081\u0082\u0005\u001c\u0000\u0000\u0082\u0084\u0003\u0004\u0002"+
+ "\u0000\u0083\u0081\u0001\u0000\u0000\u0000\u0084\u0087\u0001\u0000\u0000"+
+ "\u0000\u0085\u0083\u0001\u0000\u0000\u0000\u0085\u0086\u0001\u0000\u0000"+
+ "\u0000\u0086\r\u0001\u0000\u0000\u0000\u0087\u0085\u0001\u0000\u0000\u0000"+
+ "\u0088\u008d\u0003\f\u0006\u0000\u0089\u008a\u0007\u0002\u0000\u0000\u008a"+
+ "\u008c\u0003\f\u0006\u0000\u008b\u0089\u0001\u0000\u0000\u0000\u008c\u008f"+
+ "\u0001\u0000\u0000\u0000\u008d\u008b\u0001\u0000\u0000\u0000\u008d\u008e"+
+ "\u0001\u0000\u0000\u0000\u008e\u000f\u0001\u0000\u0000\u0000\u008f\u008d"+
+ "\u0001\u0000\u0000\u0000\u0090\u0095\u0003\u000e\u0007\u0000\u0091\u0092"+
+ "\u0007\u0003\u0000\u0000\u0092\u0094\u0003\u000e\u0007\u0000\u0093\u0091"+
+ "\u0001\u0000\u0000\u0000\u0094\u0097\u0001\u0000\u0000\u0000\u0095\u0093"+
+ "\u0001\u0000\u0000\u0000\u0095\u0096\u0001\u0000\u0000\u0000\u0096\u0011"+
+ "\u0001\u0000\u0000\u0000\u0097\u0095\u0001\u0000\u0000\u0000\u0098\u009d"+
+ "\u0003\u0010\b\u0000\u0099\u009a\u0007\u0004\u0000\u0000\u009a\u009c\u0003"+
+ "\u0010\b\u0000\u009b\u0099\u0001\u0000\u0000\u0000\u009c\u009f\u0001\u0000"+
+ "\u0000\u0000\u009d\u009b\u0001\u0000\u0000\u0000\u009d\u009e\u0001\u0000"+
+ "\u0000\u0000\u009e\u0013\u0001\u0000\u0000\u0000\u009f\u009d\u0001\u0000"+
+ "\u0000\u0000\u00a0\u00a5\u0003\u0012\t\u0000\u00a1\u00a2\u0007\u0005\u0000"+
+ "\u0000\u00a2\u00a4\u0003\u0012\t\u0000\u00a3\u00a1\u0001\u0000\u0000\u0000"+
+ "\u00a4\u00a7\u0001\u0000\u0000\u0000\u00a5\u00a3\u0001\u0000\u0000\u0000"+
+ "\u00a5\u00a6\u0001\u0000\u0000\u0000\u00a6\u0015\u0001\u0000\u0000\u0000"+
+ "\u00a7\u00a5\u0001\u0000\u0000\u0000\u00a8\u00ad\u0003\u0014\n\u0000\u00a9"+
+ "\u00aa\u0007\u0006\u0000\u0000\u00aa\u00ac\u0003\u0014\n\u0000\u00ab\u00a9"+
+ "\u0001\u0000\u0000\u0000\u00ac\u00af\u0001\u0000\u0000\u0000\u00ad\u00ab"+
+ "\u0001\u0000\u0000\u0000\u00ad\u00ae\u0001\u0000\u0000\u0000\u00ae\u0017"+
+ "\u0001\u0000\u0000\u0000\u00af\u00ad\u0001\u0000\u0000\u0000\u00b0\u00b5"+
+ "\u0003\u0016\u000b\u0000\u00b1\u00b2\u0005\u0014\u0000\u0000\u00b2\u00b4"+
+ "\u0003\u0016\u000b\u0000\u00b3\u00b1\u0001\u0000\u0000\u0000\u00b4\u00b7"+
+ "\u0001\u0000\u0000\u0000\u00b5\u00b3\u0001\u0000\u0000\u0000\u00b5\u00b6"+
+ "\u0001\u0000\u0000\u0000\u00b6\u0019\u0001\u0000\u0000\u0000\u00b7\u00b5"+
+ "\u0001\u0000\u0000\u0000\u00b8\u00bd\u0003\u0018\f\u0000\u00b9\u00ba\u0005"+
+ "\u0018\u0000\u0000\u00ba\u00bc\u0003\u0018\f\u0000\u00bb\u00b9\u0001\u0000"+
+ "\u0000\u0000\u00bc\u00bf\u0001\u0000\u0000\u0000\u00bd\u00bb\u0001\u0000"+
+ "\u0000\u0000\u00bd\u00be\u0001\u0000\u0000\u0000\u00be\u001b\u0001\u0000"+
+ "\u0000\u0000\u00bf\u00bd\u0001\u0000\u0000\u0000\u00c0\u00c5\u0003\u001a"+
+ "\r\u0000\u00c1\u00c2\u0005\u0015\u0000\u0000\u00c2\u00c4\u0003\u001a\r"+
+ "\u0000\u00c3\u00c1\u0001\u0000\u0000\u0000\u00c4\u00c7\u0001\u0000\u0000"+
+ "\u0000\u00c5\u00c3\u0001\u0000\u0000\u0000\u00c5\u00c6\u0001\u0000\u0000"+
+ "\u0000\u00c6\u001d\u0001\u0000\u0000\u0000\u00c7\u00c5\u0001\u0000\u0000"+
+ "\u0000\u00c8\u00cd\u0003\"\u0011\u0000\u00c9\u00ca\u0005\u0016\u0000\u0000"+
+ "\u00ca\u00cc\u0003\"\u0011\u0000\u00cb\u00c9\u0001\u0000\u0000\u0000\u00cc"+
+ "\u00cf\u0001\u0000\u0000\u0000\u00cd\u00cb\u0001\u0000\u0000\u0000\u00cd"+
+ "\u00ce\u0001\u0000\u0000\u0000\u00ce\u001f\u0001\u0000\u0000\u0000\u00cf"+
+ "\u00cd\u0001\u0000\u0000\u0000\u00d0\u00d5\u0003\u001e\u000f\u0000\u00d1"+
+ "\u00d2\u0005\u0017\u0000\u0000\u00d2\u00d4\u0003\u001e\u000f\u0000\u00d3"+
+ "\u00d1\u0001\u0000\u0000\u0000\u00d4\u00d7\u0001\u0000\u0000\u0000\u00d5"+
+ "\u00d3\u0001\u0000\u0000\u0000\u00d5\u00d6\u0001\u0000\u0000\u0000\u00d6"+
+ "!\u0001\u0000\u0000\u0000\u00d7\u00d5\u0001\u0000\u0000\u0000\u00d8\u00d9"+
+ "\u0003\u001c\u000e\u0000\u00d9#\u0001\u0000\u0000\u0000\u00da\u00db\u0005"+
+ "5\u0000\u0000\u00db\u00dd\u0005\u0001\u0000\u0000\u00dc\u00de\u0003&\u0013"+
+ "\u0000\u00dd\u00dc\u0001\u0000\u0000\u0000\u00dd\u00de\u0001\u0000\u0000"+
+ "\u0000\u00de\u00df\u0001\u0000\u0000\u0000\u00df\u00e0\u0005\u0002\u0000"+
+ "\u0000\u00e0%\u0001\u0000\u0000\u0000\u00e1\u00e6\u0003(\u0014\u0000\u00e2"+
+ "\u00e3\u0005\u001e\u0000\u0000\u00e3\u00e5\u0003(\u0014\u0000\u00e4\u00e2"+
+ "\u0001\u0000\u0000\u0000\u00e5\u00e8\u0001\u0000\u0000\u0000\u00e6\u00e4"+
+ "\u0001\u0000\u0000\u0000\u00e6\u00e7\u0001\u0000\u0000\u0000\u00e7\u00f1"+
+ "\u0001\u0000\u0000\u0000\u00e8\u00e6\u0001\u0000\u0000\u0000\u00e9\u00ed"+
+ "\u0003(\u0014\u0000\u00ea\u00ec\u0003(\u0014\u0000\u00eb\u00ea\u0001\u0000"+
+ "\u0000\u0000\u00ec\u00ef\u0001\u0000\u0000\u0000\u00ed\u00eb\u0001\u0000"+
+ "\u0000\u0000\u00ed\u00ee\u0001\u0000\u0000\u0000\u00ee\u00f1\u0001\u0000"+
+ "\u0000\u0000\u00ef\u00ed\u0001\u0000\u0000\u0000\u00f0\u00e1\u0001\u0000"+
+ "\u0000\u0000\u00f0\u00e9\u0001\u0000\u0000\u0000\u00f1\'\u0001\u0000\u0000"+
+ "\u0000\u00f2\u00fb\u0003\u0002\u0001\u0000\u00f3\u00fb\u00057\u0000\u0000"+
+ "\u00f4\u00fb\u00059\u0000\u0000\u00f5\u00fb\u00058\u0000\u0000\u00f6\u00f7"+
+ "\u0003\u0004\u0002\u0000\u00f7\u00f8\u0003*\u0015\u0000\u00f8\u00f9\u0003"+
+ "(\u0014\u0000\u00f9\u00fb\u0001\u0000\u0000\u0000\u00fa\u00f2\u0001\u0000"+
+ "\u0000\u0000\u00fa\u00f3\u0001\u0000\u0000\u0000\u00fa\u00f4\u0001\u0000"+
+ "\u0000\u0000\u00fa\u00f5\u0001\u0000\u0000\u0000\u00fa\u00f6\u0001\u0000"+
+ "\u0000\u0000\u00fb)\u0001\u0000\u0000\u0000\u00fc\u00fd\u0007\u0007\u0000"+
+ "\u0000\u00fd+\u0001\u0000\u0000\u0000\u001b1:BLSZahoxz\u0085\u008d\u0095"+
+ "\u009d\u00a5\u00ad\u00b5\u00bd\u00c5\u00cd\u00d5\u00dd\u00e6\u00ed\u00f0"+
+ "\u00fa";
+ public static final ATN _ATN =
+ new ATNDeserializer().deserialize(_serializedATN.toCharArray());
+ static {
+ _decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
+ for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
+ _decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionVisitor.java b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionVisitor.java
new file mode 100644
index 000000000..8fb70016c
--- /dev/null
+++ b/src/main/java/org/variantsync/diffdetective/feature/antlr/CExpressionVisitor.java
@@ -0,0 +1,145 @@
+// Generated from /home/alex/programming/DiffDetective/src/main/resources/grammars/CExpression.g4 by ANTLR 4.13.1
+package org.variantsync.diffdetective.feature.antlr;
+import org.antlr.v4.runtime.tree.ParseTreeVisitor;
+
+/**
+ * This interface defines a complete generic visitor for a parse tree produced
+ * by {@link CExpressionParser}.
+ *
+ * @param The return type of the visit operation. Use {@link Void} for
+ * operations with no return type.
+ */
+public interface CExpressionVisitor extends ParseTreeVisitor {
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#expression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitExpression(CExpressionParser.ExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#conditionalExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitConditionalExpression(CExpressionParser.ConditionalExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#primaryExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitPrimaryExpression(CExpressionParser.PrimaryExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#specialOperator}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitSpecialOperator(CExpressionParser.SpecialOperatorContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#specialOperatorArgument}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitSpecialOperatorArgument(CExpressionParser.SpecialOperatorArgumentContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#unaryOperator}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitUnaryOperator(CExpressionParser.UnaryOperatorContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#namespaceExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitNamespaceExpression(CExpressionParser.NamespaceExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#multiplicativeExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitMultiplicativeExpression(CExpressionParser.MultiplicativeExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#additiveExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitAdditiveExpression(CExpressionParser.AdditiveExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#shiftExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitShiftExpression(CExpressionParser.ShiftExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#relationalExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitRelationalExpression(CExpressionParser.RelationalExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#equalityExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitEqualityExpression(CExpressionParser.EqualityExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#andExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitAndExpression(CExpressionParser.AndExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#exclusiveOrExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitExclusiveOrExpression(CExpressionParser.ExclusiveOrExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#inclusiveOrExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitInclusiveOrExpression(CExpressionParser.InclusiveOrExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#logicalAndExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitLogicalAndExpression(CExpressionParser.LogicalAndExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#logicalOrExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitLogicalOrExpression(CExpressionParser.LogicalOrExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#logicalOperand}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitLogicalOperand(CExpressionParser.LogicalOperandContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#macroExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitMacroExpression(CExpressionParser.MacroExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#argumentExpressionList}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitArgumentExpressionList(CExpressionParser.ArgumentExpressionListContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#assignmentExpression}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitAssignmentExpression(CExpressionParser.AssignmentExpressionContext ctx);
+ /**
+ * Visit a parse tree produced by {@link CExpressionParser#assignmentOperator}.
+ * @param ctx the parse tree
+ * @return the visitor result
+ */
+ T visitAssignmentOperator(CExpressionParser.AssignmentOperatorContext ctx);
+}
\ No newline at end of file
diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/GDAnalysisUtils.java b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/GDAnalysisUtils.java
index 92f15185d..6b6f125b6 100644
--- a/src/main/java/org/variantsync/diffdetective/preliminary/analysis/GDAnalysisUtils.java
+++ b/src/main/java/org/variantsync/diffdetective/preliminary/analysis/GDAnalysisUtils.java
@@ -8,6 +8,7 @@
import org.variantsync.diffdetective.preliminary.analysis.data.PatternMatch;
import org.variantsync.diffdetective.util.IO;
import org.variantsync.diffdetective.variation.diff.DiffNode;
+import org.variantsync.diffdetective.variation.diff.Time;
import java.io.FileNotFoundException;
import java.util.ArrayList;
@@ -45,7 +46,7 @@ public static void exportCsv(GDAnalysisResult analysisResult, String fileName) {
commitResult.getPatchDiffAnalysisResults()) {
for (PatternMatch> patternMatch : patchResult.getPatternMatches()) {
commits.add(commitResult.getCommitDiff().getCommitHash());
- patches.add(patchResult.getPatchDiff().getFileName());
+ patches.add(patchResult.getPatchDiff().getFileName(Time.AFTER));
patterns.add(patternMatch.getPatternName());
if (patternMatch.hasFeatureMappings()) {
StringJoiner sj = new StringJoiner(";");
diff --git a/src/main/java/org/variantsync/diffdetective/preliminary/evaluation/GDEvaluator.java b/src/main/java/org/variantsync/diffdetective/preliminary/evaluation/GDEvaluator.java
index 64310e615..eef0a725a 100644
--- a/src/main/java/org/variantsync/diffdetective/preliminary/evaluation/GDEvaluator.java
+++ b/src/main/java/org/variantsync/diffdetective/preliminary/evaluation/GDEvaluator.java
@@ -16,6 +16,7 @@
import org.variantsync.diffdetective.preliminary.pattern.Pattern;
import org.variantsync.diffdetective.util.IO;
import org.variantsync.diffdetective.variation.diff.DiffNode;
+import org.variantsync.diffdetective.variation.diff.Time;
import java.io.*;
import java.util.*;
@@ -417,7 +418,7 @@ public void exportEvaluationCsv(String fileName) {
for (PatternMatchEvaluation> pme : pmEvaluations) {
commits.add(pme.getCommit().getCommitDiff().getCommitHash());
- patches.add(pme.getPatch().getPatchDiff().getFileName());
+ patches.add(pme.getPatch().getPatchDiff().getFileName(Time.AFTER));
patterns.add(pme.getPatternMatch().getPatternName());
if (pme.getPatternMatch().hasFeatureMappings()) {
StringJoiner sj = new StringJoiner(";");
@@ -496,7 +497,7 @@ public void exportDifferentFeatureContextsDistributionCsv(String fileName) {
*/
public void exportPatch(PatchDiff patchDiff, String fileName){
try(BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))){
- writer.write(patchDiff.getCommitDiff().getCommitHash() + ", " + patchDiff.getFileName());
+ writer.write(patchDiff.getCommitDiff().getCommitHash() + ", " + patchDiff.getFileName(Time.AFTER));
writer.newLine();
writer.write(patchDiff.getDiff());
writer.flush();
@@ -609,7 +610,7 @@ public void printPatchDiffs(PatchDiff... patchDiffs) {
System.out.println("######################################");
System.out.printf("patch (%s, %s)%n",
- patchDiff.getCommitDiff().getAbbreviatedCommitHash(), patchDiff.getFileName());
+ patchDiff.getCommitDiff().getAbbreviatedCommitHash(), patchDiff.getFileName(Time.AFTER));
System.out.println(patchDiff.getDiff());
System.out.println("######################################");
diff --git a/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java b/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java
index 035877400..cdb70d9f4 100644
--- a/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java
+++ b/src/main/java/org/variantsync/diffdetective/tablegen/styles/ShortTable.java
@@ -105,12 +105,12 @@ private static List columns(final ShortTable t, final TriFunct
/**
* Returns a formatted string of the absolute number of occurrences of {@code editClass} in
* {@code row}.
- * The signature of this method is suitable to be passed to {@link column}.
+ * The signature of this method is suitable to be passed to {@link ShortTable#columns(ShortTable, TriFunction)}.
*
* @param t an instance of this class contained in the column definition
* @param editClass the edit class to count
* @param row the data to count {@code editClass} in
- * @see column
+ * @see ShortTable#columns(ShortTable, TriFunction)
*/
private static String absoluteCountOf(final ShortTable t, final EditClass editClass, final ContentRow row) {
return t.makeReadable(row.get(EditClassCount.KEY).getOccurrences().get(editClass).getTotalAmount());
@@ -119,12 +119,12 @@ private static String absoluteCountOf(final ShortTable t, final EditClass editCl
/**
* Returns a formatted string of the relative number of occurrences of {@code editClass} in
* {@code row}.
- * The signature of this method is suitable to be passed to {@link column}.
+ * The signature of this method is suitable to be passed to {@link ShortTable#columns(ShortTable, TriFunction)}.
*
* @param t an instance of this class contained in the column definition
* @param editClass the edit class to count
* @param row the data to count {@code editClass} in
- * @see column
+ * @see ShortTable#columns(ShortTable, TriFunction)
*/
private static String relativeCountOf(final ShortTable t, final EditClass editClass, final ContentRow row) {
final LinkedHashMap editClassOccurrences =
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/Construction.java b/src/main/java/org/variantsync/diffdetective/variation/diff/Construction.java
index 02e559379..6b3bce296 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/Construction.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/Construction.java
@@ -271,11 +271,9 @@ private static void joinNode(DiffNode beforeNode, DiffNode<
/**
* Makes the implicit matching of a {@code VariationDiff} explicit.
*
- * @param src the source nodes of the matching, must be of the same {@link VariationDiff} as {@code
- * dst.
- * @param dst the destination nodes of the matching, must be of the same {@link VariationDiff} as
- * {@code src}
- * @param result the destination where the matching between {@code src} and {@code dst} is added
+ * @param src the source nodes of the matching, must be of the same {@link VariationDiff} as {@code dst}.
+ * @param dst the destination nodes of the matching, must be of the same {@link VariationDiff} as {@code src}
+ * @param result the destination where the matching between {@code src} and {@param dst} is added.
*/
private static void extractMatching(
VariationDiffAdapter src,
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/DiffType.java b/src/main/java/org/variantsync/diffdetective/variation/diff/DiffType.java
index 025202d7d..9b785c9d6 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/DiffType.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/DiffType.java
@@ -1,6 +1,7 @@
package org.variantsync.diffdetective.variation.diff;
import org.apache.commons.lang3.function.FailableConsumer;
+import org.tinylog.Logger;
import java.util.Optional;
import java.util.Set;
@@ -143,6 +144,14 @@ public static DiffType ofDiffLine(String line) {
return REM;
} else if (line.startsWith(NON.symbol)) {
return NON;
+ } else if (line.isEmpty()) {
+ // Treat empty lines as NON (i.e., unchanged) even though they are invalid in a diff, which expects at least
+ // one character (i.e., one of the diff type characters: '+', '-', or ' ').
+ // In contrast to other invalid cases handled by the 'else' branch, we log a warning instead of returning null,
+ // because empty lines may be created by certain text editors, such as Intellij's internal editor that may
+ // convert lines that only contain whitespace characters to empty lines upon save.
+ Logger.warn("parsing an empty line");
+ return NON;
} else {
return null;
}
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/VariationDiff.java b/src/main/java/org/variantsync/diffdetective/variation/diff/VariationDiff.java
index 5900432da..6480f177f 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/VariationDiff.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/VariationDiff.java
@@ -124,7 +124,7 @@ public static Result, List> fromPatch(f
if (result.diff().isPresent()) {
final CommitDiff commit = result.diff().get();
for (final PatchDiff patch : commit.getPatchDiffs()) {
- if (changedFile.equals(Path.of(patch.getFileName()))) {
+ if (changedFile.equals(Path.of(patch.getFileName(AFTER)))) {
return Result.Success(patch.getVariationDiff());
}
}
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/bad/BadVDiff.java b/src/main/java/org/variantsync/diffdetective/variation/diff/bad/BadVDiff.java
index c8cd8b7d4..25496273d 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/bad/BadVDiff.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/bad/BadVDiff.java
@@ -118,7 +118,7 @@ VariationTreeNode get(DiffNode d, Time t) {
* Copies {@link org.variantsync.diffdetective.variation.NodeType node type},
* {@link DiffNode#getFormula() formula},
* {@link DiffNode#getLinesInDiff() line numbers in the diff},
- * and {@link DiffNode#getLabelLines() label} but no edge information.
+ * and {@link DiffNode#getLabel() label} but no edge information.
* @param n The node to convert to a plain VariationTreeNode.
*/
private static VariationTreeNode plain(final DiffNode n) {
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/parse/LogicalLine.java b/src/main/java/org/variantsync/diffdetective/variation/diff/parse/LogicalLine.java
index 47aaaf29c..6270a933c 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/parse/LogicalLine.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/parse/LogicalLine.java
@@ -2,6 +2,8 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import org.variantsync.diffdetective.diff.text.DiffLineNumber;
import org.variantsync.diffdetective.util.Assert;
@@ -20,8 +22,15 @@
class LogicalLine {
private List lines;
private boolean isContinued;
+ private boolean inComment;
private DiffLineNumber startLineNumber;
+ // C++-style comments that are not embedded in C-style comments
+ // The regex assumes that C-style comments may begin in a preceding line
+ // e.g., '// Some comment'
+ // , but not '/* outer comment // inner comment */' or '/* preceding line \n// inner comment */'
+ private final static Pattern LINE_COMMENT = Pattern.compile("[^(/*)]*?//[^(*/)]*?");
+
/**
* Constructs an empty logical line.
*/
@@ -36,6 +45,7 @@ public LogicalLine() {
public void reset() {
lines = new ArrayList<>();
isContinued = false;
+ inComment = false;
startLineNumber = DiffLineNumber.Invalid();
}
@@ -51,8 +61,29 @@ public void consume(String line, DiffLineNumber lineNumber) {
if (!hasStarted()) {
startLineNumber = lineNumber;
}
- lines.add(new DiffLinesLabel.Line(line, lineNumber));
+
+ // Handle line continuations
isContinued = line.endsWith("\\");
+
+ // Handle multi-line inline macros
+ int commentStart = line.lastIndexOf("/*");
+ int commentEnd = line.lastIndexOf("*/");
+ Matcher lineCommentMatcher = LINE_COMMENT.matcher(line);
+ int lineCommentStart = lineCommentMatcher.find() ? lineCommentMatcher.start() : -1;
+ if (commentStart != -1 || commentEnd != -1) {
+ // Update 'inComment' if a C-style comment is opened and/or closed
+ if (lineCommentStart != -1 && lineCommentStart < commentStart) {
+ // Handle cases in which comments are embedded in other comments
+ // e.g., '// /* some comment'
+ inComment = false;
+ } else {
+ // Update the value if a start and/or end have been found
+ // The line is part of a multi-line comment, if a comment starts in this line (after another comment ends)
+ inComment = commentStart > commentEnd;
+ }
+ }
+
+ lines.add(new DiffLinesLabel.Line(line, lineNumber));
}
/**
@@ -67,7 +98,7 @@ public boolean hasStarted() {
* to a new logical line.
*/
public boolean isComplete() {
- return hasStarted() && !isContinued;
+ return hasStarted() && !isContinued && !inComment;
}
/**
@@ -92,10 +123,10 @@ public List getLines() {
@Override
public String toString() {
var logicalLine = new StringBuilder();
- for (var it = lines.iterator(); it.hasNext(); ) {
- String physicalLine = it.next().content();
+ for (DiffLinesLabel.Line line : lines) {
+ String physicalLine = line.content();
// Remove the backslash of the line continuation
- logicalLine.append(physicalLine, 0, physicalLine.length() - (it.hasNext() ? 1 : 0));
+ logicalLine.append(physicalLine, 0, physicalLine.length() - (physicalLine.endsWith("\\") ? 1 : 0));
}
return logicalLine.toString();
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/parse/VariationDiffParser.java b/src/main/java/org/variantsync/diffdetective/variation/diff/parse/VariationDiffParser.java
index 2555cde7d..b8cb4cdfa 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/parse/VariationDiffParser.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/parse/VariationDiffParser.java
@@ -13,12 +13,14 @@
import org.variantsync.diffdetective.diff.result.DiffError;
import org.variantsync.diffdetective.diff.result.DiffParseException;
import org.variantsync.diffdetective.diff.text.DiffLineNumber;
+import org.variantsync.diffdetective.error.UnparseableFormulaException;
import org.variantsync.diffdetective.util.Assert;
import org.variantsync.diffdetective.variation.DiffLinesLabel;
import org.variantsync.diffdetective.variation.NodeType;
import org.variantsync.diffdetective.variation.diff.DiffNode;
import org.variantsync.diffdetective.variation.diff.VariationDiff;
import org.variantsync.diffdetective.variation.diff.DiffType;
+import org.variantsync.diffdetective.variation.diff.Time;
import java.io.BufferedReader;
import java.io.IOException;
@@ -144,11 +146,8 @@ public static VariationDiff createVariationDiff(
String line = fullDiff.readLine();
if (line == null) {
return null;
- } else if (line.length() == 0) {
- return new DiffLine(null, "");
- } else {
- return new DiffLine(DiffType.ofDiffLine(line), line.substring(1));
}
+ return new DiffLine(DiffType.ofDiffLine(line), line.isEmpty() ? line : line.substring(1));
});
}
@@ -267,6 +266,9 @@ private VariationDiff parse(
}
if (beforeLine.hasStarted() || afterLine.hasStarted()) {
+ Logger.debug("line continuation but no more lines");
+ Logger.debug("beforeLine: " + beforeLine);
+ Logger.debug("afterLine: " + afterLine);
throw new DiffParseException(
DiffError.INVALID_LINE_CONTINUATION,
lineNumber
@@ -357,8 +359,8 @@ private void parseLine(
addNode(newNode);
lastArtifact = newNode.isArtifact() ? newNode : null;
- } catch (IllFormedAnnotationException e) {
- throw new DiffParseException(e.getType(), fromLine);
+ } catch (UnparseableFormulaException e) {
+ throw DiffParseException.Unparseable(e, fromLine);
}
}
}
@@ -473,7 +475,7 @@ public static PatchDiff parsePatch(Repository repo, String file, String commitHa
final CommitDiff commitDiff = parseCommit(repo, commitHash);
for (final PatchDiff pd : commitDiff.getPatchDiffs()) {
- if (file.equals(pd.getFileName())) {
+ if (file.equals(pd.getFileName(Time.AFTER))) {
return pd;
}
}
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/render/PatchDiffRenderer.java b/src/main/java/org/variantsync/diffdetective/variation/diff/render/PatchDiffRenderer.java
index f47d07de7..f87463acb 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/render/PatchDiffRenderer.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/render/PatchDiffRenderer.java
@@ -5,6 +5,7 @@
import org.variantsync.diffdetective.diff.git.PatchDiff;
import org.variantsync.diffdetective.util.IO;
import org.variantsync.diffdetective.variation.DiffLinesLabel;
+import org.variantsync.diffdetective.variation.diff.Time;
import org.variantsync.diffdetective.variation.diff.VariationDiff;
import org.variantsync.diffdetective.variation.diff.serialize.LineGraphConstants;
import org.variantsync.diffdetective.variation.diff.serialize.LineGraphExportOptions;
@@ -81,7 +82,7 @@ public void render(final VariationDiff extends DiffLinesLabel> variationDiff,
renderer.render(variationDiff, patch, outputDirectory, options);
try {
IO.write(outputDirectory.resolve(
- patch.getFileName() + LineGraphConstants.TREE_NAME_SEPARATOR + patch.getCommitHash() + ".diff"
+ patch.getFileName(Time.AFTER) + LineGraphConstants.TREE_NAME_SEPARATOR + patch.getCommitHash() + ".diff"
),
patch.getDiff());
} catch (IOException e) {
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/render/VariationDiffRenderer.java b/src/main/java/org/variantsync/diffdetective/variation/diff/render/VariationDiffRenderer.java
index 2e7a473ea..91b03e0b9 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/render/VariationDiffRenderer.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/render/VariationDiffRenderer.java
@@ -11,6 +11,7 @@
import org.variantsync.diffdetective.util.StringUtils;
import org.variantsync.diffdetective.variation.DiffLinesLabel;
import org.variantsync.diffdetective.variation.Label;
+import org.variantsync.diffdetective.variation.diff.Time;
import org.variantsync.diffdetective.variation.diff.VariationDiff;
import org.variantsync.diffdetective.variation.diff.serialize.VariationDiffSerializeDebugData;
import org.variantsync.diffdetective.variation.diff.serialize.LineGraphConstants;
@@ -126,7 +127,7 @@ public boolean render(final VariationDiff tree, final GitPa
*/
public boolean render(final VariationDiff tree, final GitPatch patch, final Path directory, final RenderOptions super L> options, final LineGraphExportOptions super L> exportOptions) {
final String treeAndFileName =
- patch.getFileName()
+ patch.getFileName(Time.AFTER)
+ LineGraphConstants.TREE_NAME_SEPARATOR
+ patch.getCommitHash();
return render(tree, treeAndFileName, directory, options, exportOptions);
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/serialize/LineGraphExport.java b/src/main/java/org/variantsync/diffdetective/variation/diff/serialize/LineGraphExport.java
index 218195561..d1483b202 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/serialize/LineGraphExport.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/serialize/LineGraphExport.java
@@ -13,6 +13,7 @@
import org.variantsync.diffdetective.util.StringUtils;
import org.variantsync.diffdetective.variation.DiffLinesLabel;
import org.variantsync.diffdetective.variation.Label;
+import org.variantsync.diffdetective.variation.diff.Time;
import org.variantsync.diffdetective.variation.diff.VariationDiff;
import org.variantsync.diffdetective.variation.diff.source.VariationDiffSource;
import org.variantsync.functjonal.category.InplaceSemigroup;
@@ -145,7 +146,7 @@ public static Statistic toLineGraphFormat(final PatchDiff patch, final LineGraph
++result.exportedTrees;
} else {
- Logger.debug(" Skipping invalid patch for file {} at commit {}", patch.getFileName(), patch.getCommitHash());
+ Logger.debug(" Skipping invalid patch for file {} at commit {}", patch.getFileName(Time.AFTER), patch.getCommitHash());
}
return result;
@@ -153,11 +154,9 @@ public static Statistic toLineGraphFormat(final PatchDiff patch, final LineGraph
/**
* Produces the final linegraph file content.
- * Creates a linegraph header from the given VariationDiffSource using the {@link LineGraphExportOptions#treeFormat} in the given options.
+ * Creates a linegraph header from the given VariationDiffSource using the {@link LineGraphExportOptions#treeFormat()} in the given options.
* Then appends the already created file content for nodes and edges.
- * @param lineGraph The string builder to write the result to.
* @param source The {@link VariationDiffSource} that describes where the VariationDiff whose content is written to the file originated from.
- * @param nodesAndEdges Result from {@link #toLineGraphFormat(VariationDiff, LineGraphExportOptions, OutputStream)}. Holds all nodes and edges in linegraph format, separated by a newline each.
* @param options {@link LineGraphExportOptions} used to determine the treeFormat for the header.
*/
private static String lineGraphHeader(final VariationDiffSource source, final LineGraphExportOptions> options) {
diff --git a/src/main/java/org/variantsync/diffdetective/variation/diff/serialize/treeformat/CommitDiffVariationDiffLabelFormat.java b/src/main/java/org/variantsync/diffdetective/variation/diff/serialize/treeformat/CommitDiffVariationDiffLabelFormat.java
index c839d464e..fe47748ef 100644
--- a/src/main/java/org/variantsync/diffdetective/variation/diff/serialize/treeformat/CommitDiffVariationDiffLabelFormat.java
+++ b/src/main/java/org/variantsync/diffdetective/variation/diff/serialize/treeformat/CommitDiffVariationDiffLabelFormat.java
@@ -3,6 +3,7 @@
import org.apache.commons.io.FilenameUtils;
import org.variantsync.diffdetective.diff.git.CommitDiff;
import org.variantsync.diffdetective.diff.git.PatchDiff;
+import org.variantsync.diffdetective.variation.diff.Time;
import org.variantsync.diffdetective.variation.diff.serialize.LineGraphConstants;
import org.variantsync.diffdetective.variation.diff.source.CommitDiffVariationDiffSource;
import org.variantsync.diffdetective.variation.diff.source.VariationDiffSource;
@@ -36,7 +37,7 @@ public String toLabel(final VariationDiffSource variationDiffSource) {
return FilenameUtils.separatorsToUnix(commitDiffVariationDiffSource.getFileName().toString()) + LineGraphConstants.TREE_NAME_SEPARATOR + commitDiffVariationDiffSource.getCommitHash();
} else if (variationDiffSource instanceof PatchDiff patchDiff) {
// write for instances of PatchDiffs
- return FilenameUtils.separatorsToUnix(patchDiff.getFileName()) + LineGraphConstants.TREE_NAME_SEPARATOR + patchDiff.getCommitDiff().getCommitHash();
+ return FilenameUtils.separatorsToUnix(patchDiff.getFileName(Time.AFTER)) + LineGraphConstants.TREE_NAME_SEPARATOR + patchDiff.getCommitDiff().getCommitHash();
} else {
throw new UnsupportedOperationException("There is no implementation for this VariationDiffSource type: " + variationDiffSource);
}
diff --git a/src/main/resources/grammars/CExpression.g4 b/src/main/resources/grammars/CExpression.g4
new file mode 100644
index 000000000..1d38df99d
--- /dev/null
+++ b/src/main/resources/grammars/CExpression.g4
@@ -0,0 +1,472 @@
+grammar CExpression;
+// A copy of the official C ANTLR grammar that was adjusted to parse C preprocessor expressions
+// https://github.com/antlr/grammars-v4/blob/master/c/C.g4
+
+expression
+ : assignmentExpression (',' assignmentExpression)*
+ ;
+
+conditionalExpression
+ : logicalOrExpression ('?' expression ':' conditionalExpression)?
+ ;
+
+primaryExpression
+ : macroExpression
+ | Identifier
+ | Constant
+ | StringLiteral+
+ | '(' expression ')'
+ | unaryOperator primaryExpression
+ | specialOperator
+ ;
+
+specialOperator
+ : HasAttribute ('(' specialOperatorArgument ')')?
+ | HasCPPAttribute ('(' specialOperatorArgument ')')?
+ | HasCAttribute ('(' specialOperatorArgument ')')?
+ | HasBuiltin ('(' specialOperatorArgument ')')?
+ | HasInclude ('(' specialOperatorArgument ')')?
+ | Defined ('(' specialOperatorArgument ')')
+ | Defined specialOperatorArgument?
+ ;
+
+specialOperatorArgument
+ : HasAttribute
+ | HasCPPAttribute
+ | HasCAttribute
+ | HasBuiltin
+ | HasInclude
+ | Defined
+ | Identifier
+ | PathLiteral
+ | StringLiteral
+ ;
+
+unaryOperator
+ : '&' | '*' | '+' | '-' | '~' | '!'
+ ;
+
+namespaceExpression
+ : primaryExpression (':' primaryExpression)*
+ ;
+
+multiplicativeExpression
+ : namespaceExpression (('*'|'/'|'%') namespaceExpression)*
+ ;
+
+additiveExpression
+ : multiplicativeExpression (('+'|'-') multiplicativeExpression)*
+ ;
+
+shiftExpression
+ : additiveExpression (('<<'|'>>') additiveExpression)*
+ ;
+
+relationalExpression
+ : shiftExpression (('<'|'>'|'<='|'>=') shiftExpression)*
+ ;
+
+equalityExpression
+ : relationalExpression (('=='| '!=') relationalExpression)*
+ ;
+
+andExpression
+ : equalityExpression ( '&' equalityExpression)*
+ ;
+
+exclusiveOrExpression
+ : andExpression ('^' andExpression)*
+ ;
+
+inclusiveOrExpression
+ : exclusiveOrExpression ('|' exclusiveOrExpression)*
+ ;
+
+logicalAndExpression
+ : logicalOperand ( '&&' logicalOperand)*
+ ;
+
+logicalOrExpression
+ : logicalAndExpression ( '||' logicalAndExpression)*
+ ;
+
+logicalOperand
+ : inclusiveOrExpression
+ ;
+
+macroExpression
+ : Identifier '(' argumentExpressionList? ')'
+ ;
+
+argumentExpressionList
+ : assignmentExpression (',' assignmentExpression)*
+ | assignmentExpression (assignmentExpression)*
+ ;
+
+assignmentExpression
+ : conditionalExpression
+ | DigitSequence // for
+ | PathLiteral
+ | StringLiteral
+ | primaryExpression assignmentOperator assignmentExpression
+ ;
+
+assignmentOperator
+ : '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='
+ ;
+
+
+LeftParen : '(';
+RightParen : ')';
+LeftBracket : '[';
+RightBracket : ']';
+LeftBrace : '{';
+RightBrace : '}';
+
+Less : '<';
+LessEqual : '<=';
+Greater : '>';
+GreaterEqual : '>=';
+LeftShift : '<<';
+RightShift : '>>';
+
+Plus : '+';
+PlusPlus : '++';
+Minus : '-';
+MinusMinus : '--';
+Star : '*';
+Div : '/';
+Mod : '%';
+
+And : '&';
+Or : '|';
+AndAnd : '&&';
+OrOr : '||';
+Caret : '^';
+Not : '!';
+Tilde : '~';
+
+Question : '?';
+Colon : ':';
+Semi : ';';
+Comma : ',';
+
+Assign : '=';
+// '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|='
+StarAssign : '*=';
+DivAssign : '/=';
+ModAssign : '%=';
+PlusAssign : '+=';
+MinusAssign : '-=';
+LeftShiftAssign : '<<=';
+RightShiftAssign : '>>=';
+AndAssign : '&=';
+XorAssign : '^=';
+OrAssign : '|=';
+
+Equal : '==';
+NotEqual : '!=';
+
+Arrow : '->';
+Dot : '.';
+Ellipsis : '...';
+
+HasAttribute : '__has_attribute';
+HasCPPAttribute : '__has_cpp_attribute';
+HasCAttribute : '__has_c_attribute';
+HasBuiltin : '__has_builtin';
+HasInclude : '__has_include';
+Defined : 'defined';
+
+Identifier
+ : ('\\')? ( IdentifierNondigit
+ | Digit
+ )+
+ ;
+
+fragment
+IdentifierNondigit
+ : Nondigit
+ | UniversalCharacterName
+ //| // other implementation-defined characters...y
+ ;
+
+fragment
+Nondigit
+ : [a-zA-Z_]
+ ;
+
+fragment
+Digit
+ : [0-9]
+ ;
+
+fragment
+UniversalCharacterName
+ : '\\u' HexQuad
+ | '\\U' HexQuad HexQuad
+ ;
+
+fragment
+HexQuad
+ : HexadecimalDigit HexadecimalDigit HexadecimalDigit HexadecimalDigit
+ ;
+
+Constant
+ : IntegerConstant
+ | FloatingConstant
+ //| EnumerationConstant
+ | CharacterConstant
+ ;
+
+fragment
+IntegerConstant
+ : DecimalConstant IntegerSuffix?
+ | OctalConstant IntegerSuffix?
+ | HexadecimalConstant IntegerSuffix?
+ | BinaryConstant
+ ;
+
+fragment
+BinaryConstant
+ : '0' [bB] [0-1]+
+ ;
+
+fragment
+DecimalConstant
+ : NonzeroDigit Digit*
+ ;
+
+fragment
+OctalConstant
+ : '0' OctalDigit*
+ ;
+
+fragment
+HexadecimalConstant
+ : HexadecimalPrefix HexadecimalDigit+
+ ;
+
+fragment
+HexadecimalPrefix
+ : '0' [xX]
+ ;
+
+fragment
+NonzeroDigit
+ : [1-9]
+ ;
+
+fragment
+OctalDigit
+ : [0-7]
+ ;
+
+fragment
+HexadecimalDigit
+ : [0-9a-fA-F]
+ ;
+
+fragment
+IntegerSuffix
+ : UnsignedSuffix LongSuffix?
+ | UnsignedSuffix LongLongSuffix
+ | LongSuffix UnsignedSuffix?
+ | LongLongSuffix UnsignedSuffix?
+ ;
+
+fragment
+UnsignedSuffix
+ : [uU]
+ ;
+
+fragment
+LongSuffix
+ : [lL]
+ ;
+
+fragment
+LongLongSuffix
+ : 'll' | 'LL'
+ ;
+
+fragment
+FloatingConstant
+ : DecimalFloatingConstant
+ | HexadecimalFloatingConstant
+ ;
+
+fragment
+DecimalFloatingConstant
+ : FractionalConstant ExponentPart? FloatingSuffix?
+ | DigitSequence ExponentPart FloatingSuffix?
+ ;
+
+fragment
+HexadecimalFloatingConstant
+ : HexadecimalPrefix (HexadecimalFractionalConstant | HexadecimalDigitSequence) BinaryExponentPart FloatingSuffix?
+ ;
+
+fragment
+FractionalConstant
+ : DigitSequence? '.' DigitSequence
+ | DigitSequence '.'
+ ;
+
+fragment
+ExponentPart
+ : [eE] Sign? DigitSequence
+ ;
+
+fragment
+Sign
+ : [+-]
+ ;
+
+DigitSequence
+ : Digit+
+ ;
+
+fragment
+HexadecimalFractionalConstant
+ : HexadecimalDigitSequence? '.' HexadecimalDigitSequence
+ | HexadecimalDigitSequence '.'
+ ;
+
+fragment
+BinaryExponentPart
+ : [pP] Sign? DigitSequence
+ ;
+
+fragment
+HexadecimalDigitSequence
+ : HexadecimalDigit+
+ ;
+
+fragment
+FloatingSuffix
+ : [flFL]
+ ;
+
+fragment
+CharacterConstant
+ : '\'' CCharSequence '\''
+ | 'L\'' CCharSequence '\''
+ | 'u\'' CCharSequence '\''
+ | 'U\'' CCharSequence '\''
+ ;
+
+fragment
+CCharSequence
+ : CChar+
+ ;
+
+fragment
+CChar
+ : ~['\\\r\n]
+ | EscapeSequence
+ ;
+
+fragment
+EscapeSequence
+ : SimpleEscapeSequence
+ | OctalEscapeSequence
+ | HexadecimalEscapeSequence
+ | UniversalCharacterName
+ ;
+
+fragment
+SimpleEscapeSequence
+ : '\\' ['"?abfnrtv\\]
+ ;
+
+fragment
+OctalEscapeSequence
+ : '\\' OctalDigit OctalDigit? OctalDigit?
+ ;
+
+fragment
+HexadecimalEscapeSequence
+ : '\\x' HexadecimalDigit+
+ ;
+
+StringLiteral
+ : EncodingPrefix? '"' SCharSequence? '"'
+ ;
+
+PathLiteral
+ : '<' ~[<> \t]+ '>'
+ ;
+
+fragment
+EncodingPrefix
+ : 'u8'
+ | 'u'
+ | 'U'
+ | 'L'
+ ;
+
+fragment
+SCharSequence
+ : SChar+
+ ;
+
+fragment
+SChar
+ : ~["\\\r\n]
+ | EscapeSequence
+ | '\\\n' // Added line
+ | '\\\r\n' // Added line
+ ;
+
+//MultiLineMacro:
+// '#' (~[\n]*? '\\' '\r'? '\n')+ ~ [\n]+ -> channel (HIDDEN);
+//
+//Directive: '#' ~ [\n]* -> channel (HIDDEN);
+
+NumberSign
+ : '#' -> channel (HIDDEN);
+
+AtSign
+ : '@' -> channel (HIDDEN);
+
+Dollar
+ : '$' -> channel (HIDDEN);
+
+// ignore the following asm blocks:
+/*
+ asm
+ {
+ mfspr x, 286;
+ }
+ */
+AsmBlock
+ : 'asm' ~'{'* '{' ~'}'* '}'
+ -> channel(HIDDEN)
+ ;
+
+Whitespace
+ : [ \t]+ -> channel(HIDDEN)
+ ;
+
+Newline
+ : ( '\r' '\n'?
+ | '\n'
+ )
+ -> channel(HIDDEN)
+ ;
+
+BlockComment
+ : '/*' .*? '*/'
+ -> channel(HIDDEN)
+ ;
+
+OpenBlockComment
+ : '/*' ~[*/]*
+ -> channel(HIDDEN)
+ ;
+
+LineComment
+ : '//' ~[\r\n]*
+ -> channel(HIDDEN)
+ ;
\ No newline at end of file
diff --git a/src/test/java/CPPParserTest.java b/src/test/java/CPPParserTest.java
index 54ff6a2eb..77b6ed19a 100644
--- a/src/test/java/CPPParserTest.java
+++ b/src/test/java/CPPParserTest.java
@@ -1,4 +1,4 @@
-import org.variantsync.diffdetective.variation.diff.parse.IllFormedAnnotationException;
+import org.variantsync.diffdetective.error.UnparseableFormulaException;
import org.variantsync.diffdetective.feature.CPPDiffLineFormulaExtractor;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.params.ParameterizedTest;
@@ -24,35 +24,89 @@ private static List testCases() {
new TestCase("#if A && B", "A&&B"),
new TestCase("#if A || B", "A||B"),
new TestCase("#if A && (B || C)", "A&&(B||C)"),
+ new TestCase("#if A && B || C", "A&&B||C"),
- new TestCase("#if 1 > -42", "1__GT____SUB__42"),
- new TestCase("#if 1 > +42", "1__GT____ADD__42"),
+ new TestCase("#if 1 > -42", "1__GT____U_MINUS__42"),
+ new TestCase("#if 1 > +42", "1__GT____U_PLUS__42"),
new TestCase("#if 42 > A", "42__GT__A"),
- new TestCase("#if 42 > ~A", "42__GT____NOT__A"),
+ new TestCase("#if 42 > ~A", "42__GT____U_TILDE__A"),
new TestCase("#if A + B > 42", "A__ADD__B__GT__42"),
new TestCase("#if A << B", "A__LSHIFT__B"),
- new TestCase("#if A ? B : C", "A__THEN__B__ELSE__C"),
+ new TestCase("#if A ? B : C", "A__THEN__B__COLON__C"),
new TestCase("#if A >= B && C > D", "A__GEQ__B&&C__GT__D"),
new TestCase("#if A * (B + C)", "A__MUL____LB__B__ADD__C__RB__"),
- new TestCase("#if defined(A) && (B * 2) > C", "DEFINED_A&&__LB__B__MUL__2__RB____GT__C"),
+ new TestCase("#if defined(A) && (B * 2) > C", "DEFINED___LB__A__RB__&&__LB__B__MUL__2__RB____GT__C"),
+ new TestCase("#if(STDC == 1) && (defined(LARGE) || defined(COMPACT))", "(STDC__EQ__1)&&(DEFINED___LB__LARGE__RB__||DEFINED___LB__COMPACT__RB__)"),
+ new TestCase("#if (('Z' - 'A') == 25)", "(__LB____SQUOTE__Z__SQUOTE____SUB____SQUOTE__A__SQUOTE____RB____EQ__25)"),
+ new TestCase("#if APR_CHARSET_EBCDIC && !(('Z' - 'A') == 25)", "APR_CHARSET_EBCDIC&&!(__LB____SQUOTE__Z__SQUOTE____SUB____SQUOTE__A__SQUOTE____RB____EQ__25)"),
+ new TestCase("# if ((GNUTLS_VERSION_MAJOR + (GNUTLS_VERSION_MINOR > 0 || GNUTLS_VERSION_PATCH >= 20)) > 3)",
+ "(__LB__GNUTLS_VERSION_MAJOR__ADD____LB__GNUTLS_VERSION_MINOR__GT__0__L_OR__GNUTLS_VERSION_PATCH__GEQ__20__RB____RB____GT__3)"),
+
+ new TestCase("#if A && (B > C)", "A&&(B__GT__C)"),
+ new TestCase("#if (A && B) > C", "__LB__A__L_AND__B__RB____GT__C"),
+ new TestCase("#if C == (A || B)", "C__EQ____LB__A__L_OR__B__RB__"),
+ new TestCase("#if ((A && B) > C)", "(__LB__A__L_AND__B__RB____GT__C)"),
+ new TestCase("#if A && ((B + 1) > (C || D))", "A&&(__LB__B__ADD__1__RB____GT____LB__C__L_OR__D__RB__)"),
+
+ new TestCase("#if __has_include", "HAS_INCLUDE_"),
+ new TestCase("#if defined __has_include", "DEFINED_HAS_INCLUDE_"),
+ new TestCase("#if __has_include()", "HAS_INCLUDE___LB____LT__nss3__DIV__nss__DOT__h__GT____RB__"),
+ new TestCase("#if __has_include()", "HAS_INCLUDE___LB____LT__nss__DOT__h__GT____RB__"),
+ new TestCase("#if __has_include(\"nss3/nss.h\")", "HAS_INCLUDE___LB____QUOTE__nss3__DIV__nss__DOT__h__QUOTE____RB__"),
+ new TestCase("#if __has_include(\"nss.h\")", "HAS_INCLUDE___LB____QUOTE__nss__DOT__h__QUOTE____RB__"),
+
+ new TestCase("#if __has_attribute", "HAS_ATTRIBUTE_"),
+ new TestCase("#if defined __has_attribute", "DEFINED_HAS_ATTRIBUTE_"),
+ new TestCase("# if __has_attribute (nonnull)", "HAS_ATTRIBUTE___LB__nonnull__RB__"),
+ new TestCase("#if defined __has_attribute && __has_attribute (nonnull)", "DEFINED_HAS_ATTRIBUTE_&&HAS_ATTRIBUTE___LB__nonnull__RB__"),
+
+ new TestCase("#if __has_cpp_attribute", "HAS_CPP_ATTRIBUTE_"),
+ new TestCase("#if defined __has_cpp_attribute", "DEFINED_HAS_CPP_ATTRIBUTE_"),
+ new TestCase("#if __has_cpp_attribute (nonnull)", "HAS_CPP_ATTRIBUTE___LB__nonnull__RB__"),
+ new TestCase("#if __has_cpp_attribute (nonnull) && A", "HAS_CPP_ATTRIBUTE___LB__nonnull__RB__&&A"),
+
+ new TestCase("#if defined __has_c_attribute", "DEFINED_HAS_C_ATTRIBUTE_"),
+ new TestCase("#if __has_c_attribute", "HAS_C_ATTRIBUTE_"),
+ new TestCase("#if __has_c_attribute (nonnull)", "HAS_C_ATTRIBUTE___LB__nonnull__RB__"),
+ new TestCase("#if __has_c_attribute (nonnull) && A", "HAS_C_ATTRIBUTE___LB__nonnull__RB__&&A"),
+
+ new TestCase("#if defined __has_builtin", "DEFINED_HAS_BUILTIN_"),
+ new TestCase("#if __has_builtin", "HAS_BUILTIN_"),
+ new TestCase("#if __has_builtin (__nonnull)", "HAS_BUILTIN___LB____nonnull__RB__"),
+ new TestCase("#if __has_builtin (nonnull) && A", "HAS_BUILTIN___LB__nonnull__RB__&&A"),
new TestCase("#if A // Comment && B", "A"),
new TestCase("#if A /* Comment */ && B", "A&&B"),
+ new TestCase("#if A && B /* Multiline Comment", "A&&B"),
new TestCase("#if A == B", "A__EQ__B"),
new TestCase("#if A == 1", "A__EQ__1"),
new TestCase("#if defined A", "DEFINED_A"),
- new TestCase("#if defined(A)", "DEFINED_A"),
- new TestCase("#if defined (A)", "DEFINED_A"),
- new TestCase("#if defined ( A )", "DEFINED_A"),
- new TestCase("#if (defined A)", "__LB__DEFINED_A__RB__"),
- new TestCase("#if MACRO (A)", "MACRO__LB__A__RB__"),
- new TestCase("#if MACRO (A, B)", "MACRO__LB__A__B__RB__"),
- new TestCase("#if MACRO (A, B + C)", "MACRO__LB__A__B__ADD__C__RB__"),
- new TestCase("#if MACRO (A, B) == 1", "MACRO__LB__A__B__RB____EQ__1"),
-
- new TestCase("#if ifndef", "ifndef")
+ new TestCase("#if defined(A)", "DEFINED___LB__A__RB__"),
+ new TestCase("#if defined (A)", "DEFINED___LB__A__RB__"),
+ new TestCase("#if defined ( A )", "DEFINED___LB__A__RB__"),
+ new TestCase("#if (defined A)", "(DEFINED_A)"),
+ new TestCase("#if MACRO (A)", "MACRO___LB__A__RB__"),
+ new TestCase("#if MACRO (A, B)", "MACRO___LB__A__B__RB__"),
+ new TestCase("#if MACRO (A, B + C)", "MACRO___LB__A__B__ADD__C__RB__"),
+ new TestCase("#if MACRO (A, B) == 1", "MACRO___LB__A__B__RB____EQ__1"),
+
+ new TestCase("#if ifndef", "ifndef"),
+
+ new TestCase("#if __has_include_next()", "__HAS_INCLUDE_NEXT___LB____LT__some__SUB__header__DOT__h__GT____RB__"),
+ new TestCase("#if __is_target_arch(x86)", "__IS_TARGET_ARCH___LB__x86__RB__"),
+ new TestCase("#if A || (defined(NAME) && (NAME >= 199630))", "A||(DEFINED___LB__NAME__RB__&&(NAME__GEQ__199630))"),
+ new TestCase("#if MACRO(part:part)", "MACRO___LB__part__COLON__part__RB__"),
+ new TestCase("#if MACRO(x=1)", "MACRO___LB__x__ASSIGN__1__RB__"),
+ new TestCase("#if A = 3", "A__ASSIGN__3"),
+ new TestCase("#if ' ' == 32", "__SQUOTE_____SQUOTE____EQ__32"),
+ new TestCase("#if (NAME<<1) > (1<= 199905) && (NAME < 1991011)) || (NAME >= 300000) || defined(NAME)", "(DEFINED___LB__NAME__RB__&&(NAME__GEQ__199905)&&(NAME__LT__1991011))||(NAME__GEQ__300000)||DEFINED___LB__NAME__RB__"),
+ new TestCase("#if __has_warning(\"-Wa-warning\"_foo)",
+ "__HAS_WARNING___LB____QUOTE____SUB__Wa__SUB__warning__QUOTE_____foo__RB__")
);
}
@@ -81,7 +135,7 @@ private static List wontfixTestCases() {
@ParameterizedTest
@MethodSource("testCases")
- public void testCase(TestCase testCase) throws IllFormedAnnotationException {
+ public void testCase(TestCase testCase) throws UnparseableFormulaException {
assertEquals(
testCase.expected,
new CPPDiffLineFormulaExtractor().extractFormula(testCase.formula())
@@ -91,7 +145,7 @@ public void testCase(TestCase testCase) throws IllFormedAnnotationException {
@ParameterizedTest
@MethodSource("throwingTestCases")
public void throwingTestCase(ThrowingTestCase testCase) {
- assertThrows(IllFormedAnnotationException.class, () ->
+ assertThrows(UnparseableFormulaException.class, () ->
new CPPDiffLineFormulaExtractor().extractFormula(testCase.formula)
);
}
@@ -99,7 +153,7 @@ public void throwingTestCase(ThrowingTestCase testCase) {
@Disabled("WONTFIX")
@ParameterizedTest
@MethodSource("wontfixTestCases")
- public void wontfixTestCase(TestCase testCase) throws IllFormedAnnotationException {
+ public void wontfixTestCase(TestCase testCase) throws UnparseableFormulaException {
assertEquals(
testCase.expected,
new CPPDiffLineFormulaExtractor().extractFormula(testCase.formula())
diff --git a/src/test/java/MarlinDebug.java b/src/test/java/MarlinDebug.java
index 3e855e631..465a8a141 100644
--- a/src/test/java/MarlinDebug.java
+++ b/src/test/java/MarlinDebug.java
@@ -13,10 +13,10 @@
import org.variantsync.diffdetective.datasets.Repository;
import org.variantsync.diffdetective.diff.git.CommitDiff;
import org.variantsync.diffdetective.diff.git.PatchDiff;
+import org.variantsync.diffdetective.error.UnparseableFormulaException;
import org.variantsync.diffdetective.variation.DiffLinesLabel;
import org.variantsync.diffdetective.variation.diff.VariationDiff;
import org.variantsync.diffdetective.variation.diff.parse.VariationDiffParser;
-import org.variantsync.diffdetective.variation.diff.parse.IllFormedAnnotationException;
import org.variantsync.diffdetective.variation.diff.transform.VariationDiffTransformer;
import org.variantsync.diffdetective.feature.CPPAnnotationParser;
import org.variantsync.diffdetective.mining.VariationDiffMiner;
@@ -173,7 +173,7 @@ public void testPHP() throws Exception {
}
@Test
- public void testFormulaParsing() throws IllFormedAnnotationException {
+ public void testFormulaParsing() throws UnparseableFormulaException {
final String original = "#if defined ( a ) && x > 200 + 2 && A && (foo(3, 4) || bar ( 3 , 4, 9, baz(3)) || z==3-1) && h<=7/2 && x == 4 % 2 && m>=k && k<11*3";
// String adapted = original;
// adapted = adapted.replaceAll("\\(\\)", "");
diff --git a/src/test/java/TestMultiLineMacros.java b/src/test/java/TestMultiLineMacros.java
index 1f9cc097d..2ebc48dfe 100644
--- a/src/test/java/TestMultiLineMacros.java
+++ b/src/test/java/TestMultiLineMacros.java
@@ -1,4 +1,5 @@
import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
import org.junit.jupiter.params.provider.ValueSource;
import org.tinylog.Logger;
import org.variantsync.diffdetective.variation.DiffLinesLabel;
@@ -23,44 +24,20 @@
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.stream.Stream;
public class TestMultiLineMacros {
- private static final Path resDir = Constants.RESOURCE_DIR.resolve("multilinemacros");
- public void diffToVariationDiff(LineGraphExportOptions exportOptions, Path p) throws IOException, DiffParseException {
- VariationDiff tree;
- try (BufferedReader fullDiff = Files.newBufferedReader(p)) {
- tree = VariationDiffParser.createVariationDiff(
- fullDiff,
- new VariationDiffParseOptions(
- CPPAnnotationParser.Default,
- true,
- false
- ));
- }
+ private final static Path testDir = Constants.RESOURCE_DIR.resolve("multilinemacros");
- try (var destination = IO.newBufferedOutputStream(resDir.resolve("gen").resolve(p.getFileName() + ".lg"))) {
- destination.write(("t # 1" + StringUtils.LINEBREAK).getBytes());
-
- final VariationDiffSerializeDebugData debugData = LineGraphExport.toLineGraphFormat(tree, exportOptions, destination);
- assertNotNull(debugData);
- Logger.info("Parsed {} nodes of diff type NON.", debugData.numExportedNonNodes);
- Logger.info("Parsed {} nodes of diff type ADD.", debugData.numExportedAddNodes);
- Logger.info("Parsed {} nodes of diff type REM.", debugData.numExportedRemNodes);
-
- }
+ public static Stream multilineTests() throws IOException {
+ return VariationDiffParserTest.findTestCases(testDir);
}
@ParameterizedTest
- @ValueSource(strings = { "mldiff1.txt", "diffWithComments.txt" })
- public void test(String filename) throws IOException, DiffParseException {
- final LineGraphExportOptions exportOptions = new LineGraphExportOptions<>(
- GraphFormat.VARIATION_DIFF,
- new CommitDiffVariationDiffLabelFormat(),
- new DebugDiffNodeFormat<>(),
- new DefaultEdgeLabelFormat<>()
- );
-
- diffToVariationDiff(exportOptions, resDir.resolve(filename));
+ @MethodSource("multilineTests")
+ public void testMultiline(Path basename) throws IOException, DiffParseException {
+ VariationDiffParserTest.testCase(basename);
}
}
diff --git a/src/test/java/TestUtils.java b/src/test/java/TestUtils.java
index 6f6593ed6..77e5c5548 100644
--- a/src/test/java/TestUtils.java
+++ b/src/test/java/TestUtils.java
@@ -12,8 +12,6 @@ public final class TestUtils {
/**
* Compare two line graphs.
*
- * @param originalLineGraph The original line graph
- * @param generatedLineGraph The generated line graph
*/
public static void assertEqualToFile(final Path filePath, final String actual) throws IOException {
try (BufferedReader expected = Files.newBufferedReader(filePath)) {
diff --git a/src/test/java/VariationDiffParserTest.java b/src/test/java/VariationDiffParserTest.java
index 9e6666731..4c1d4e48f 100644
--- a/src/test/java/VariationDiffParserTest.java
+++ b/src/test/java/VariationDiffParserTest.java
@@ -26,7 +26,7 @@ public class VariationDiffParserTest {
private final static Path testDir = Constants.RESOURCE_DIR.resolve("diffs").resolve("parser");
private final static String testCaseSuffix = ".diff";
- private static Stream findTestCases(Path dir) throws IOException {
+ protected static Stream findTestCases(Path dir) throws IOException {
return Files
.list(dir)
.filter(filename -> filename.getFileName().toString().endsWith(testCaseSuffix));
@@ -53,11 +53,11 @@ public void wontfixTest(Path testCase) throws IOException, DiffParseException {
testCase(testCase);
}
- public void testCase(Path testCasePath) throws IOException, DiffParseException {
+ public static void testCase(Path testCasePath) throws IOException, DiffParseException {
String filename = testCasePath.getFileName().toString();
String basename = filename.substring(0, filename.length() - testCaseSuffix.length());
- var actualPath = testDir.resolve(basename + "_actual.lg");
- var expectedPath = testDir.resolve(basename + "_expected.lg");
+ var actualPath = testCasePath.getParent().resolve(basename + "_actual.lg");
+ var expectedPath = testCasePath.getParent().resolve(basename + "_expected.lg");
VariationDiff variationDiff;
try (var inputFile = Files.newBufferedReader(testCasePath)) {
@@ -84,7 +84,7 @@ public void testCase(Path testCasePath) throws IOException, DiffParseException {
Files.delete(actualPath);
} else {
// Keep output files if the test failed
- var visualizationPath = testDir.resolve("tex").resolve(basename + ".tex");
+ var visualizationPath = testCasePath.getParent().resolve("tex").resolve(basename + ".tex");
new TikzExporter<>(new Format<>(new FullNodeFormat(), new DefaultEdgeLabelFormat<>()))
.exportFullLatexExample(variationDiff, visualizationPath);
fail("The VariationDiff in file " + testCasePath + " didn't parse correctly. "
diff --git a/src/test/resources/diffs/differ/a032346092e47048becb36a7cb183b4739547370.lg b/src/test/resources/diffs/differ/a032346092e47048becb36a7cb183b4739547370.lg
index 3b29f682f..042ba288a 100644
--- a/src/test/resources/diffs/differ/a032346092e47048becb36a7cb183b4739547370.lg
+++ b/src/test/resources/diffs/differ/a032346092e47048becb36a7cb183b4739547370.lg
@@ -5,7 +5,7 @@ v 275 NON;ARTIFACT;(old: 3, diff: 3, new: 3);(old: 4, diff: 4, new: 4);;
v 336 NON;IF;(old: 4, diff: 4, new: 4);(old: 33, diff: 33, new: 33);-_DB_STL_RESOURCE_MANAGER_H__;#ifndef _DB_STL_RESOURCE_MANAGER_H__
v 403 NON;ARTIFACT;(old: 5, diff: 5, new: 5);(old: 6, diff: 6, new: 6);;#include
v 467 NON;ARTIFACT;(old: 6, diff: 6, new: 6);(old: 7, diff: 7, new: 7);;
-v 528 NON;IF;(old: 7, diff: 7, new: 7);(old: 9, diff: 9, new: 9);-DEFINED_MESSAGE;#if !defined (MESSAGE)
+v 528 NON;IF;(old: 7, diff: 7, new: 7);(old: 9, diff: 9, new: 9);-DEFINED___LB__MESSAGE__RB__;#if !defined (MESSAGE)
v 595 NON;ARTIFACT;(old: 8, diff: 8, new: 8);(old: 9, diff: 9, new: 9);; #define MESSAGE "You wish!"
v 657 NON;ELSE;(old: 9, diff: 9, new: 9);(old: 11, diff: 11, new: 11);;#else
v 723 NON;ARTIFACT;(old: 10, diff: 10, new: 10);(old: 11, diff: 11, new: 11);; // do nothing
@@ -13,14 +13,14 @@ v 851 NON;ARTIFACT;(old: 12, diff: 12, new: 12);(old: 13, diff: 13, new: 13);;
v 915 NON;ARTIFACT;(old: 13, diff: 13, new: 13);(old: 14, diff: 14, new: 14);;int main(void) {
v 979 NON;ARTIFACT;(old: 14, diff: 14, new: 14);(old: 15, diff: 15, new: 15);; printf("Here is the message: %s\n", MESSAGE);
v 1043 NON;ARTIFACT;(old: 15, diff: 15, new: 15);(old: 16, diff: 16, new: 16);;
-v 1104 NON;IF;(old: 16, diff: 16, new: 16);(old: 21, diff: 21, new: 21);(-DEFINED_HAVE_GETHOSTBYNAME_R | -DEFINED_HAVE_GETHOSTBYADDR_R | -DEFINED_HAVE_GETPWUID_R | -DEFINED_HAVE_GETGRGID_R) & (-DEFINED_HAVE_MTSAFE_GETHOSTBYNAME | -DEFINED_HAVE_MTSAFE_GETHOSTBYADDR);#if (!defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETHOSTBYADDR_R) || \; !defined(HAVE_GETPWUID_R) || !defined(HAVE_GETGRGID_R)) && \; (!defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR))
+v 1104 NON;IF;(old: 16, diff: 16, new: 16);(old: 21, diff: 21, new: 21);(-DEFINED___LB__HAVE_GETHOSTBYNAME_R__RB__ | -DEFINED___LB__HAVE_GETHOSTBYADDR_R__RB__ | -DEFINED___LB__HAVE_GETPWUID_R__RB__ | -DEFINED___LB__HAVE_GETGRGID_R__RB__) & (-DEFINED___LB__HAVE_MTSAFE_GETHOSTBYNAME__RB__ | -DEFINED___LB__HAVE_MTSAFE_GETHOSTBYADDR__RB__);#if (!defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETHOSTBYADDR_R) || \; !defined(HAVE_GETPWUID_R) || !defined(HAVE_GETGRGID_R)) && \; (!defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR))
v 1299 NON;ARTIFACT;(old: 19, diff: 19, new: 19);(old: 20, diff: 20, new: 20);; blabla
v 1363 NON;ARTIFACT;(old: 20, diff: 20, new: 20);(old: 21, diff: 21, new: 21);; blabla
v 1619 NON;ARTIFACT;(old: 24, diff: 24, new: 24);(old: 25, diff: 25, new: 25);;
-v 1680 NON;IF;(old: 25, diff: 25, new: 25);(old: 28, diff: 28, new: 28);(-DEFINED_HAVE_GETHOSTBYNAME_R | -DEFINED_HAVE_GETHOSTBYADDR_R) & (-DEFINED_HAVE_MTSAFE_GETHOSTBYNAME | -DEFINED_HAVE_MTSAFE_GETHOSTBYADDR);#if (!defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETHOSTBYADDR_R)) && \; (!defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR))
+v 1680 NON;IF;(old: 25, diff: 25, new: 25);(old: 28, diff: 28, new: 28);(-DEFINED___LB__HAVE_GETHOSTBYNAME_R__RB__ | -DEFINED___LB__HAVE_GETHOSTBYADDR_R__RB__) & (-DEFINED___LB__HAVE_MTSAFE_GETHOSTBYNAME__RB__ | -DEFINED___LB__HAVE_MTSAFE_GETHOSTBYADDR__RB__);#if (!defined(HAVE_GETHOSTBYNAME_R) || !defined(HAVE_GETHOSTBYADDR_R)) && \; (!defined(HAVE_MTSAFE_GETHOSTBYNAME) || !defined(HAVE_MTSAFE_GETHOSTBYADDR))
v 1811 NON;ARTIFACT;(old: 27, diff: 27, new: 27);(old: 28, diff: 28, new: 28);;hello
v 1939 NON;ARTIFACT;(old: 29, diff: 29, new: 29);(old: 30, diff: 30, new: 30);;}
-v 2000 NON;IF;(old: 30, diff: 30, new: 30);(old: 32, diff: 32, new: 32);DEFINED_MESSAGE;#if defined (MESSAGE)
+v 2000 NON;IF;(old: 30, diff: 30, new: 30);(old: 32, diff: 32, new: 32);DEFINED___LB__MESSAGE__RB__;#if defined (MESSAGE)
v 2067 NON;ARTIFACT;(old: 31, diff: 31, new: 31);(old: 32, diff: 32, new: 32);; #define MESSAGE "You wish!"
e 147 16 ba;0,0
e 211 16 ba;1,1
diff --git a/src/test/resources/diffs/parser/12_expected.lg b/src/test/resources/diffs/parser/12_expected.lg
index 62a68f6e6..6a1964001 100644
--- a/src/test/resources/diffs/parser/12_expected.lg
+++ b/src/test/resources/diffs/parser/12_expected.lg
@@ -1,5 +1,5 @@
v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
-v 144 NON;IF;(old: 1, diff: 1, new: 1);(old: 3, diff: 3, new: 3);DEFINED_A;#if defined(A)
+v 144 NON;IF;(old: 1, diff: 1, new: 1);(old: 3, diff: 3, new: 3);DEFINED___LB__A__RB__;#if defined(A)
v 211 NON;ARTIFACT;(old: 2, diff: 2, new: 2);(old: 3, diff: 3, new: 3);;Code
e 144 16 ba;0,0
e 211 144 ba;0,0
diff --git a/src/test/resources/diffs/parser/17_expected.lg b/src/test/resources/diffs/parser/17_expected.lg
index 9f5eed2f5..718641f8a 100644
--- a/src/test/resources/diffs/parser/17_expected.lg
+++ b/src/test/resources/diffs/parser/17_expected.lg
@@ -1,7 +1,7 @@
v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
v 136 REM;IF;(old: 1, diff: 1, new: -1);(old: 2, diff: 3, new: -1);A;#ifdef A
v 265 REM;ELSE;(old: 2, diff: 3, new: -1);(old: 3, diff: 5, new: -1);;#else
-v 192 ADD;IF;(old: -1, diff: 2, new: 1);(old: -1, diff: 4, new: 3);B##else;#ifdef B #\;#else
+v 192 ADD;IF;(old: -1, diff: 2, new: 1);(old: -1, diff: 4, new: 3);B;#ifdef B #\;#else
e 136 16 b;0,-1
e 265 136 b;0,-1
e 192 16 a;-1,0
diff --git a/src/test/resources/multilinemacros/.gitignore b/src/test/resources/multilinemacros/.gitignore
new file mode 100644
index 000000000..0fe60ec07
--- /dev/null
+++ b/src/test/resources/multilinemacros/.gitignore
@@ -0,0 +1,2 @@
+*_actual.lg
+tex/
\ No newline at end of file
diff --git a/src/test/resources/multilinemacros/diffWithComments.txt b/src/test/resources/multilinemacros/diffWithComments.diff
similarity index 82%
rename from src/test/resources/multilinemacros/diffWithComments.txt
rename to src/test/resources/multilinemacros/diffWithComments.diff
index 196f062c1..220fb2009 100644
--- a/src/test/resources/multilinemacros/diffWithComments.txt
+++ b/src/test/resources/multilinemacros/diffWithComments.diff
@@ -1,7 +1,7 @@
+#define multi \
+kulti
- /** hihi **\
+ /** hihi **/
//\
a
diff --git a/src/test/resources/multilinemacros/diffWithComments_expected.lg b/src/test/resources/multilinemacros/diffWithComments_expected.lg
new file mode 100644
index 000000000..ce94c7e49
--- /dev/null
+++ b/src/test/resources/multilinemacros/diffWithComments_expected.lg
@@ -0,0 +1,18 @@
+v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
+v 275 NON;ARTIFACT;(old: 1, diff: 3, new: 3);(old: 2, diff: 4, new: 4);;
+v 339 NON;ARTIFACT;(old: 2, diff: 4, new: 4);(old: 3, diff: 5, new: 5);;/** hihi **/
+v 403 NON;ARTIFACT;(old: 3, diff: 5, new: 5);(old: 4, diff: 6, new: 6);;
+v 467 NON;ARTIFACT;(old: 4, diff: 6, new: 6);(old: 6, diff: 8, new: 8);;//\;a
+v 595 NON;ARTIFACT;(old: 6, diff: 8, new: 8);(old: 7, diff: 9, new: 9);;
+v 723 NON;ARTIFACT;(old: 7, diff: 10, new: 10);(old: 8, diff: 11, new: 11);;foo();
+v 131 ADD;ARTIFACT;(old: -1, diff: 1, new: 1);(old: -1, diff: 3, new: 3);;#define multi \;kulti
+v 640 ADD;IF;(old: -1, diff: 9, new: 9);(old: -1, diff: 11, new: 11);A&B;#if A & B
+e 275 16 ba;0,1
+e 339 16 ba;1,2
+e 403 16 ba;2,3
+e 467 16 ba;3,4
+e 595 16 ba;4,5
+e 723 16 b;5,-1
+e 723 640 a;-1,0
+e 131 16 a;-1,0
+e 640 16 a;-1,6
diff --git a/src/test/resources/multilinemacros/inline_comments_1.diff b/src/test/resources/multilinemacros/inline_comments_1.diff
new file mode 100644
index 000000000..dd9989878
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_1.diff
@@ -0,0 +1,13 @@
+ # if A && /* inline
++ comment */ C \
+- comment */ B \
+ && D
+ baz();
+ #endif
+
+ # if A && /* inline
+ comment */ C \
+ && D
++ baz();
+- vaz();
+ #endif
diff --git a/src/test/resources/multilinemacros/inline_comments_1_expected.lg b/src/test/resources/multilinemacros/inline_comments_1_expected.lg
new file mode 100644
index 000000000..241ccd6d1
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_1_expected.lg
@@ -0,0 +1,16 @@
+v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
+v 136 REM;IF;(old: 1, diff: 1, new: -1);(old: 5, diff: 6, new: -1);A & B & D;# if A && /* inline; comment */ B \; && D
+v 403 NON;ARTIFACT;(old: 4, diff: 5, new: 4);(old: 5, diff: 6, new: 5);; baz();
+v 531 NON;ARTIFACT;(old: 6, diff: 7, new: 6);(old: 7, diff: 8, new: 7);;
+v 592 NON;IF;(old: 7, diff: 8, new: 7);(old: 11, diff: 13, new: 11);A & C & D;# if A && /* inline;comment */ C \; && D
+v 843 REM;ARTIFACT;(old: 10, diff: 12, new: -1);(old: 11, diff: 13, new: -1);; vaz();
+v 771 ADD;ARTIFACT;(old: -1, diff: 11, new: 10);(old: -1, diff: 12, new: 11);; baz();
+v 128 ADD;IF;(old: -1, diff: 1, new: 1);(old: -1, diff: 6, new: 5);A & C & D;# if A && /* inline; comment */ C \; && D
+e 136 16 b;0,-1
+e 403 136 b;0,-1
+e 403 128 a;-1,0
+e 531 16 ba;1,1
+e 592 16 ba;2,2
+e 843 592 b;0,-1
+e 771 592 a;-1,0
+e 128 16 a;-1,0
diff --git a/src/test/resources/multilinemacros/inline_comments_2.diff b/src/test/resources/multilinemacros/inline_comments_2.diff
new file mode 100644
index 000000000..437398b1c
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_2.diff
@@ -0,0 +1,17 @@
+ # if A && \
+ /* inline
+ comment */ \
++ C \
+- B \
+ && D
+ baz();
+ #endif
+
+ # if A && \
+ /* inline
+ comment */ \
+ B \
+ && D
++ baz();
+- vaz();
+ #endif
diff --git a/src/test/resources/multilinemacros/inline_comments_2_expected.lg b/src/test/resources/multilinemacros/inline_comments_2_expected.lg
new file mode 100644
index 000000000..cb4af0742
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_2_expected.lg
@@ -0,0 +1,16 @@
+v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
+v 136 REM;IF;(old: 1, diff: 1, new: -1);(old: 7, diff: 8, new: -1);A & B & D;# if A && \;/* inline;comment */ \; B \; && D
+v 531 NON;ARTIFACT;(old: 6, diff: 7, new: 6);(old: 7, diff: 8, new: 7);; baz();
+v 659 NON;ARTIFACT;(old: 8, diff: 9, new: 8);(old: 9, diff: 10, new: 9);;
+v 720 NON;IF;(old: 9, diff: 10, new: 9);(old: 15, diff: 17, new: 15);A & B & D;# if A && \;/* inline;comment */ \; B \; && D
+v 1099 REM;ARTIFACT;(old: 14, diff: 16, new: -1);(old: 15, diff: 17, new: -1);; vaz();
+v 1027 ADD;ARTIFACT;(old: -1, diff: 15, new: 14);(old: -1, diff: 16, new: 15);; baz();
+v 128 ADD;IF;(old: -1, diff: 1, new: 1);(old: -1, diff: 8, new: 7);A & C & D;# if A && \;/* inline;comment */ \; C \; && D
+e 136 16 b;0,-1
+e 531 136 b;0,-1
+e 531 128 a;-1,0
+e 659 16 ba;1,1
+e 720 16 ba;2,2
+e 1099 720 b;0,-1
+e 1027 720 a;-1,0
+e 128 16 a;-1,0
diff --git a/src/test/resources/multilinemacros/inline_comments_3.diff b/src/test/resources/multilinemacros/inline_comments_3.diff
new file mode 100644
index 000000000..739fb19fc
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_3.diff
@@ -0,0 +1,21 @@
+ # if A && \
+ /* inline
+ comment
+ with multiple
+ lines
+ */ \
++ C \
+- B \
+ && D
+ baz();
+ #endif
+
+ # if A && /* inline
+ comment
+ with multiple
+ lines */ \
+ B \
+ && D
++ baz();
+- vaz();
+ #endif
diff --git a/src/test/resources/multilinemacros/inline_comments_3_expected.lg b/src/test/resources/multilinemacros/inline_comments_3_expected.lg
new file mode 100644
index 000000000..7ea557356
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_3_expected.lg
@@ -0,0 +1,16 @@
+v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
+v 136 REM;IF;(old: 1, diff: 1, new: -1);(old: 10, diff: 11, new: -1);A & B & D;# if A && \;/* inline;comment;with multiple;lines;*/ \; B \; && D
+v 723 NON;ARTIFACT;(old: 9, diff: 10, new: 9);(old: 10, diff: 11, new: 10);; baz();
+v 851 NON;ARTIFACT;(old: 11, diff: 12, new: 11);(old: 12, diff: 13, new: 12);;
+v 912 NON;IF;(old: 12, diff: 13, new: 12);(old: 19, diff: 21, new: 19);A & B & D;# if A && /* inline;comment;with multiple;lines */ \; B \; && D
+v 1355 REM;ARTIFACT;(old: 18, diff: 20, new: -1);(old: 19, diff: 21, new: -1);; vaz();
+v 1283 ADD;ARTIFACT;(old: -1, diff: 19, new: 18);(old: -1, diff: 20, new: 19);; baz();
+v 128 ADD;IF;(old: -1, diff: 1, new: 1);(old: -1, diff: 11, new: 10);A & C & D;# if A && \;/* inline;comment;with multiple;lines;*/ \; C \; && D
+e 136 16 b;0,-1
+e 723 136 b;0,-1
+e 723 128 a;-1,0
+e 851 16 ba;1,1
+e 912 16 ba;2,2
+e 1355 912 b;0,-1
+e 1283 912 a;-1,0
+e 128 16 a;-1,0
diff --git a/src/test/resources/multilinemacros/inline_comments_4.diff b/src/test/resources/multilinemacros/inline_comments_4.diff
new file mode 100644
index 000000000..590ce95de
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_4.diff
@@ -0,0 +1,18 @@
+ # if A && /* multiple inline
+ comments */ B && /* that */ C && /*
+ are distributed
+ */ \
++ E \
+- B \
+ && D
+ baz();
+ #endif
+
+ # if A && /* multiple inline
+ comments */ B && /* that */ C /*
+ are distributed
+ */ \
+ && D
++ baz();
+- vaz();
+ #endif
diff --git a/src/test/resources/multilinemacros/inline_comments_4_expected.lg b/src/test/resources/multilinemacros/inline_comments_4_expected.lg
new file mode 100644
index 000000000..a25a1a85c
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_4_expected.lg
@@ -0,0 +1,16 @@
+v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
+v 136 REM;IF;(old: 1, diff: 1, new: -1);(old: 8, diff: 9, new: -1);A & B & C & B & D;# if A && /* multiple inline;comments */ B && /* that */ C && /*;are distributed;*/ \; B \; && D
+v 595 NON;ARTIFACT;(old: 7, diff: 8, new: 7);(old: 8, diff: 9, new: 8);; baz();
+v 723 NON;ARTIFACT;(old: 9, diff: 10, new: 9);(old: 10, diff: 11, new: 10);;
+v 784 NON;IF;(old: 10, diff: 11, new: 10);(old: 16, diff: 18, new: 16);A & B & C & D;# if A && /* multiple inline;comments */ B && /* that */ C /*;are distributed;*/ \; && D
+v 1163 REM;ARTIFACT;(old: 15, diff: 17, new: -1);(old: 16, diff: 18, new: -1);; vaz();
+v 1091 ADD;ARTIFACT;(old: -1, diff: 16, new: 15);(old: -1, diff: 17, new: 16);; baz();
+v 128 ADD;IF;(old: -1, diff: 1, new: 1);(old: -1, diff: 9, new: 8);A & B & C & E & D;# if A && /* multiple inline;comments */ B && /* that */ C && /*;are distributed;*/ \; E \; && D
+e 136 16 b;0,-1
+e 595 136 b;0,-1
+e 595 128 a;-1,0
+e 723 16 ba;1,1
+e 784 16 ba;2,2
+e 1163 784 b;0,-1
+e 1091 784 a;-1,0
+e 128 16 a;-1,0
diff --git a/src/test/resources/multilinemacros/inline_comments_5.diff b/src/test/resources/multilinemacros/inline_comments_5.diff
new file mode 100644
index 000000000..5a87616d2
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_5.diff
@@ -0,0 +1,17 @@
+ # if A && /* inline
++ comment */ C \
+- comment */ B \
+ && D //* no continuation
+ baz();
+ #endif
+
+ # if A && /* inline
+ comment */ C \
+ && D //* no continuation
++ baz();
+- vaz();
+ #endif
+
+ //*ptr=something
+ //other comment /* inner
+ text
diff --git a/src/test/resources/multilinemacros/inline_comments_5_expected.lg b/src/test/resources/multilinemacros/inline_comments_5_expected.lg
new file mode 100644
index 000000000..0c22c138a
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_5_expected.lg
@@ -0,0 +1,24 @@
+v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
+v 136 REM;IF;(old: 1, diff: 1, new: -1);(old: 5, diff: 6, new: -1);A & B & D;# if A && /* inline; comment */ B \; && D //* no continuation
+v 403 NON;ARTIFACT;(old: 4, diff: 5, new: 4);(old: 5, diff: 6, new: 5);; baz();
+v 531 NON;ARTIFACT;(old: 6, diff: 7, new: 6);(old: 7, diff: 8, new: 7);;
+v 592 NON;IF;(old: 7, diff: 8, new: 7);(old: 11, diff: 13, new: 11);A & C & D;# if A && /* inline;comment */ C \; && D //* no continuation
+v 843 REM;ARTIFACT;(old: 10, diff: 12, new: -1);(old: 11, diff: 13, new: -1);; vaz();
+v 771 ADD;ARTIFACT;(old: -1, diff: 11, new: 10);(old: -1, diff: 12, new: 11);; baz();
+v 979 NON;ARTIFACT;(old: 12, diff: 14, new: 12);(old: 13, diff: 15, new: 13);;
+v 1043 NON;ARTIFACT;(old: 13, diff: 15, new: 13);(old: 14, diff: 16, new: 14);;//*ptr=something
+v 1107 NON;ARTIFACT;(old: 14, diff: 16, new: 14);(old: 15, diff: 17, new: 15);;//other comment /* inner
+v 1171 NON;ARTIFACT;(old: 15, diff: 17, new: 15);(old: 16, diff: 18, new: 16);;text
+v 128 ADD;IF;(old: -1, diff: 1, new: 1);(old: -1, diff: 6, new: 5);A & C & D;# if A && /* inline; comment */ C \; && D //* no continuation
+e 136 16 b;0,-1
+e 403 136 b;0,-1
+e 403 128 a;-1,0
+e 531 16 ba;1,1
+e 592 16 ba;2,2
+e 843 592 b;0,-1
+e 771 592 a;-1,0
+e 979 16 ba;3,3
+e 1043 16 ba;4,4
+e 1107 16 ba;5,5
+e 1171 16 ba;6,6
+e 128 16 a;-1,0
diff --git a/src/test/resources/multilinemacros/inline_comments_6.diff b/src/test/resources/multilinemacros/inline_comments_6.diff
new file mode 100644
index 000000000..2fdc295f6
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_6.diff
@@ -0,0 +1,7 @@
+ # if A && /* inline
+ // Some inner line comment
++ comment */ C \
+- comment */ B \
+ && D
+ baz();
+ #endif
diff --git a/src/test/resources/multilinemacros/inline_comments_6_expected.lg b/src/test/resources/multilinemacros/inline_comments_6_expected.lg
new file mode 100644
index 000000000..91805d3cf
--- /dev/null
+++ b/src/test/resources/multilinemacros/inline_comments_6_expected.lg
@@ -0,0 +1,8 @@
+v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
+v 136 REM;IF;(old: 1, diff: 1, new: -1);(old: 6, diff: 7, new: -1);A & B & D;# if A && /* inline;// Some inner line comment; comment */ B \; && D
+v 467 NON;ARTIFACT;(old: 5, diff: 6, new: 5);(old: 6, diff: 7, new: 6);; baz();
+v 128 ADD;IF;(old: -1, diff: 1, new: 1);(old: -1, diff: 7, new: 6);A & C & D;# if A && /* inline;// Some inner line comment; comment */ C \; && D
+e 136 16 b;0,-1
+e 467 136 b;0,-1
+e 467 128 a;-1,0
+e 128 16 a;-1,0
diff --git a/src/test/resources/multilinemacros/mldiff1.txt b/src/test/resources/multilinemacros/mldiff1.diff
similarity index 100%
rename from src/test/resources/multilinemacros/mldiff1.txt
rename to src/test/resources/multilinemacros/mldiff1.diff
diff --git a/src/test/resources/multilinemacros/mldiff1_expected.lg b/src/test/resources/multilinemacros/mldiff1_expected.lg
new file mode 100644
index 000000000..327fb093e
--- /dev/null
+++ b/src/test/resources/multilinemacros/mldiff1_expected.lg
@@ -0,0 +1,43 @@
+v 16 NON;IF;(old: -1, diff: -1, new: -1);(old: -1, diff: -1, new: -1);True
+v 147 NON;ARTIFACT;(old: 1, diff: 1, new: 1);(old: 2, diff: 2, new: 2);;code0
+v 208 NON;IF;(old: 2, diff: 2, new: 2);(old: 5, diff: 5, new: 5);-(DEFINED___LB____FreeBSD____RB__ | DEFINED___LB____OpenBSD____RB__ | DEFINED___LB____NetBSD____RB__ | DEFINED___LB____NEWLINE____RB__);#if !(defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \; || defined(__NEWLINE__))
+v 339 NON;ARTIFACT;(old: 4, diff: 4, new: 4);(old: 5, diff: 5, new: 5);; foo();
+v 467 NON;ARTIFACT;(old: 6, diff: 6, new: 6);(old: 7, diff: 7, new: 7);;code1
+v 659 NON;ARTIFACT;(old: 7, diff: 9, new: 9);(old: 8, diff: 10, new: 10);; bar();
+v 787 NON;ARTIFACT;(old: 8, diff: 11, new: 11);(old: 9, diff: 12, new: 12);;code2
+v 840 REM;IF;(old: 9, diff: 12, new: -1);(old: 13, diff: 17, new: -1);DEFINED___UCLIBC__ & REMOVED_FEATURE & lol;# if defined __UCLIBC__ && ( \; REMOVED_FEATURE \; ) && lol
+v 1107 NON;ARTIFACT;(old: 12, diff: 16, new: 15);(old: 13, diff: 17, new: 16);; baz();
+v 1235 NON;ARTIFACT;(old: 14, diff: 18, new: 17);(old: 15, diff: 19, new: 18);;code3
+v 1288 REM;IF;(old: 15, diff: 19, new: -1);(old: 18, diff: 24, new: -1);A & REMOVED_FEATURE;# if A && ( \; REMOVED_FEATURE)
+v 1555 NON;ARTIFACT;(old: 17, diff: 23, new: 21);(old: 18, diff: 24, new: 22);; cat();
+v 1683 NON;ARTIFACT;(old: 19, diff: 25, new: 23);(old: 20, diff: 26, new: 24);;code4
+v 1736 REM;IF;(old: 20, diff: 26, new: -1);(old: 23, diff: 30, new: -1);X & Y | W;#if (X && Y) \; || W
+v 1939 NON;ARTIFACT;(old: 22, diff: 29, new: 27);(old: 23, diff: 30, new: 28);; dog();
+v 2067 NON;ARTIFACT;(old: 24, diff: 31, new: 29);(old: 25, diff: 32, new: 30);;code5
+v 512 ADD;IF;(old: -1, diff: 7, new: 7);(old: -1, diff: 10, new: 10);ENABLE_FEATURE_LESS_DASHCMD & ENABLE_FEATURE_LESS_LINENUMS | DEFINED___LB____NEWLINE____RB__;#if (ENABLE_FEATURE_LESS_DASHCMD && ENABLE_FEATURE_LESS_LINENUMS) \; || defined(__NEWLINE__)
+v 832 ADD;IF;(old: -1, diff: 12, new: 12);(old: -1, diff: 17, new: 16);DEFINED___UCLIBC__ & ADDED_FEATURE & lol;# if defined __UCLIBC__ && ( \; ADDED_FEATURE \; ) && lol
+v 1280 ADD;IF;(old: -1, diff: 19, new: 18);(old: -1, diff: 24, new: 22);A & (ADDED_FEATURE1 | ADDED_FEATURE2) & lol;# if A && ( \; ADDED_FEATURE1 || ADDED_FEATURE2 \; ) && lol
+v 1728 ADD;IF;(old: -1, diff: 26, new: 24);(old: -1, diff: 30, new: 28);X & Y | DEFINED___LB__Z__RB__ | W;#if (X && Y) \; || defined(Z) \; || W
+e 147 16 ba;0,0
+e 208 16 ba;1,1
+e 339 208 ba;0,0
+e 467 16 ba;2,2
+e 659 16 b;3,-1
+e 659 512 a;-1,0
+e 787 16 ba;4,4
+e 840 16 b;5,-1
+e 1107 840 b;0,-1
+e 1107 832 a;-1,0
+e 1235 16 ba;6,6
+e 1288 16 b;7,-1
+e 1555 1288 b;0,-1
+e 1555 1280 a;-1,0
+e 1683 16 ba;8,8
+e 1736 16 b;9,-1
+e 1939 1736 b;0,-1
+e 1939 1728 a;-1,0
+e 2067 16 ba;10,10
+e 512 16 a;-1,3
+e 832 16 a;-1,5
+e 1280 16 a;-1,7
+e 1728 16 a;-1,9