diff --git a/default.nix b/default.nix index ff750912a..2a39cb7eb 100644 --- a/default.nix +++ b/default.nix @@ -45,7 +45,7 @@ pkgs.stdenv.mkDerivation rec { dontConfigure = true; outputHashAlgo = "sha256"; outputHashMode = "recursive"; - outputHash = "sha256-qIKFqNwooJ0iqzkv6TTS5GM4bA6iYkVa35zqE+q5izY="; + outputHash = "sha256-Kc8kQiC7qzAk3SFmbuUFzoBqxImkHl7RjXMYMJ6SgCg="; }; buildPhase = '' diff --git a/local-maven-repo/deploy-functjonal.sh b/local-maven-repo/deploy-functjonal.sh new file mode 100644 index 000000000..19b0ea050 --- /dev/null +++ b/local-maven-repo/deploy-functjonal.sh @@ -0,0 +1,3 @@ +# A simple script for deploying an update of the functjonal library to the local maven repository +mvn deploy:deploy-file -DgroupId=org.variantsync -DartifactId=functjonal -Dversion=1.0-SNAPSHOT -Durl=file:../local-maven-repo/ -DrepositoryId=local-maven-repo -DupdateReleaseInfo=true -Dfile=../src/main/resources/lib/functjonal-1.0-SNAPSHOT.jar +rm -rf ~/.m2/repository/org/variantsync/functjonal/ \ No newline at end of file diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.jar.md5 b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.jar.md5 deleted file mode 100644 index ae2d2d356..000000000 --- a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.jar.md5 +++ /dev/null @@ -1 +0,0 @@ -4e59459158cfc6af9e8e44d688313046 \ No newline at end of file diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.jar.sha1 b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.jar.sha1 deleted file mode 100644 index c1d527631..000000000 --- a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.jar.sha1 +++ /dev/null @@ -1 +0,0 @@ -d470f07edacf1866880dae50a7ec60cfa5a8b09e \ No newline at end of file diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.jar b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.jar similarity index 85% rename from local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.jar rename to local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.jar index c4f538198..b5c13d047 100644 Binary files a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.jar and b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.jar differ diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.jar.md5 b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.jar.md5 new file mode 100644 index 000000000..3ef2ef57c --- /dev/null +++ b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.jar.md5 @@ -0,0 +1 @@ +9c298528d8baeeccd664e5c06f881265 \ No newline at end of file diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.jar.sha1 b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.jar.sha1 new file mode 100644 index 000000000..43875df79 --- /dev/null +++ b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.jar.sha1 @@ -0,0 +1 @@ +98de1b4bfa2aa9f4e9eaa8c547922f41c59e6e4f \ No newline at end of file diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.pom b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.pom similarity index 100% rename from local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.pom rename to local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.pom diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.pom.md5 b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.pom.md5 similarity index 100% rename from local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.pom.md5 rename to local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.pom.md5 diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.pom.sha1 b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.pom.sha1 similarity index 100% rename from local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230308.125347-1.pom.sha1 rename to local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/functjonal-1.0-20230616.172827-4.pom.sha1 diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml index 180ba3c5f..e986a1d0f 100644 --- a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml +++ b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml @@ -2,24 +2,24 @@ org.variantsync functjonal - 1.0-SNAPSHOT + 20230616172827 - 20230308.125347 - 1 + 20230616.172827 + 4 - 20230308125347 jar - 1.0-20230308.125347-1 - 20230308125347 + 1.0-20230616.172827-4 + 20230616172827 pom - 1.0-20230308.125347-1 - 20230308125347 + 1.0-20230616.172827-4 + 20230616172827 + 1.0-SNAPSHOT diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml.md5 b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml.md5 index 7093ba6df..b8b07bbcb 100644 --- a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml.md5 +++ b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml.md5 @@ -1 +1 @@ -cc732baa0478a9c6f2d21fdeb08f6a82 \ No newline at end of file +409dc289b1020047cbbd30802a354ba7 \ No newline at end of file diff --git a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml.sha1 b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml.sha1 index 5220a677e..500cc0349 100644 --- a/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml.sha1 +++ b/local-maven-repo/org/variantsync/functjonal/1.0-SNAPSHOT/maven-metadata.xml.sha1 @@ -1 +1 @@ -feb03041c908b3f11611fb2380e6bb9424ff2e63 \ No newline at end of file +7e20f40901ae2691c36c164a4306d0c3567d7edc \ No newline at end of file diff --git a/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml b/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml index bf7cd293b..0b01b7afa 100644 --- a/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml +++ b/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml @@ -6,6 +6,6 @@ 1.0-SNAPSHOT - 20230308125347 + 20230616172827 diff --git a/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml.md5 b/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml.md5 index 591810f63..b4bf8db3c 100644 --- a/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml.md5 +++ b/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml.md5 @@ -1 +1 @@ -a9a0be7eec34faf063b51a34b7fed4a7 \ No newline at end of file +a374a3f90764d4507ada7e4ff0d8f0f6 \ No newline at end of file diff --git a/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml.sha1 b/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml.sha1 index d6273c5a6..eba9c175a 100644 --- a/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml.sha1 +++ b/local-maven-repo/org/variantsync/functjonal/maven-metadata.xml.sha1 @@ -1 +1 @@ -d53c3d14023e9052bda58ce2fdcc5580efda1a0b \ No newline at end of file +834afd5cf8d0319105bad448138bf311e9734b1e \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5801c3fd4..b26f24813 100644 --- a/pom.xml +++ b/pom.xml @@ -67,6 +67,19 @@ + + + org.antlr + antlr4-maven-plugin + 4.9.3 + + + + antlr4 + + + + @@ -192,5 +205,11 @@ slf4j-simple 2.0.5 + + + org.antlr + antlr4 + 4.12.0 + diff --git a/scripts/generateANTLRClasses.sh b/scripts/generateANTLRClasses.sh new file mode 100755 index 000000000..24280a5e7 --- /dev/null +++ b/scripts/generateANTLRClasses.sh @@ -0,0 +1,20 @@ +#!/bin/bash +# Call this script from the repository's root directory './scripts/generateANTLRClasses.sh' + +# Define the paths and package information +GRAMMAR_DIR="src/main/resources/grammars" +GRAMMAR_FILE="CExpression.g4" +PACKAGE="org.variantsync.diffdetective.feature.antlr" +OUTPUT_DIR="$(pwd)/src/main/java/org/variantsync/diffdetective/feature/antlr" + +cd $GRAMMAR_DIR + +# Call ANTLR to generate the lexer and parser +antlr4 -o $OUTPUT_DIR -package "$PACKAGE" "$GRAMMAR_FILE" + +# Provide feedback to the user +if [ $? -eq 0 ]; then + echo "ANTLR Lexer and Parser generated successfully in '$OUTPUT_DIR/$PACKAGE'." +else + echo "ANTLR generation and compilation failed." +fi diff --git a/src/main/java/org/variantsync/diffdetective/analysis/Analysis.java b/src/main/java/org/variantsync/diffdetective/analysis/Analysis.java index caf11902d..7740cb13f 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/Analysis.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/Analysis.java @@ -20,6 +20,7 @@ import org.variantsync.diffdetective.diff.git.GitDiffer; import org.variantsync.diffdetective.diff.git.PatchDiff; import org.variantsync.diffdetective.diff.result.CommitDiffResult; +import org.variantsync.diffdetective.diff.result.DiffError; import org.variantsync.diffdetective.metadata.Metadata; import org.variantsync.diffdetective.parallel.ScheduledTasksIterator; import org.variantsync.diffdetective.util.Assert; @@ -27,6 +28,7 @@ import org.variantsync.diffdetective.util.Diagnostics; import org.variantsync.diffdetective.util.InvocationCounter; import org.variantsync.diffdetective.variation.DiffLinesLabel; +import org.variantsync.diffdetective.variation.diff.Time; import org.variantsync.diffdetective.variation.diff.VariationDiff; import org.variantsync.functjonal.iteration.ClusteredIterator; import org.variantsync.functjonal.iteration.MappedIterator; @@ -204,11 +206,16 @@ default void initializeResults(Analysis analysis) {} default void beginBatch(Analysis analysis) throws Exception {} default boolean beginCommit(Analysis analysis) throws Exception { return true; } /** - * Signals a parsing failure of some patch in the current commit. + * Signals a parsing failure of all patches in the current commit. * Called at most once during the commit phase. If this hook is called {@link * onParsedCommit} and the following patch phase invocations are skipped. */ default void onFailedCommit(Analysis analysis) throws Exception {} + /** + * Signals a parsing failure of some patch in the current commit. + * Called at most once during the commit phase. + */ + default void onFailedParse(Analysis analysis) throws Exception {} /** * Signals the completion of the commit diff extraction. * Called exactly once during the commit phase before the patch phase begins. @@ -316,7 +323,8 @@ public static void forSinglePatch(final String commitHash, final String fileName final Hooks filterPatchHook = new Hooks() { @Override public boolean beginPatch(Analysis analysis) { - return fileName.equals(analysis.getCurrentPatch().getFileName()); + return fileName.equals(analysis.getCurrentPatch().getFileName(Time.AFTER)) + || fileName.equals(analysis.getCurrentPatch().getFileName(Time.BEFORE)); } }; @@ -496,6 +504,12 @@ protected void processCommit() throws Exception { // report any errors that occurred and exit in case no VariationDiff could be parsed. getResult().reportDiffErrors(commitDiffResult.errors()); + if (!commitDiffResult.errors().isEmpty()) { + StringBuilder sb = new StringBuilder(); + commitDiffResult.errors().forEach(e -> sb.append(e).append("\n")); + Logger.debug("found commit for which at least one patch could not be parsed because:\n{}", sb); + runHook(hooks.listIterator(), Hooks::onFailedParse); + } if (commitDiffResult.diff().isEmpty()) { Logger.debug("found commit that failed entirely because:\n{}", commitDiffResult.errors()); runHook(hooks.listIterator(), Hooks::onFailedCommit); @@ -520,7 +534,7 @@ protected void processCommit() throws Exception { processPatch(); } catch (Throwable t) { - Logger.error("error during {} {}", currentPatch.getFileName(), currentPatch.getCommitHash()); + Logger.error("error during {} {}", currentPatch.getFileName(Time.AFTER), currentPatch.getCommitHash()); throw t; } finally { runReverseHook(patchHook, Hooks::endPatch); diff --git a/src/main/java/org/variantsync/diffdetective/analysis/EditClassOccurenceAnalysis.java b/src/main/java/org/variantsync/diffdetective/analysis/EditClassOccurenceAnalysis.java index 2308e8f5c..896d0995e 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/EditClassOccurenceAnalysis.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/EditClassOccurenceAnalysis.java @@ -14,6 +14,7 @@ import org.variantsync.diffdetective.util.CSV; import org.variantsync.diffdetective.util.FileUtils; import org.variantsync.diffdetective.util.StringUtils; +import org.variantsync.diffdetective.variation.diff.Time; public class EditClassOccurenceAnalysis implements Analysis.Hooks { public static final String PATCH_STATISTICS_EXTENSION = ".patchStatistics.csv"; @@ -66,7 +67,7 @@ public boolean analyzeVariationDiff(Analysis analysis) throws IOException { Stream.concat( Stream.of( analysis.getCurrentPatch().getCommitHash(), - analysis.getCurrentPatch().getFileName() + analysis.getCurrentPatch().getFileName(Time.AFTER) ), editClassCounts.values().stream()) .map(Object::toString) diff --git a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java index 9cfb461e9..4cddb3044 100644 --- a/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java +++ b/src/main/java/org/variantsync/diffdetective/analysis/strategies/AnalyzeAndExportIncrementally.java @@ -76,8 +76,6 @@ public void end() { /** * Appends the given linegraph string at the end of the given file. - * @param outputPath File to which the linegraph string should be appended. - * @param linegraph String to append to the given file. */ private void flush() { try (var output = IO.newBufferedOutputStream(outputPath, StandardOpenOption.CREATE, StandardOpenOption.APPEND)) { diff --git a/src/main/java/org/variantsync/diffdetective/diff/git/DiffFilter.java b/src/main/java/org/variantsync/diffdetective/diff/git/DiffFilter.java index 46b76a41b..fe9c67b9c 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/git/DiffFilter.java +++ b/src/main/java/org/variantsync/diffdetective/diff/git/DiffFilter.java @@ -3,6 +3,7 @@ import org.apache.commons.io.FilenameUtils; import org.eclipse.jgit.diff.DiffEntry; import org.eclipse.jgit.revwalk.RevCommit; +import org.variantsync.diffdetective.variation.diff.Time; import java.util.ArrayList; import java.util.Arrays; @@ -12,9 +13,8 @@ * A filter for commits and patches. * Can only be created using a DiffFilter.Builder. * - * @see Builder - * * @author Sören Viegener, Paul Bittner + * @see Builder */ public class DiffFilter { /** @@ -69,8 +69,9 @@ public class DiffFilter { /** * Builder for a DiffFilter. - * + *

* See field descriptions of DiffFilter for more details. + * * @author Sören Viegener */ public static class Builder { @@ -97,6 +98,7 @@ public Builder() { /** * Create a new builder that is initialized to the values of the given DiffFilter. + * * @param other The DiffFilter whose values to copy. */ public Builder(final DiffFilter other) { @@ -112,6 +114,7 @@ public Builder(final DiffFilter other) { /** * Adds a regex of allowed file paths for patches. * All paths that do not match any set regex will be filtered. + * * @param regex Java regex that describes desired paths. * @return this */ @@ -123,6 +126,7 @@ public Builder allowedPaths(String regex) { /** * Adds a regex of blocked file paths for patches. * All paths that match at least one blocked regex will be filtered. + * * @param regex Java regex that describes undesired paths. * @return this */ @@ -134,6 +138,7 @@ public Builder blockedPaths(String regex) { /** * Same as {@link Builder#allowedPaths} but with file extensions instead of regexes. * Extensions should be given without preceding dot .. + * * @param fileExtensions A list of file extensions that should be considered only. * @return this */ @@ -145,6 +150,7 @@ public Builder allowedFileExtensions(String... fileExtensions) { /** * Same as {@link Builder#allowedPaths} but with file extensions instead of regexes. * Extensions should be given without preceding dot .. + * * @param fileExtensions A list of file extensions that should be ignored. * @return this */ @@ -156,6 +162,7 @@ public Builder blockedFileExtensions(String... fileExtensions) { /** * Only allow the given change types for patches. * If a patch does not have any of the specified change types, it will be discarded. + * * @param changeTypes The change types to consider only. * @return this */ @@ -166,6 +173,7 @@ public Builder allowedChangeTypes(DiffEntry.ChangeType... changeTypes) { /** * Specifies whether merge commits should be considered or not. + * * @param allowMerge True iff merge commits should be included. * @return this */ @@ -188,6 +196,7 @@ public Builder allowCommitsWithoutParents(boolean allowNoParents) { /** * Resets the list of allowed change types to allow all change types. + * * @return this */ public Builder allowAllChangeTypes() { @@ -197,6 +206,7 @@ public Builder allowAllChangeTypes() { /** * Resets the list of allowed file extensions to allow all file extensions. + * * @return this */ public Builder allowAllFileExtensions() { @@ -228,23 +238,33 @@ private DiffFilter(Builder builder) { /** * Applies this filter to the given PatchDiff. * The given PatchDiff remains unmodifed. + * * @param patchDiff The PatchDiff whose inclusion should be checked. * @return True iff the given patch should be considered w.r.t. this filter. False iff it should be ignored. */ public boolean filter(PatchDiff patchDiff) { - if (!allowedPaths.isEmpty() && !isAllowedPath(patchDiff.getFileName())) { + if (!allowedPaths.isEmpty() + && !isAllowedPath(patchDiff.getFileName(Time.BEFORE)) + && !isAllowedPath(patchDiff.getFileName(Time.AFTER))) { return false; } - if (!blockedPaths.isEmpty() && isBlockedPath(patchDiff.getFileName())) { + if (!blockedPaths.isEmpty() + && isBlockedPath(patchDiff.getFileName(Time.BEFORE)) + && isBlockedPath(patchDiff.getFileName(Time.AFTER))) { return false; } - if (!allowedChangeTypes.isEmpty() && !allowedChangeTypes.contains(patchDiff.getChangeType())) { + if (!allowedChangeTypes.isEmpty() + && !allowedChangeTypes.contains(patchDiff.getChangeType())) { return false; } - if (!allowedFileExtensions.isEmpty() && !allowedFileExtensions.contains(patchDiff.getFileExtension())) { + if (!allowedFileExtensions.isEmpty() + && !allowedFileExtensions.contains(patchDiff.getFileExtension(Time.BEFORE)) + && !allowedFileExtensions.contains(patchDiff.getFileExtension(Time.AFTER))) { return false; } - if (!blockedFileExtensions.isEmpty() && blockedFileExtensions.contains(patchDiff.getFileExtension())) { + if (!blockedFileExtensions.isEmpty() + && blockedFileExtensions.contains(patchDiff.getFileExtension(Time.BEFORE)) + && blockedFileExtensions.contains(patchDiff.getFileExtension(Time.AFTER))) { return false; } return true; @@ -253,33 +273,29 @@ public boolean filter(PatchDiff patchDiff) { /** * Applies this filter to the given DiffEntry. * The given DiffEntry remains unmodifed. + * * @param diffEntry The DiffEntry whose inclusion should be checked. * @return True iff the given entry should be considered w.r.t. this filter. False iff it should be ignored. */ public boolean filter(DiffEntry diffEntry) { if (!allowedPaths.isEmpty() && - !(isAllowedPath(diffEntry.getOldPath()) || isAllowedPath(diffEntry.getNewPath()))) - { + !(isAllowedPath(diffEntry.getOldPath()) || isAllowedPath(diffEntry.getNewPath()))) { return false; } if (!blockedPaths.isEmpty() && - (isBlockedPath(diffEntry.getOldPath()) || isBlockedPath(diffEntry.getNewPath()))) - { + (isBlockedPath(diffEntry.getOldPath()) || isBlockedPath(diffEntry.getNewPath()))) { return false; } if (!allowedChangeTypes.isEmpty() && - !allowedChangeTypes.contains(diffEntry.getChangeType())) - { + !allowedChangeTypes.contains(diffEntry.getChangeType())) { return false; } if (!allowedFileExtensions.isEmpty() && - !(hasAllowedExtension(diffEntry.getOldPath()) || hasAllowedExtension(diffEntry.getNewPath()))) - { + !(hasAllowedExtension(diffEntry.getOldPath()) || hasAllowedExtension(diffEntry.getNewPath()))) { return false; } if (!blockedFileExtensions.isEmpty() && - (hasBlockedExtension(diffEntry.getOldPath()) || hasBlockedExtension(diffEntry.getNewPath()))) - { + (hasBlockedExtension(diffEntry.getOldPath()) || hasBlockedExtension(diffEntry.getNewPath()))) { return false; } return true; @@ -288,15 +304,16 @@ public boolean filter(DiffEntry diffEntry) { /** * Applies this filter to the given commit. * The given RevCommit remains unmodifed. + * * @param commit The commit whose inclusion should be checked. * @return True iff the given commit should be considered w.r.t. this filter. False iff it should be ignored. */ public boolean filter(RevCommit commit) { return // merge - (this.allowMerge || commit.getParentCount() <= 1) - // no parents - && (this.allowCommitsWithoutParents || commit.getParentCount() > 0) + (this.allowMerge || commit.getParentCount() <= 1) + // no parents + && (this.allowCommitsWithoutParents || commit.getParentCount() > 0) ; } @@ -316,7 +333,7 @@ private boolean hasBlockedExtension(String filename) { return blockedFileExtensions.contains(getFileExtension(filename)); } - private String getFileExtension(String path){ + private String getFileExtension(String path) { return FilenameUtils.getExtension(path).toLowerCase(); } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/git/GitDiffer.java b/src/main/java/org/variantsync/diffdetective/diff/git/GitDiffer.java index 13f02e6f4..d7c5fe846 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/git/GitDiffer.java +++ b/src/main/java/org/variantsync/diffdetective/diff/git/GitDiffer.java @@ -398,6 +398,32 @@ private static CommitDiffResult getPatchDiffs( Logger.debug(e, "Could not obtain full diff of file " + filename + " before commit " + parentCommit + "!"); errors.add(DiffError.COULD_NOT_OBTAIN_FULLDIFF); } catch (DiffParseException e) { + StringBuilder logMessage = new StringBuilder(); + logMessage + .append("parse exception for commit ") + .append(childCommit.getName()) + .append(" in line ") + .append(e.getLineNumber()) + .append(" of patch ") + .append(diffEntry.getOldPath()) + .append(" -> ") + .append(diffEntry.getNewPath()) + .append("\n"); + logMessage + .append(e) + .append("\n"); + if (e.getMessage() != null) { + logMessage + .append("error message: ") + .append(e.getMessage()) + .append("\n"); + } + if (e.getCause() != null) { + logMessage + .append("cause: ") + .append(e.getCause()); + } + Logger.debug(logMessage); errors.add(e.getError()); } diff --git a/src/main/java/org/variantsync/diffdetective/diff/git/GitPatch.java b/src/main/java/org/variantsync/diffdetective/diff/git/GitPatch.java index 2506a2fa7..6bdef202e 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/git/GitPatch.java +++ b/src/main/java/org/variantsync/diffdetective/diff/git/GitPatch.java @@ -2,6 +2,7 @@ import org.eclipse.jgit.diff.DiffEntry; import org.variantsync.diffdetective.diff.text.TextBasedDiff; +import org.variantsync.diffdetective.variation.diff.Time; import org.variantsync.diffdetective.variation.diff.VariationDiff; // For Javadoc import org.variantsync.diffdetective.variation.diff.source.VariationDiffSource; @@ -15,20 +16,30 @@ public interface GitPatch extends VariationDiffSource, TextBasedDiff { * Minimal default implementation of {@link GitPatch} * @param getDiff The diff in text form. * @param getChangeType The change type of this patch (e.g., file insertion or modification). - * @param getFileName The name of the patched file. + * @param oldFileName The name of the patched file before the edit. + * @param newFileName The name of the patched file after the edit. * @param getCommitHash The hash of the commit introducing the change. * @param getParentCommitHash The hash of the parent commit regarding which the diff was created. */ - record SimpleGitPatch(String getDiff, DiffEntry.ChangeType getChangeType, String getFileName, String getCommitHash, String getParentCommitHash) + record SimpleGitPatch(String getDiff, DiffEntry.ChangeType getChangeType, String oldFileName, String newFileName, String getCommitHash, String getParentCommitHash) implements GitPatch { + @Override + public String getFileName(Time time) { + if (time == Time.BEFORE) { + return oldFileName; + } else { + return newFileName; + } + } + @Override public GitPatch shallowClone() { - return new SimpleGitPatch(getDiff, getChangeType, getFileName, getCommitHash, getParentCommitHash); + return new SimpleGitPatch(getDiff, getChangeType, oldFileName, newFileName, getCommitHash, getParentCommitHash); } @Override public String toString() { - return getFileName + "@ commit from " + getParentCommitHash + " (parent) to " + getCommitHash + " (child)"; + return oldFileName + "@ " + getParentCommitHash + " (parent) to " + newFileName + " @ " + getCommitHash + " (child)"; } } @@ -38,9 +49,9 @@ public String toString() { DiffEntry.ChangeType getChangeType(); /** - * Returns the name of the patched file. + * Returns the name of the patched file at the given time. */ - String getFileName(); + String getFileName(Time time); /** * Returns the hash of the commit introducing the change. diff --git a/src/main/java/org/variantsync/diffdetective/diff/git/PatchDiff.java b/src/main/java/org/variantsync/diffdetective/diff/git/PatchDiff.java index 11269f2e7..f6e03b0c7 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/git/PatchDiff.java +++ b/src/main/java/org/variantsync/diffdetective/diff/git/PatchDiff.java @@ -3,6 +3,7 @@ import org.apache.commons.io.FilenameUtils; import org.eclipse.jgit.diff.DiffEntry; import org.variantsync.diffdetective.variation.DiffLinesLabel; +import org.variantsync.diffdetective.variation.diff.Time; import org.variantsync.diffdetective.variation.diff.VariationDiff; /** @@ -27,9 +28,13 @@ public class PatchDiff implements GitPatch { private final DiffEntry.ChangeType changeType; /** - * Path of the file that has been modified. + * Path of the file before modification. */ - private final String path; + private final String oldPath; + /** + * Path of the file after modification. + */ + private final String newPath; /** * Creates a new PatchDiff. @@ -42,7 +47,8 @@ public PatchDiff(CommitDiff commitDiff, DiffEntry diffEntry, String fullDiff, VariationDiff variationDiff) { this.commitDiff = commitDiff; this.changeType = diffEntry.getChangeType(); - this.path = diffEntry.getNewPath(); + this.oldPath = diffEntry.getOldPath(); + this.newPath = diffEntry.getNewPath(); this.fullDiff = fullDiff; this.variationDiff = variationDiff; if (this.variationDiff != null) { @@ -60,8 +66,8 @@ public CommitDiff getCommitDiff() { /** * Returns the extension of the file this patch is modifying. */ - public String getFileExtension() { - return FilenameUtils.getExtension(getFileName()).toLowerCase(); + public String getFileExtension(Time time) { + return FilenameUtils.getExtension(getFileName(time)).toLowerCase(); } @Override @@ -70,8 +76,12 @@ public DiffEntry.ChangeType getChangeType() { } @Override - public String getFileName() { - return path; + public String getFileName(Time time) { + if (time == Time.BEFORE) { + return oldPath; + }else { + return newPath; + } } @Override @@ -106,11 +116,11 @@ public boolean isValid() { @Override public String toString() { - return path + "@ " + commitDiff; + return newPath + "@ " + commitDiff; } @Override public GitPatch shallowClone() { - return new GitPatch.SimpleGitPatch(getDiff(), getChangeType(), getFileName(), getCommitHash(), getParentCommitHash()); + return new GitPatch.SimpleGitPatch(getDiff(), getChangeType(), getFileName(Time.BEFORE), getFileName(Time.AFTER), getCommitHash(), getParentCommitHash()); } } diff --git a/src/main/java/org/variantsync/diffdetective/diff/result/DiffError.java b/src/main/java/org/variantsync/diffdetective/diff/result/DiffError.java index 0d45271f8..24d587ac7 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/result/DiffError.java +++ b/src/main/java/org/variantsync/diffdetective/diff/result/DiffError.java @@ -77,7 +77,12 @@ public enum DiffError { /** * A line continuation without a following line. */ - INVALID_LINE_CONTINUATION("a line continuation was detected but there are no more lines"); + INVALID_LINE_CONTINUATION("a line continuation was detected but there are no more lines"), + + /** + * A line with an unparseable formula. + */ + UNPARSEABLE_FORMULA("the extracted formula cannot be parsed"); private final String message; diff --git a/src/main/java/org/variantsync/diffdetective/diff/result/DiffParseException.java b/src/main/java/org/variantsync/diffdetective/diff/result/DiffParseException.java index 78c20996a..8f25e08f7 100644 --- a/src/main/java/org/variantsync/diffdetective/diff/result/DiffParseException.java +++ b/src/main/java/org/variantsync/diffdetective/diff/result/DiffParseException.java @@ -19,6 +19,26 @@ public DiffParseException(DiffError error, DiffLineNumber lineNumber) { this.lineNumber = lineNumber; } + /** + * @param exception an exception that indicated the error + * @param error the error type to be reported + * @param lineNumber the source line of the error + */ + private DiffParseException(Exception exception, DiffError error, DiffLineNumber lineNumber) { + super(exception); + this.error = error; + this.lineNumber = lineNumber; + } + + /** + * A DiffParseException due to an unparseable formula. + * @param exception The parse exception that occurred + * @param lineNumber The line number of the unparseable formula + */ + public static DiffParseException Unparseable(Exception exception, DiffLineNumber lineNumber) { + return new DiffParseException(exception, DiffError.UNPARSEABLE_FORMULA, lineNumber); + } + public DiffError getError() { return error; } diff --git a/src/main/java/org/variantsync/diffdetective/error/UncheckedUnParseableFormulaException.java b/src/main/java/org/variantsync/diffdetective/error/UncheckedUnParseableFormulaException.java new file mode 100644 index 000000000..1cbd0de44 --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/error/UncheckedUnParseableFormulaException.java @@ -0,0 +1,17 @@ +package org.variantsync.diffdetective.error; + +/** + * Runtime exception for cases in which a formula extracted from a diff cannot be parsed. + */ +public class UncheckedUnParseableFormulaException extends RuntimeException { + final UnparseableFormulaException inner; + + public UncheckedUnParseableFormulaException(String message, Exception e) { + super(message, e); + inner = new UnparseableFormulaException(message, e); + } + + public UnparseableFormulaException inner() { + return this.inner; + } +} diff --git a/src/main/java/org/variantsync/diffdetective/error/UnparseableFormulaException.java b/src/main/java/org/variantsync/diffdetective/error/UnparseableFormulaException.java new file mode 100644 index 000000000..4d3ca2cda --- /dev/null +++ b/src/main/java/org/variantsync/diffdetective/error/UnparseableFormulaException.java @@ -0,0 +1,18 @@ +package org.variantsync.diffdetective.error; + +/** + * Exception for cases in which a formula extracted from a diff cannot be parsed. + */ +public class UnparseableFormulaException extends Exception { + public UnparseableFormulaException(Exception other) { + super(other); + } + + public UnparseableFormulaException(String message) { + super(message); + } + + public UnparseableFormulaException(String message, Exception other) { + super(message, other); + } +} diff --git a/src/main/java/org/variantsync/diffdetective/examplesearch/ExampleFinder.java b/src/main/java/org/variantsync/diffdetective/examplesearch/ExampleFinder.java index b6288031f..f782571d4 100644 --- a/src/main/java/org/variantsync/diffdetective/examplesearch/ExampleFinder.java +++ b/src/main/java/org/variantsync/diffdetective/examplesearch/ExampleFinder.java @@ -13,6 +13,7 @@ import org.variantsync.diffdetective.util.IO; import org.variantsync.diffdetective.util.StringUtils; 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.filter.ExplainedFilter; import org.variantsync.diffdetective.variation.diff.parse.VariationDiffParseOptions; @@ -152,7 +153,7 @@ private void exportExample(final Analysis analysis, final String tdiff, final Va final Repository repo = analysis.getRepository(); final GitPatch patch = (GitPatch) vdiff.getSource(); outputDir = outputDir.resolve(Path.of(repo.getRepositoryName() + "_" + patch.getCommitHash())); - final String filename = patch.getFileName(); + final String filename = patch.getFileName(Time.AFTER); Logger.info("Exporting example candidate: {}", patch); @@ -162,7 +163,7 @@ private void exportExample(final Analysis analysis, final String tdiff, final Va metadata += "Repository URL: " + repo.getRemoteURI() + StringUtils.LINEBREAK; metadata += "Child commit: " + patch.getCommitHash() + StringUtils.LINEBREAK; metadata += "Parent commit: " + patch.getParentCommitHash() + StringUtils.LINEBREAK; - metadata += "File: " + patch.getFileName() + StringUtils.LINEBREAK; + metadata += "File: " + patch.getFileName(Time.AFTER) + StringUtils.LINEBREAK; String githubLink = repo.getRemoteURI().toString(); if (githubLink.endsWith(".git")) { githubLink = githubLink.substring(0, githubLink.length() - ".git".length()); @@ -177,7 +178,7 @@ private void exportExample(final Analysis analysis, final String tdiff, final Va // export vdiff //exampleExport.render(example, patch, treeDir); try { - Show.diff(vdiff).dontShowButRenderToTexture().saveAsPng(outputDir.resolve(patch.getFileName() + ".png").toFile()); + Show.diff(vdiff).dontShowButRenderToTexture().saveAsPng(outputDir.resolve(patch.getFileName(Time.AFTER) + ".png").toFile()); } catch (IOException e) { Logger.error("Could not render example"); } diff --git a/src/main/java/org/variantsync/diffdetective/experiments/thesis_bm/ConstructionValidation.java b/src/main/java/org/variantsync/diffdetective/experiments/thesis_bm/ConstructionValidation.java index a31fd3e27..8c7b63b9a 100644 --- a/src/main/java/org/variantsync/diffdetective/experiments/thesis_bm/ConstructionValidation.java +++ b/src/main/java/org/variantsync/diffdetective/experiments/thesis_bm/ConstructionValidation.java @@ -276,7 +276,7 @@ public void beginBatch(Analysis analysis) throws IOException { @Override public boolean analyzeVariationDiff(Analysis analysis) throws Exception, DiffParseException { - Logger.info("current patch: {} {} (by thread {})", analysis.getCurrentPatch().getFileName(), analysis.getCurrentPatch().getCommitHash(), Thread.currentThread().getId()); + Logger.info("current patch: {} {} (by thread {})", analysis.getCurrentPatch().getFileName(AFTER), analysis.getCurrentPatch().getCommitHash(), Thread.currentThread().getId()); Statistics statistics = new Statistics(); try { statistics.variationDiff[0].matchingDuration = 0; @@ -325,7 +325,7 @@ public boolean analyzeVariationDiff(Analysis analysis) throws Exception, DiffPar statistics.writeCsvCells(destination); destination.newLine(); } catch (Throwable t) { - Logger.error(t, "{} {}", analysis.getCurrentPatch().getFileName(), analysis.getCurrentPatch().getCommitHash()); + Logger.error(t, "{} {}", analysis.getCurrentPatch().getFileName(AFTER), analysis.getCurrentPatch().getCommitHash()); } return true; } @@ -386,7 +386,7 @@ private VariationDiff parseVariationTree(Analysis analysis, RevC GitDiffer.getBeforeFullFile( analysis.getRepository().getGitRepo().run(), commit, - analysis.getCurrentPatch().getFileName()), + analysis.getCurrentPatch().getFileName(AFTER)), 0xfeff)) // BOM, same as GitDiffer.BOM_PATTERN ) { return VariationDiffParser.createVariationTree(afterFile, analysis.getRepository().getParseOptions().variationDiffParseOptions()); diff --git a/src/main/java/org/variantsync/diffdetective/experiments/views/ViewAnalysis.java b/src/main/java/org/variantsync/diffdetective/experiments/views/ViewAnalysis.java index 85edab754..0ab7cd656 100644 --- a/src/main/java/org/variantsync/diffdetective/experiments/views/ViewAnalysis.java +++ b/src/main/java/org/variantsync/diffdetective/experiments/views/ViewAnalysis.java @@ -98,7 +98,7 @@ private void runRelevanceExperiment(Analysis analysis, final VariationDiff + * Not all formulas or parts of a formula might require abstraction (e.g., 'A && B'). Therefore, this visitor should not be used directly. + * Instead, you may use a {@link ControllingCExpressionVisitor} which internally uses an {@link AbstractingCExpressionVisitor} + * to control how formulas are abstracted, and only abstracts those parts of a formula that require it. + *

+ */ +@SuppressWarnings("CheckReturnValue") +public class AbstractingCExpressionVisitor extends AbstractParseTreeVisitor implements CExpressionVisitor { + + public AbstractingCExpressionVisitor() {} + + // conditionalExpression + // : logicalOrExpression ('?' expression ':' conditionalExpression)? + // ; + @Override public StringBuilder visitConditionalExpression(CExpressionParser.ConditionalExpressionContext ctx) { + return visitExpression(ctx, + childContext -> childContext instanceof CExpressionParser.LogicalOrExpressionContext + || childContext instanceof CExpressionParser.ExpressionContext + || childContext instanceof CExpressionParser.ConditionalExpressionContext); + } + + // 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(this); + } + // Identifier + if (ctx.Identifier() != null) { + // Terminal + return new StringBuilder(BooleanAbstraction.abstractAll(ctx.Identifier().getText().trim())); + } + // Constant + if (ctx.Constant() != null) { + // Terminal + return new StringBuilder(BooleanAbstraction.abstractAll(ctx.Constant().getText().trim())); + } + // StringLiteral+ + if (!ctx.StringLiteral().isEmpty()) { + // Terminal + StringBuilder sb = new StringBuilder(); + ctx.StringLiteral().stream().map(ParseTree::getText).map(String::trim).map(BooleanAbstraction::abstractAll).forEach(sb::append); + return sb; + } + // '(' expression ')' + if (ctx.expression() != null) { + StringBuilder sb = ctx.expression().accept(this); + sb.insert(0, BooleanAbstraction.BRACKET_L); + sb.append(BooleanAbstraction.BRACKET_R); + 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(this); + } + + // Unreachable + throw new IllegalStateException("Unreachable code."); + } + + // unaryOperator + // : '&' | '*' | '+' | '-' | '~' | '!' + // ; + @Override public StringBuilder visitUnaryOperator(CExpressionParser.UnaryOperatorContext ctx) { + if (ctx.And() != null) { + return new StringBuilder(BooleanAbstraction.U_AND); + } + if (ctx.Star() != null) { + return new StringBuilder(BooleanAbstraction.U_STAR); + } + if (ctx.Plus() != null) { + return new StringBuilder(BooleanAbstraction.U_PLUS); + } + if (ctx.Minus() != null) { + return new StringBuilder(BooleanAbstraction.U_MINUS); + } + if (ctx.Tilde() != null) { + return new StringBuilder(BooleanAbstraction.U_TILDE); + } + if (ctx.Not() != null) { + return new StringBuilder(BooleanAbstraction.U_NOT); + } + throw new IllegalStateException(); + } + + // namespaceExpression + // : primaryExpression (':' primaryExpression)* + // ; + @Override + public StringBuilder visitNamespaceExpression(CExpressionParser.NamespaceExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.PrimaryExpressionContext); + } + + // multiplicativeExpression + // : namespaceExpression (('*'|'/'|'%') namespaceExpression)* + // ; + @Override public StringBuilder visitMultiplicativeExpression(CExpressionParser.MultiplicativeExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.NamespaceExpressionContext); + } + + // additiveExpression + // : multiplicativeExpression (('+'|'-') multiplicativeExpression)* + // ; + @Override public StringBuilder visitAdditiveExpression(CExpressionParser.AdditiveExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.MultiplicativeExpressionContext); + } + + // shiftExpression + // : additiveExpression (('<<'|'>>') additiveExpression)* + // ; + @Override public StringBuilder visitShiftExpression(CExpressionParser.ShiftExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.AdditiveExpressionContext); + } + + // relationalExpression + // : shiftExpression (('<'|'>'|'<='|'>=') shiftExpression)* + // ; + @Override public StringBuilder visitRelationalExpression(CExpressionParser.RelationalExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.ShiftExpressionContext); + } + + // equalityExpression + // : relationalExpression (('=='| '!=') relationalExpression)* + // ; + @Override public StringBuilder visitEqualityExpression(CExpressionParser.EqualityExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.RelationalExpressionContext); + } + + // andExpression + // : equalityExpression ( '&' equalityExpression)* + // ; + @Override public StringBuilder visitAndExpression(CExpressionParser.AndExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.EqualityExpressionContext); + } + + // exclusiveOrExpression + // : andExpression ('^' andExpression)* + // ; + @Override public StringBuilder visitExclusiveOrExpression(CExpressionParser.ExclusiveOrExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.AndExpressionContext); + } + + // inclusiveOrExpression + // : exclusiveOrExpression ('|' exclusiveOrExpression)* + // ; + @Override public StringBuilder visitInclusiveOrExpression(CExpressionParser.InclusiveOrExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.ExclusiveOrExpressionContext); + } + + // specialOperator + // : HasAttribute ('(' specialOperatorArgument ')')? + // | HasCPPAttribute ('(' specialOperatorArgument ')')? + // | HasCAttribute ('(' specialOperatorArgument ')')? + // | HasBuiltin ('(' specialOperatorArgument ')')? + // | HasInclude ('(' specialOperatorArgument ')')? + // | Defined ('(' specialOperatorArgument ')') + // | Defined specialOperatorArgument? + // ; + @Override public StringBuilder visitSpecialOperator(CExpressionParser.SpecialOperatorContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.SpecialOperatorArgumentContext); + } + + // specialOperatorArgument + // : HasAttribute + // | HasCPPAttribute + // | HasCAttribute + // | HasBuiltin + // | HasInclude + // | Defined + // | Identifier + // | PathLiteral + // | StringLiteral + // ; + @Override + public StringBuilder visitSpecialOperatorArgument(CExpressionParser.SpecialOperatorArgumentContext ctx) { + return new StringBuilder(BooleanAbstraction.abstractAll(ctx.getText().trim())); + } + + // logicalAndExpression + // : logicalOperand ( '&&' logicalOperand)* + // ; + @Override public StringBuilder visitLogicalAndExpression(CExpressionParser.LogicalAndExpressionContext ctx) { + return visitExpression(ctx, childExpression -> childExpression instanceof CExpressionParser.LogicalOperandContext); + } + + // logicalOrExpression + // : logicalAndExpression ( '||' logicalAndExpression)* + // ; + @Override public StringBuilder visitLogicalOrExpression(CExpressionParser.LogicalOrExpressionContext ctx) { + return visitExpression(ctx, childExpression -> childExpression instanceof CExpressionParser.LogicalAndExpressionContext); + } + + // logicalOperand + // : inclusiveOrExpression + // ; + @Override + public StringBuilder visitLogicalOperand(CExpressionParser.LogicalOperandContext ctx) { + return ctx.inclusiveOrExpression().accept(this); + } + + // macroExpression + // : Identifier '(' argumentExpressionList? ')' + // ; + @Override + public StringBuilder visitMacroExpression(CExpressionParser.MacroExpressionContext ctx) { + StringBuilder sb = new StringBuilder(); + sb.append(ctx.Identifier().getText().trim().toUpperCase()).append("_"); + if (ctx.argumentExpressionList() != null) { + sb.append(ctx.argumentExpressionList().accept(this)); + } + return sb; + } + + // argumentExpressionList + // : assignmentExpression (',' assignmentExpression)* + // | assignmentExpression (assignmentExpression)* + // ; + @Override + public StringBuilder visitArgumentExpressionList(CExpressionParser.ArgumentExpressionListContext ctx) { + StringBuilder sb = new StringBuilder(); + sb.append(BooleanAbstraction.BRACKET_L); + for (int i = 0; i < ctx.assignmentExpression().size(); i++) { + sb.append(ctx.assignmentExpression(i).accept(this)); + if (i < ctx.assignmentExpression().size()-1) { + // For each ',' separating arguments + sb.append("__"); + } + } + sb.append(BooleanAbstraction.BRACKET_R); + return sb; + } + + // assignmentExpression + // : conditionalExpression + // | DigitSequence // for + // | PathLiteral + // | StringLiteral + // | primaryExpression assignmentOperator assignmentExpression + // ; + @Override + public StringBuilder visitAssignmentExpression(CExpressionParser.AssignmentExpressionContext ctx) { + if (ctx.conditionalExpression() != null) { + // conditionalExpression + return ctx.conditionalExpression().accept(this); + } else if (ctx.primaryExpression() != null) { + // primaryExpression assignmentOperator assignmentExpression + StringBuilder sb = new StringBuilder(); + sb.append(ctx.primaryExpression().accept(this)); + sb.append(ctx.assignmentOperator().accept(this)); + sb.append(ctx.assignmentExpression().accept(this)); + return sb; + } else { + // all other cases require direct abstraction + return new StringBuilder(BooleanAbstraction.abstractAll(ctx.getText().trim())); + } + } + + // assignmentOperator + // : '=' | '*=' | '/=' | '%=' | '+=' | '-=' | '<<=' | '>>=' | '&=' | '^=' | '|=' + // ; + @Override + public StringBuilder visitAssignmentOperator(CExpressionParser.AssignmentOperatorContext ctx) { + return new StringBuilder(BooleanAbstraction.abstractToken(ctx.getText().trim())); + } + + // expression + // : assignmentExpression (',' assignmentExpression)* + // ; + @Override + public StringBuilder visitExpression(CExpressionParser.ExpressionContext ctx) { + return visitExpression(ctx, childContext -> childContext instanceof CExpressionParser.AssignmentExpressionContext); + } + + /** + * Abstract all child nodes in the parse tree. + * @param expressionContext The root of the subtree to abstract + * @param instanceCheck A check for expected child node types + * @return The abstracted formula of the subtree + */ + private StringBuilder visitExpression(ParserRuleContext expressionContext, Function 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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 visitor) { + if ( visitor instanceof CExpressionVisitor ) return ((CExpressionVisitor)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 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 options, final LineGraphExportOptions 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