Added the modules and everything
This commit is contained in:
parent
07af5bf983
commit
b4f1ccff9b
|
@ -0,0 +1,7 @@
|
|||
.classpath
|
||||
.project
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
target/
|
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<!-- parent project -->
|
||||
<parent>
|
||||
<groupId>it.unitn</groupId>
|
||||
<artifactId>foss-vuln-tracker</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>it.unitn.molerat</groupId>
|
||||
<artifactId>molerat</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<!-- declare dependencies -->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
<version>4.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>bson</artifactId>
|
||||
<version>3.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>it.unitn.repoman</groupId>
|
||||
<artifactId>repoman</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>2.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
<version>3.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver</artifactId>
|
||||
<version>3.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
<version>3.4.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jgit</groupId>
|
||||
<artifactId>org.eclipse.jgit</artifactId>
|
||||
<version>4.2.0.201601211800-r</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
<version>1.7.25</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-nop</artifactId>
|
||||
<version>1.7.25</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.tmatesoft.svnkit</groupId>
|
||||
<artifactId>svnkit-cli</artifactId>
|
||||
<version>1.8.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.tmatesoft.svnkit</groupId>
|
||||
<artifactId>svnkit</artifactId>
|
||||
<version>1.8.13</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.tmatesoft.svnkit</groupId>
|
||||
<artifactId>svnkit-javahl16</artifactId>
|
||||
<version>1.8.13</version>
|
||||
</dependency>
|
||||
<!--
|
||||
<dependency>
|
||||
<groupId>org.tmatesoft.svnkit</groupId>
|
||||
<artifactId>svnkit-javahl</artifactId>
|
||||
<version>1.3.5</version>
|
||||
</dependency>
|
||||
-->
|
||||
</dependencies>
|
||||
|
||||
<!-- build plugins -->
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-dependencies</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>
|
||||
${project.build.directory}/libs
|
||||
</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>libs/</classpathPrefix>
|
||||
<mainClass>it.unitn.molerat.cmd.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,267 @@
|
|||
package it.unitn.molerat.cmd;
|
||||
|
||||
import it.unitn.molerat.data.csv.InputDataPoint;
|
||||
import it.unitn.molerat.data.csv.VulnEvidenceDataPoint;
|
||||
import it.unitn.molerat.data.db.MongoWrapper;
|
||||
import it.unitn.molerat.data.memory.AnalysisEntry;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
import it.unitn.molerat.repos.trackers.vuln.VulnerabilityEvidenceTracker;
|
||||
import it.unitn.molerat.repos.trackers.vuln.VulnerabilityEvidenceTrackerFactory;
|
||||
import it.unitn.molerat.repos.utils.IORoutines;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.cli.*;
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
public class Main {
|
||||
|
||||
private static MongoWrapper db = new MongoWrapper("molerat");
|
||||
|
||||
public static void main(String[] args) {
|
||||
Options opts = new Options();
|
||||
|
||||
Option listTrackersOpt = Option.builder()
|
||||
.longOpt("list-trackers")
|
||||
.desc("List the available trackers for vulnerability molerat.evidence")
|
||||
.build();
|
||||
opts.addOption(listTrackersOpt);
|
||||
|
||||
Option projectNameOpt = Option.builder()
|
||||
.longOpt("project-name")
|
||||
.desc("The name of the project")
|
||||
.hasArg()
|
||||
.build();
|
||||
opts.addOption(projectNameOpt);
|
||||
|
||||
Option repoTypeOpt = Option.builder()
|
||||
.longOpt("repo-type")
|
||||
.desc("The type of the source code repository ('git' or 'svn')")
|
||||
.hasArg()
|
||||
.build();
|
||||
opts.addOption(repoTypeOpt);
|
||||
|
||||
Option repoPathOpt = Option.builder()
|
||||
.longOpt("repo-path")
|
||||
.desc("The path of the working copy of the source code repository")
|
||||
.hasArg()
|
||||
.build();
|
||||
opts.addOption(repoPathOpt);
|
||||
|
||||
Option cveIdOpt = Option.builder()
|
||||
.longOpt("cve-id")
|
||||
.desc("The CVE identifier of a vulnerability")
|
||||
.hasArg()
|
||||
.build();
|
||||
opts.addOption(cveIdOpt);
|
||||
|
||||
Option fixCommitOpt = Option.builder()
|
||||
.longOpt("fix-commit")
|
||||
.desc("The commit that fixed a vulnerability")
|
||||
.hasArg()
|
||||
.build();
|
||||
opts.addOption(fixCommitOpt);
|
||||
|
||||
Option trackerTypeOpt = Option.builder()
|
||||
.longOpt("tracker-type")
|
||||
.desc("The type of the vulnerability molerat.evidence tracker")
|
||||
.hasArg()
|
||||
.build();
|
||||
opts.addOption(trackerTypeOpt);
|
||||
|
||||
Option inputFileOpt = Option.builder()
|
||||
.longOpt("input-file")
|
||||
.desc("Path to the input .csv file")
|
||||
.hasArg()
|
||||
.argName("input-file-path")
|
||||
.build();
|
||||
opts.addOption(inputFileOpt);
|
||||
|
||||
Option outputFileOpt = Option.builder()
|
||||
.longOpt("output-file")
|
||||
.desc("Path to the output .csv file")
|
||||
.hasArg()
|
||||
.argName("output-file-path")
|
||||
.build();
|
||||
opts.addOption(outputFileOpt);
|
||||
|
||||
CommandLineParser cmdParser = new DefaultParser();
|
||||
HelpFormatter helpFormatter = new HelpFormatter();
|
||||
CommandLine cmd;
|
||||
try {
|
||||
cmd = cmdParser.parse(opts, args);
|
||||
if (cmd.getOptions().length == 0) {
|
||||
throw new ParseException("Arguments are not specified");
|
||||
}
|
||||
|
||||
if (cmd.hasOption("list-trackers")) {
|
||||
System.out.println(VulnerabilityEvidenceTrackerFactory.getTrackersList());
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd.hasOption("input-file")) {
|
||||
String i = cmd.getOptionValue("input-file");
|
||||
collectVulnEvidence(i);
|
||||
}
|
||||
if (cmd.hasOption("output-file")) {
|
||||
String o = cmd.getOptionValue("output-file");
|
||||
generateCsv(o);
|
||||
}
|
||||
|
||||
if (!cmd.hasOption("input-file") && !cmd.hasOption("output-file")) {
|
||||
String projectName = null;
|
||||
String repoType = null;
|
||||
String repoPath = null;
|
||||
String cveId = null;
|
||||
String fixCommit = null;
|
||||
String trackerType = null;
|
||||
|
||||
if (cmd.hasOption("project-name")) {
|
||||
projectName = cmd.getOptionValue("project-name");
|
||||
}
|
||||
if (cmd.hasOption("repo-type")) {
|
||||
repoType = cmd.getOptionValue("repo-type");
|
||||
}
|
||||
if(cmd.hasOption("repo-path")) {
|
||||
repoPath = cmd.getOptionValue("repo-path");
|
||||
}
|
||||
if(cmd.hasOption("cve-id")) {
|
||||
cveId = cmd.getOptionValue("cve-id");
|
||||
}
|
||||
if(cmd.hasOption("fix-commit")) {
|
||||
fixCommit = cmd.getOptionValue("fix-commit");
|
||||
}
|
||||
if(cmd.hasOption("tracker-type")) {
|
||||
trackerType = cmd.getOptionValue("tracker-type");
|
||||
}
|
||||
if (projectName == null) {
|
||||
throw new ParseException("The 'project-name' parameter is not specified");
|
||||
}
|
||||
if (repoType == null) {
|
||||
throw new ParseException("The 'repo-type' parameter is not specified");
|
||||
}
|
||||
if (repoPath == null) {
|
||||
throw new ParseException("The 'repo-path' parameter is not specified");
|
||||
}
|
||||
if (cveId == null) {
|
||||
throw new ParseException("The 'cve-id' parameter is not specified");
|
||||
}
|
||||
if (fixCommit == null) {
|
||||
throw new ParseException("The 'fix-commit' parameter is not specified");
|
||||
}
|
||||
if (trackerType == null) {
|
||||
throw new ParseException("The 'tracker-type' parameter is not specified");
|
||||
}
|
||||
collect(projectName, repoType, repoPath, cveId, fixCommit, trackerType);
|
||||
}
|
||||
}
|
||||
catch (ParseException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
helpFormatter.printHelp("utility-name", opts);
|
||||
}
|
||||
}
|
||||
|
||||
private static void collectVulnEvidence(String inputCsvPath) {
|
||||
try {
|
||||
Set<InputDataPoint> inputs = IORoutines.readInputDataPoints(inputCsvPath);
|
||||
for (InputDataPoint ip : inputs) {
|
||||
collect(ip.PROJECTID,
|
||||
ip.REPO_TYPE,
|
||||
ip.REPO_ROOT,
|
||||
ip.CVEID,
|
||||
ip.FIX_REV,
|
||||
ip.TRACKER_TYPE);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void collect(String projectName, String repositoryType,
|
||||
String repositoryPath, String cveName, String fixCommit, String trackerType) {
|
||||
try {
|
||||
boolean entryExists = db.analysisEntryExists(projectName, cveName, repositoryType, repositoryPath);
|
||||
if (entryExists) {
|
||||
System.out.format("WARNING: The analysis entry for '%s' from '%s' already exists, skipping\n", cveName, projectName);
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.format("INFO: Collecting the molerat.evidence for '%s' from '%s'\n", cveName, projectName);
|
||||
VulnerabilityEvidenceTracker vulnTracker = VulnerabilityEvidenceTrackerFactory.getTracker(
|
||||
repositoryPath,
|
||||
fixCommit,
|
||||
repositoryType,
|
||||
trackerType
|
||||
);
|
||||
vulnTracker.trackEvidence();
|
||||
|
||||
AnalysisEntry entry = new AnalysisEntry(
|
||||
cveName,
|
||||
projectName,
|
||||
repositoryType,
|
||||
repositoryPath,
|
||||
fixCommit,
|
||||
vulnTracker.getProcessedCommits(),
|
||||
vulnTracker.getEvidences(),
|
||||
null // we're not tracking any changes so far
|
||||
);
|
||||
boolean isSuccessful = db.insertAnalysisEntry(entry);
|
||||
if (!isSuccessful) {
|
||||
System.out.format("WARNING: Could not get any molerat.evidence for '%s' in '%s'\n", cveName, projectName);
|
||||
}
|
||||
System.out.println("INFO: Done!");
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static void generateCsv(String outFilePath) {
|
||||
System.out.format("INFO: generating the .csv file '%s'\n", outFilePath);
|
||||
String csvHeader = new VulnEvidenceDataPoint().getHeader() + "\n";
|
||||
try {
|
||||
IORoutines.writeFile(outFilePath, csvHeader);
|
||||
Set<ObjectId> cveIds = db.getAllCveIds();
|
||||
for (ObjectId cveId : cveIds) {
|
||||
AnalysisEntry analysis = db.getAnalysisEntry(cveId);
|
||||
if (analysis == null) {
|
||||
continue;
|
||||
}
|
||||
String projectName = analysis.getProjectName();
|
||||
String cveName = analysis.getCveName();
|
||||
|
||||
System.out.format("INFO: writing the entries for '%s'\n", cveName);
|
||||
Set<VulnerabilityEvidence> evidences = analysis.getVulnEvidencesSet();
|
||||
if (evidences.size() == 0) {
|
||||
throw new Exception(String.format("There is no molerat.evidence for '%s' in the database", cveName));
|
||||
}
|
||||
Map<String, Integer> locsCount = new LinkedHashMap<>();
|
||||
for (VulnerabilityEvidence evd : evidences) {
|
||||
if (locsCount.containsKey(evd.getCommit())) {
|
||||
int count = locsCount.get(evd.getCommit());
|
||||
locsCount.remove(evd.getCommit());
|
||||
locsCount.put(evd.getCommit(), ++count);
|
||||
} else {
|
||||
locsCount.put(evd.getCommit(), 1);
|
||||
}
|
||||
}
|
||||
int timestamp = 0;
|
||||
for (Map.Entry<String, Integer> entry : locsCount.entrySet()) {
|
||||
VulnEvidenceDataPoint dp = new VulnEvidenceDataPoint(new String[]{
|
||||
projectName,
|
||||
cveName,
|
||||
entry.getKey(),
|
||||
String.valueOf(timestamp--),
|
||||
String.valueOf(entry.getValue())
|
||||
});
|
||||
IORoutines.writeFile(outFilePath, dp.toString() + "\n");
|
||||
}
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package it.unitn.molerat.cmd.experiments;
|
||||
|
||||
import it.unitn.molerat.data.csv.InputDataPoint;
|
||||
import it.unitn.molerat.repos.utils.IORoutines;
|
||||
import java.util.Set;
|
||||
|
||||
public class AbstractExperiment {
|
||||
|
||||
protected static Set<InputDataPoint> readInputDataPoints(String path) throws Exception {
|
||||
return IORoutines.readInputDataPoints(path);
|
||||
}
|
||||
|
||||
protected static void saveOutput(String path, String output) throws Exception {
|
||||
IORoutines.writeFile(path, output + "\n");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
package it.unitn.molerat.cmd.experiments;
|
||||
|
||||
import it.unitn.molerat.data.csv.InputDataPoint;
|
||||
import it.unitn.molerat.data.csv.OutputDataPoint;
|
||||
import it.unitn.molerat.data.csv.PerfOutputDataPoint;
|
||||
import it.unitn.molerat.repos.utils.CommitMetrics;
|
||||
import it.unitn.molerat.repos.wrappers.GitRepoWrapper;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class CalculateAllChangesExperiment extends AbstractExperiment {
|
||||
public static void main(String[] args) {
|
||||
if (args.length < 2) {
|
||||
System.out.println("USAGE: [input.csv] [output.csv]");
|
||||
return;
|
||||
}
|
||||
String inputCsvPath = args[0];
|
||||
String outputCsvPath = args[1];
|
||||
|
||||
try {
|
||||
Set<InputDataPoint> inputs = readInputDataPoints(inputCsvPath);
|
||||
saveOutput(outputCsvPath, new PerfOutputDataPoint().getHeader());
|
||||
for (InputDataPoint idp : inputs) {
|
||||
|
||||
System.out.println("Processing the " + idp.CVEID + "...");
|
||||
long timeNow = System.currentTimeMillis();
|
||||
|
||||
RepoWrapper wrapper = new GitRepoWrapper(idp.REPO_ROOT);
|
||||
Set<String> processedCommits = wrapper.getRevisionNumbers(idp.FIX_REV);
|
||||
int timestamp = 0;
|
||||
for (String commit : processedCommits) {
|
||||
|
||||
int publicAPICount = CommitMetrics.getNumberOfPublicMethodsPerRevision(commit, wrapper);
|
||||
int rem = CommitMetrics.getGlobalPublicMethodsRemoved(commit, idp.FIX_REV, wrapper);
|
||||
double currentUntouched = (((double) publicAPICount - (double) rem) / (double) publicAPICount) * 100.0;
|
||||
currentUntouched = Math.round(currentUntouched * 100.0) / 100.0;
|
||||
|
||||
String[] output = new String[]{
|
||||
idp.CVEID,
|
||||
idp.TRACKER_TYPE,
|
||||
"empty",
|
||||
commit,
|
||||
String.valueOf(timestamp),
|
||||
"empty",
|
||||
String.valueOf(publicAPICount),
|
||||
String.valueOf(rem),
|
||||
String.valueOf(currentUntouched)
|
||||
};
|
||||
OutputDataPoint odp = new OutputDataPoint(output);
|
||||
saveOutput(outputCsvPath, odp.toString());
|
||||
timestamp--;
|
||||
}
|
||||
long timeAfter = System.currentTimeMillis();
|
||||
System.out.println("TIME (ms): " + (timeAfter - timeNow));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
package it.unitn.molerat.cmd.experiments;
|
||||
|
||||
import it.unitn.molerat.data.csv.InputDataPoint;
|
||||
import it.unitn.molerat.data.csv.PerfOutputDataPoint;
|
||||
import it.unitn.molerat.repos.trackers.vuln.VulnerabilityEvidenceTracker;
|
||||
import it.unitn.molerat.repos.trackers.vuln.VulnerabilityEvidenceTrackerFactory;
|
||||
import it.unitn.molerat.repos.utils.CommitMetrics;
|
||||
import java.util.Set;
|
||||
|
||||
public class ChangeEvdPerformanceExperiment extends AbstractExperiment {
|
||||
public static void main(String[] args) {
|
||||
if (args.length < 2) {
|
||||
System.out.println("USAGE: [input.csv] [output.csv]");
|
||||
return;
|
||||
}
|
||||
String inputCsvPath = args[0];
|
||||
String outputCsvPath = args[1];
|
||||
|
||||
try {
|
||||
Set<InputDataPoint> inputs = readInputDataPoints(inputCsvPath);
|
||||
saveOutput(outputCsvPath, new PerfOutputDataPoint().getHeader());
|
||||
for (InputDataPoint idp : inputs) {
|
||||
|
||||
System.out.println("Processing the " + idp.CVEID + "...");
|
||||
|
||||
VulnerabilityEvidenceTracker vulnTracker = VulnerabilityEvidenceTrackerFactory.getTracker(idp.REPO_ROOT, idp.FIX_REV, idp.REPO_TYPE, idp.TRACKER_TYPE);
|
||||
vulnTracker.trackEvidence();
|
||||
|
||||
Set<String> processedCommits = vulnTracker.getProcessedCommits();
|
||||
for (String commit : processedCommits) {
|
||||
long timeNow = System.currentTimeMillis();
|
||||
|
||||
int publicAPICount = CommitMetrics.getNumberOfPublicMethodsPerRevision(commit, vulnTracker.getRepoWrapper());
|
||||
int rem = CommitMetrics.getGlobalPublicMethodsRemoved(commit, vulnTracker.getFixedRevision(), vulnTracker.getRepoWrapper());
|
||||
double currentUntouched = (((double) publicAPICount - (double) rem) / (double) publicAPICount) * 100.0;
|
||||
currentUntouched = Math.round(currentUntouched * 100.0) / 100.0;
|
||||
|
||||
long timeAfter = System.currentTimeMillis();
|
||||
String[] output = new String[]{
|
||||
idp.CVEID,
|
||||
idp.TRACKER_TYPE,
|
||||
String.valueOf(timeAfter - timeNow)
|
||||
};
|
||||
PerfOutputDataPoint odp = new PerfOutputDataPoint(output);
|
||||
saveOutput(outputCsvPath, odp.toString());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package it.unitn.molerat.cmd.experiments;
|
||||
|
||||
import it.unitn.molerat.data.csv.InputDataPoint;
|
||||
import it.unitn.molerat.data.csv.PerfOutputDataPoint;
|
||||
import it.unitn.molerat.repos.trackers.vuln.VulnerabilityEvidenceTracker;
|
||||
import it.unitn.molerat.repos.trackers.vuln.VulnerabilityEvidenceTrackerFactory;
|
||||
import java.util.Set;
|
||||
|
||||
public class VulnEvdPerformanceExperiment extends AbstractExperiment {
|
||||
|
||||
public static void main(String[] args) {
|
||||
if (args.length < 2) {
|
||||
System.out.println("USAGE: [input.csv] [output.csv]");
|
||||
return;
|
||||
}
|
||||
String inputCsvPath = args[0];
|
||||
String outputCsvPath = args[1];
|
||||
|
||||
try {
|
||||
Set<InputDataPoint> inputs = readInputDataPoints(inputCsvPath);
|
||||
saveOutput(outputCsvPath, new PerfOutputDataPoint().getHeader());
|
||||
for (InputDataPoint idp : inputs) {
|
||||
|
||||
System.out.println("Processing the " + idp.CVEID + "...");
|
||||
long timeNow = System.currentTimeMillis();
|
||||
|
||||
VulnerabilityEvidenceTracker vulnTracker = VulnerabilityEvidenceTrackerFactory.getTracker(idp.REPO_ROOT, idp.FIX_REV, idp.REPO_TYPE, idp.TRACKER_TYPE);
|
||||
vulnTracker.trackEvidence();
|
||||
|
||||
long timeAfter = System.currentTimeMillis();
|
||||
|
||||
String[] output = new String[]{
|
||||
idp.CVEID,
|
||||
idp.TRACKER_TYPE,
|
||||
String.valueOf(timeAfter - timeNow)
|
||||
};
|
||||
PerfOutputDataPoint odp = new PerfOutputDataPoint(output);
|
||||
saveOutput(outputCsvPath, odp.toString());
|
||||
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package it.unitn.molerat.data.csv;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public abstract class AbstractDataPoint {
|
||||
|
||||
public AbstractDataPoint(String[] entries) throws Exception {
|
||||
Field[] fields = this.getClass().getFields();
|
||||
if (entries.length != fields.length) {
|
||||
throw new Exception("Bad entries for initializing a molerat.data point!");
|
||||
}
|
||||
int i = 0;
|
||||
for (Field field : fields) {
|
||||
if (!field.getName().equals("this$0")) {
|
||||
try {
|
||||
field.set(this, entries[i++]);
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AbstractDataPoint(String str) throws Exception {
|
||||
this(str.replace(" ", "").split(","));
|
||||
}
|
||||
|
||||
public AbstractDataPoint() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Field[] fields = this.getClass().getFields();
|
||||
for (Field field : fields) {
|
||||
if (!field.getName().equals("this$0")) {
|
||||
try {
|
||||
builder.append(field.get(this) + ",");
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
} catch (IllegalAccessException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.deleteCharAt(builder.length()-1);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public final String getHeader() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Field[] fields = this.getClass().getFields();
|
||||
for (Field field : fields) {
|
||||
if (!field.getName().equals("this$0")) {
|
||||
try {
|
||||
builder.append(field.getName() + ",");
|
||||
} catch (IllegalArgumentException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.deleteCharAt(builder.length()-1);
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package it.unitn.molerat.data.csv;
|
||||
|
||||
/**
|
||||
* Created by standash on 06/12/2016.
|
||||
*/
|
||||
public class ChangeStatsDataPoint extends AbstractDataPoint {
|
||||
public String PROJECT;
|
||||
public String CURRENT_COMMIT;
|
||||
public String ADDED_LINES;
|
||||
public String DELETED_LINES;
|
||||
public String TOUCHED_METHODS;
|
||||
public String TOUCHED_FILES;
|
||||
|
||||
public ChangeStatsDataPoint(String[] entries) throws Exception {
|
||||
super(entries);
|
||||
}
|
||||
|
||||
public ChangeStatsDataPoint(String str) throws Exception {
|
||||
super(str);
|
||||
}
|
||||
|
||||
public ChangeStatsDataPoint() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package it.unitn.molerat.data.csv;
|
||||
|
||||
public class FixStatsDataPoint extends AbstractDataPoint {
|
||||
public String CVEID;
|
||||
public String ADDED_LINES;
|
||||
public String DELETED_LINES;
|
||||
public String TOUCHED_METHODS;
|
||||
public String TOUCHED_FILES;
|
||||
|
||||
public FixStatsDataPoint(String[] entries) throws Exception {
|
||||
super(entries);
|
||||
}
|
||||
|
||||
public FixStatsDataPoint(String str) throws Exception {
|
||||
super(str);
|
||||
}
|
||||
|
||||
public FixStatsDataPoint() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package it.unitn.molerat.data.csv;
|
||||
|
||||
public final class InputDataPoint extends AbstractDataPoint {
|
||||
|
||||
public String PROJECTID;
|
||||
public String CVEID;
|
||||
public String REPO_TYPE;
|
||||
public String REPO_ROOT;
|
||||
public String FIX_REV;
|
||||
public String TRACKER_TYPE;
|
||||
|
||||
public InputDataPoint(String[] entries) throws Exception {
|
||||
super(entries);
|
||||
}
|
||||
|
||||
public InputDataPoint(String str) throws Exception {
|
||||
super(str);
|
||||
}
|
||||
|
||||
public InputDataPoint() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package it.unitn.molerat.data.csv;
|
||||
|
||||
public class OutputDataPoint extends AbstractDataPoint {
|
||||
|
||||
public String CVEID;
|
||||
public String TRACKING_METHOD;
|
||||
public String CURRENT_FILE;
|
||||
public String CURRENT_REV;
|
||||
public String TIMESTAMP;
|
||||
public String EVIDENCE_LOC;
|
||||
//public String GLOBAL_PUBLIC_API_COUNT;
|
||||
//public String GLOBAL_PUBLIC_API_REMOVED;
|
||||
//public String GLOBAL_PUBLIC_API_UNTOUCHED;
|
||||
|
||||
public OutputDataPoint(String[] entries) throws Exception {
|
||||
super(entries);
|
||||
}
|
||||
|
||||
public OutputDataPoint(String str) throws Exception {
|
||||
super(str);
|
||||
}
|
||||
|
||||
public OutputDataPoint() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package it.unitn.molerat.data.csv;
|
||||
|
||||
public class PerfOutputDataPoint extends AbstractDataPoint {
|
||||
|
||||
public String CVEID;
|
||||
public String TRACKING_METHOD;
|
||||
public String TIME_MS;
|
||||
|
||||
public PerfOutputDataPoint(String[] entries) throws Exception {
|
||||
super(entries);
|
||||
}
|
||||
|
||||
public PerfOutputDataPoint(String str) throws Exception {
|
||||
super(str);
|
||||
}
|
||||
|
||||
public PerfOutputDataPoint() {
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package it.unitn.molerat.data.csv;
|
||||
|
||||
public class VulnEvidenceDataPoint extends AbstractDataPoint {
|
||||
|
||||
public String PROJECT_NAME;
|
||||
public String CVEID;
|
||||
public String CURRENT_REV;
|
||||
public String TIMESTAMP;
|
||||
public String EVIDENCE_LOC;
|
||||
|
||||
public VulnEvidenceDataPoint(String[] entries) throws Exception {
|
||||
super(entries);
|
||||
}
|
||||
|
||||
public VulnEvidenceDataPoint(String str) throws Exception {
|
||||
super(str);
|
||||
}
|
||||
|
||||
public VulnEvidenceDataPoint() {
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,245 @@
|
|||
package it.unitn.molerat.data.db;
|
||||
|
||||
import com.mongodb.BasicDBObject;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.client.FindIterable;
|
||||
import com.mongodb.client.MongoCollection;
|
||||
import com.mongodb.client.MongoDatabase;
|
||||
import com.mongodb.client.model.Indexes;
|
||||
import it.unitn.molerat.data.memory.AnalysisEntry;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
import java.util.*;
|
||||
|
||||
public class MongoWrapper {
|
||||
|
||||
private static final String projectCollection = "projects";
|
||||
private static final String vulnsCollection = "vulns";
|
||||
private static final String vulnEvdCollection = "vuln_evidences";
|
||||
|
||||
private MongoClient client = null;
|
||||
private MongoDatabase db = null;
|
||||
|
||||
public MongoWrapper(String dbName) {
|
||||
this.client = new MongoClient();
|
||||
this.db = client.getDatabase(dbName);
|
||||
}
|
||||
|
||||
private FindIterable<Document> getEntries(BasicDBObject query, String collection) {
|
||||
MongoCollection<Document> docs = db.getCollection(collection);
|
||||
return docs.find(query);
|
||||
}
|
||||
|
||||
private Document getEntry(BasicDBObject query, String collection) {
|
||||
return getEntries(query, collection).first();
|
||||
}
|
||||
|
||||
private ObjectId getEntryId(Document doc) {
|
||||
return (doc != null) ? doc.getObjectId("_id") : null;
|
||||
}
|
||||
|
||||
private Document getProjectEntry(String name, String repoType, String repoPath) {
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
query.put("name", name);
|
||||
query.put("repo_type", repoType);
|
||||
query.put("repo_path", repoPath);
|
||||
return getEntry(query, projectCollection);
|
||||
}
|
||||
|
||||
private Document getProjectEntry(ObjectId projectId) {
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
query.put("_id", projectId);
|
||||
return getEntry(query, projectCollection);
|
||||
}
|
||||
|
||||
private ObjectId getProjectId(String name, String repoType, String repoPath) {
|
||||
return getEntryId(getProjectEntry(name, repoType, repoPath));
|
||||
}
|
||||
|
||||
private ObjectId getProjectId(ObjectId cveId) {
|
||||
return getCveEntry(cveId).getObjectId("owner_id");
|
||||
}
|
||||
|
||||
private Document getCveEntry(ObjectId projectId, String cve) {
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
query.put("cve", cve);
|
||||
query.put("owner_id", projectId);
|
||||
return getEntry(query, vulnsCollection);
|
||||
}
|
||||
|
||||
private Document getCveEntry(ObjectId cveId) {
|
||||
BasicDBObject query = new BasicDBObject();
|
||||
query.put("_id", cveId);
|
||||
return getEntry(query, vulnsCollection);
|
||||
}
|
||||
|
||||
private ObjectId getCveId(ObjectId projectId, String cve) {
|
||||
return getEntryId(getCveEntry(projectId, cve));
|
||||
}
|
||||
|
||||
public Set<ObjectId> getAllCveIds() {
|
||||
Set<ObjectId> ids = new LinkedHashSet<>();
|
||||
MongoCollection<Document> vulns = db.getCollection(vulnsCollection);
|
||||
FindIterable<Document> docs = vulns.find();
|
||||
for (Document doc : docs) {
|
||||
ids.add(doc.getObjectId("_id"));
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
private FindIterable<Document> getVulnEvidences(ObjectId cveId) {
|
||||
BasicDBObject query = new BasicDBObject() ;
|
||||
query.put("owner_id", cveId);
|
||||
FindIterable<Document> result = getEntries(query, vulnEvdCollection);
|
||||
result.sort(new BasicDBObject("order", -1));
|
||||
return result;
|
||||
}
|
||||
|
||||
private ObjectId insertProject(String name, String repoType, String repoPath) {
|
||||
Document proj = getProjectEntry(name, repoType, repoPath);
|
||||
if (proj == null) {
|
||||
MongoCollection<Document> projects = db.getCollection(projectCollection);
|
||||
proj = new Document("name", name)
|
||||
.append("repo_type", repoType)
|
||||
.append("repo_path", repoPath);
|
||||
projects.insertOne(proj);
|
||||
|
||||
}
|
||||
return getEntryId(proj);
|
||||
}
|
||||
|
||||
private ObjectId insertCve(ObjectId projectId, String cve, String fixCommit) {
|
||||
Document vuln = getCveEntry(projectId, cve);
|
||||
if (vuln == null) {
|
||||
MongoCollection<Document> vulns = db.getCollection(vulnsCollection);
|
||||
vuln = new Document("cve", cve)
|
||||
.append("fix_commit", fixCommit)
|
||||
.append("owner_id", projectId)
|
||||
.append("processed", false);
|
||||
vulns.insertOne(vuln);
|
||||
MongoCollection<Document> projects = db.getCollection(projectCollection);
|
||||
projects.findOneAndUpdate(new BasicDBObject("_id", projectId), new BasicDBObject("$push",
|
||||
new BasicDBObject("vulns", getEntryId(vuln))));
|
||||
}
|
||||
return getEntryId(vuln);
|
||||
}
|
||||
|
||||
private boolean isVulnProcessed(ObjectId cveId) {
|
||||
MongoCollection<Document> vulns = db.getCollection(vulnsCollection);
|
||||
Document cve = vulns.find(new BasicDBObject("_id", cveId)).first();
|
||||
return (Boolean)cve.get("processed");
|
||||
}
|
||||
|
||||
public boolean insertAnalysisEntry(AnalysisEntry entry) {
|
||||
// if there's no molerat.evidence for some reason, return false
|
||||
if (entry.getVulnEvidences().isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectId projectId = insertProject(entry.getProjectName(), entry.getRepositoryType(), entry.getRepositoryPath());
|
||||
ObjectId cveId = insertCve(projectId, entry.getCveName(), entry.getFixCommit());
|
||||
MongoCollection<Document> vulns = db.getCollection(vulnsCollection);
|
||||
MongoCollection<Document> evds = db.getCollection(vulnEvdCollection);
|
||||
|
||||
if (isVulnProcessed(cveId)) {
|
||||
vulns.updateOne(
|
||||
new BasicDBObject("_id", cveId),
|
||||
new BasicDBObject("$set", new BasicDBObject("processed", false))
|
||||
);
|
||||
evds.deleteMany(new BasicDBObject("owner_id", cveId));
|
||||
}
|
||||
|
||||
List<Document> records = new LinkedList<Document>();
|
||||
int order= 0;
|
||||
Set<String> commits = entry.getCommits();
|
||||
for (String commit : commits) {
|
||||
Set<VulnerabilityEvidence> evidences = entry.getVulnEvidences().get(commit);
|
||||
if (evidences != null) {
|
||||
for (VulnerabilityEvidence e : evidences) {
|
||||
BasicDBObject record = new BasicDBObject();
|
||||
record.put("owner_id", cveId);
|
||||
record.put("revision", commit);
|
||||
record.put("order", order);
|
||||
record.put("file_path", e.getPath());
|
||||
record.put("container", e.getContainer());
|
||||
record.put("line_number", e.getLineNumber());
|
||||
record.put("line_contents", e.getLineContents());
|
||||
Document doc = new Document(record);
|
||||
records.add(doc);
|
||||
}
|
||||
}
|
||||
order--;
|
||||
}
|
||||
|
||||
evds.insertMany(records);
|
||||
vulns.updateOne(
|
||||
new BasicDBObject("_id", cveId),
|
||||
new BasicDBObject("$set", new BasicDBObject("processed", true))
|
||||
);
|
||||
//create index
|
||||
evds.createIndex(Indexes.descending("order"));
|
||||
return true;
|
||||
}
|
||||
|
||||
public AnalysisEntry getAnalysisEntry(String projectName, String cveName, String repoType, String repoPath) {
|
||||
ObjectId projectId = getProjectId(projectName, repoType, repoPath);
|
||||
ObjectId cveId = getCveId(projectId, cveName);
|
||||
return getAnalysisEntry(cveId);
|
||||
}
|
||||
|
||||
public boolean analysisEntryExists(String projectName, String cveName, String repoType, String repoPath) {
|
||||
ObjectId projectId = getProjectId(projectName, repoType, repoPath);
|
||||
ObjectId cveId = getCveId(projectId, cveName);
|
||||
return (projectId != null && cveId != null);
|
||||
}
|
||||
|
||||
public Set<AnalysisEntry> getAnalysisEntries() {
|
||||
Set<AnalysisEntry> entries = new LinkedHashSet<>();
|
||||
FindIterable<Document> cves = db.getCollection(vulnsCollection).find();
|
||||
for (Document cve : cves) {
|
||||
ObjectId cveId = cve.getObjectId("_id");
|
||||
AnalysisEntry entry = getAnalysisEntry(cveId);
|
||||
entries.add(entry);
|
||||
}
|
||||
return entries;
|
||||
}
|
||||
|
||||
public AnalysisEntry getAnalysisEntry(ObjectId cveId) {
|
||||
if (!isVulnProcessed(cveId)) {
|
||||
return null;
|
||||
}
|
||||
ObjectId projectId = getProjectId(cveId);
|
||||
Document projectDoc = getProjectEntry(projectId);
|
||||
String projectName = projectDoc.getString("name");
|
||||
String repoType = projectDoc.getString("repo_type");
|
||||
String repoPath = projectDoc.getString("repo_path");
|
||||
|
||||
Document cveDoc = getCveEntry(cveId);
|
||||
String cveName = cveDoc.getString("cve");
|
||||
String fixCommit = cveDoc.getString("fix_commit");
|
||||
|
||||
Map<String, Set<VulnerabilityEvidence>> vulnEvidences = new LinkedHashMap<>();
|
||||
FindIterable<Document> docs = getVulnEvidences(cveId);
|
||||
for (Document doc : docs) {
|
||||
String filePath = doc.getString("file_path");
|
||||
String container = doc.getString("container");
|
||||
String revision = doc.getString("revision");
|
||||
int lineNumber = doc.getInteger("line_number");
|
||||
String lineContents = doc.getString("line_contents");
|
||||
VulnerabilityEvidence evidence = new VulnerabilityEvidence(filePath, revision, container, lineNumber, lineContents);
|
||||
if (vulnEvidences.containsKey(revision)) {
|
||||
vulnEvidences.get(revision).add(evidence);
|
||||
}
|
||||
else {
|
||||
Set<VulnerabilityEvidence> set = new LinkedHashSet<>();
|
||||
set.add(evidence);
|
||||
vulnEvidences.put(evidence.getCommit(), set);
|
||||
}
|
||||
}
|
||||
/* TODO: add stuff for getting the changes molerat.evidence
|
||||
Map<String, Set<ChangeEvidence>> chgEvidences = new TreeMap<>();
|
||||
*/
|
||||
return new AnalysisEntry(cveName, projectName, repoType, repoPath, fixCommit, vulnEvidences.keySet(), vulnEvidences, null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package it.unitn.molerat.data.memory;
|
||||
|
||||
import it.unitn.molerat.evidence.ChangeEvidence;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class AnalysisEntry {
|
||||
private final String cveId;
|
||||
private final String projectId;
|
||||
private final String fixCommit;
|
||||
private final String repositoryType;
|
||||
private final String repositoryPath;
|
||||
private final Set<String> commits;
|
||||
private final Map<String, Set<VulnerabilityEvidence>> vulnEvidences;
|
||||
private final Map<String, Set<ChangeEvidence>> changEvidences;
|
||||
|
||||
public AnalysisEntry(String cveId, String projectId, String repositoryType, String repositoryPath,
|
||||
String fixCommit, Set<String> commits,
|
||||
Map<String, Set<VulnerabilityEvidence>> vulnEvidences,
|
||||
Map<String, Set<ChangeEvidence>> changEvidences) {
|
||||
this.cveId = cveId;
|
||||
this.projectId = projectId;
|
||||
this.repositoryType = repositoryType;
|
||||
this.repositoryPath = repositoryPath;
|
||||
this.commits = commits;
|
||||
this.fixCommit = fixCommit;
|
||||
this.vulnEvidences = vulnEvidences;
|
||||
this.changEvidences = changEvidences;
|
||||
}
|
||||
|
||||
public String getCveName() {
|
||||
return cveId;
|
||||
}
|
||||
|
||||
public Set<String> getCommits() {
|
||||
return commits;
|
||||
}
|
||||
|
||||
public String getFixCommit() {
|
||||
return fixCommit;
|
||||
}
|
||||
|
||||
public String getRepositoryType() {
|
||||
return repositoryType;
|
||||
}
|
||||
|
||||
public String getRepositoryPath() {
|
||||
return repositoryPath;
|
||||
}
|
||||
|
||||
public Map<String, Set<VulnerabilityEvidence>> getVulnEvidences() {
|
||||
return vulnEvidences;
|
||||
}
|
||||
|
||||
public Set<VulnerabilityEvidence> getVulnEvidencesSet() {
|
||||
Set<VulnerabilityEvidence> evidences = new LinkedHashSet<>();
|
||||
for (Set<VulnerabilityEvidence> eset : vulnEvidences.values()) {
|
||||
evidences.addAll(eset);
|
||||
}
|
||||
return evidences;
|
||||
}
|
||||
|
||||
public Map<String, Set<ChangeEvidence>> getChangEvidences() {
|
||||
return changEvidences;
|
||||
}
|
||||
|
||||
public String getProjectName() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package it.unitn.molerat.data.printers;
|
||||
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class VulnerabilityEvidencePrinter {
|
||||
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
|
||||
public VulnerabilityEvidencePrinter(Set<VulnerabilityEvidence> evidence) {
|
||||
List<VulnerabilityEvidence> sortedEvidence = new LinkedList<>(evidence);
|
||||
Collections.sort(sortedEvidence, new Comparator<VulnerabilityEvidence>() {
|
||||
@Override
|
||||
public int compare(VulnerabilityEvidence o1, VulnerabilityEvidence o2) {
|
||||
if (o1.getLineNumber() < o2.getLineNumber()) {
|
||||
return -1;
|
||||
} else if (o1.getLineNumber() > o2.getLineNumber()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
String path = "";
|
||||
String container = "";
|
||||
for (VulnerabilityEvidence e : sortedEvidence) {
|
||||
if (!path.equals(e.getPath())) {
|
||||
path = e.getPath();
|
||||
builder.append("<" + path + ">\n");
|
||||
}
|
||||
if (!container.equals(e.getContainer())) {
|
||||
container = e.getContainer();
|
||||
builder.append("\t" + container + "\n");
|
||||
}
|
||||
builder.append("\t\t" + e.getLineNumber() + ": " + e.getLineContents() + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.builder.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package it.unitn.molerat.evidence;
|
||||
|
||||
public class ChangeEvidence extends GenericEvidence {
|
||||
|
||||
private final boolean removed;
|
||||
|
||||
public ChangeEvidence(String file, String commit, String container, boolean removed) {
|
||||
super(file, commit, container);
|
||||
this.removed = removed;
|
||||
}
|
||||
|
||||
public boolean isMethodOrConstructor() {
|
||||
return this.container.contains("(") && this.container.contains(")");
|
||||
}
|
||||
|
||||
public boolean isAbsentInFix() {
|
||||
return removed;
|
||||
}
|
||||
|
||||
public String getAccessModifier() {
|
||||
if (this.container.startsWith("public")) {
|
||||
return "public";
|
||||
}
|
||||
else if (this.container.startsWith("protected")) {
|
||||
return "protected";
|
||||
}
|
||||
else if (this.container.startsWith("private")) {
|
||||
return "private";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean isPublicMethodOrConstructor() {
|
||||
return this.isMethodOrConstructor() && this.getAccessModifier().equals("public");
|
||||
}
|
||||
|
||||
public boolean isProtectedMethodOrConstructor() {
|
||||
return this.isMethodOrConstructor() && this.getAccessModifier().equals("protected");
|
||||
}
|
||||
|
||||
public boolean isPrivateMethodOrConstructor() {
|
||||
return this.isMethodOrConstructor() && this.getAccessModifier().equals("private");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package it.unitn.molerat.evidence;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class Changes {
|
||||
|
||||
private final String path;
|
||||
private final String leftRev;
|
||||
private final String rightRev;
|
||||
private final Map<Integer, String> deletions;
|
||||
private final Map<Integer, String> additions;
|
||||
private String renamedTo = "";
|
||||
|
||||
|
||||
public Changes(String path, String leftRev, String rightRev) {
|
||||
this.path = path;
|
||||
this.leftRev = leftRev;
|
||||
this.rightRev = rightRev;
|
||||
this.deletions = new TreeMap<>();
|
||||
this.additions = new TreeMap<>();
|
||||
}
|
||||
|
||||
public Changes(String path, String renamedTo, String leftRev, String rightRev) {
|
||||
this(path, leftRev, rightRev);
|
||||
this.renamedTo = renamedTo;
|
||||
}
|
||||
|
||||
public Changes(Changes changes, String leftRev, String rightRev) {
|
||||
this.path = changes.path;
|
||||
this.leftRev = leftRev;
|
||||
this.rightRev = rightRev;
|
||||
this.deletions = changes.deletions;
|
||||
this.additions = changes.additions;
|
||||
}
|
||||
|
||||
public String getRenamedTo() {
|
||||
return renamedTo;
|
||||
}
|
||||
|
||||
public boolean wasRenamed() {
|
||||
return !renamedTo.equals("");
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public String getLeftRevision() {
|
||||
return this.leftRev;
|
||||
}
|
||||
|
||||
public String getRightRevision() {
|
||||
return this.rightRev;
|
||||
}
|
||||
|
||||
public void putDeletedLine(int lineNumber, String line) {
|
||||
this.deletions.put(lineNumber, line);
|
||||
}
|
||||
|
||||
public void putAddedLine(int lineNumber, String line) {
|
||||
this.additions.put(lineNumber, line);
|
||||
}
|
||||
|
||||
public Map<Integer, String> getDeletions() {
|
||||
return this.deletions;
|
||||
}
|
||||
|
||||
public Map<Integer, String> getAdditions() {
|
||||
return this.additions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("CHANGES:\n");
|
||||
for (Map.Entry<Integer, String> entry : this.deletions.entrySet()) {
|
||||
builder.append("-, " + this.formatAsCSV(entry) + "\n");
|
||||
}
|
||||
for (Map.Entry<Integer, String> entry : this.additions.entrySet()) {
|
||||
builder.append("+, " + this.formatAsCSV(entry) + "\n");
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private String formatAsCSV(Map.Entry<Integer, String> entry) {
|
||||
return this.leftRev + ", " +
|
||||
this.path + ", " +
|
||||
entry.getKey() + ", " +
|
||||
entry.getValue();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package it.unitn.molerat.evidence;
|
||||
|
||||
public class GenericEvidence {
|
||||
|
||||
protected final String commit;
|
||||
protected final String container;
|
||||
protected String path;
|
||||
|
||||
protected GenericEvidence(String file, String commit, String container) {
|
||||
this.path = file;
|
||||
this.commit = commit;
|
||||
this.container = container;
|
||||
}
|
||||
|
||||
public String getContainer() {
|
||||
return this.container;
|
||||
}
|
||||
|
||||
public String getCommit() {
|
||||
return this.commit;
|
||||
}
|
||||
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
public void setPath(String path) {
|
||||
this.path = path;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package it.unitn.molerat.evidence;
|
||||
|
||||
public class VulnerabilityEvidence extends GenericEvidence {
|
||||
|
||||
protected final int lineNumber;
|
||||
protected final String lineContents;
|
||||
|
||||
public VulnerabilityEvidence(String file, String commit, String container, int lineNumber, String lineContents) {
|
||||
super(file, commit, container);
|
||||
this.lineNumber = lineNumber;
|
||||
this.lineContents = lineContents
|
||||
.trim()
|
||||
.replace("\t","");
|
||||
}
|
||||
|
||||
public int getLineNumber() {
|
||||
return this.lineNumber;
|
||||
}
|
||||
|
||||
public String getLineContents() {
|
||||
return this.lineContents;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("<" + commit + ": " + path + ">\n");
|
||||
builder.append("\t" + container + "\n");
|
||||
builder.append("\t\t" + lineNumber + ": " + lineContents + "\n\t\n");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package it.unitn.molerat.repos.trackers;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AbstractEvidenceTracker {
|
||||
protected final String fixedRevision;
|
||||
protected final String vulnRevision;
|
||||
protected final String repoPath;
|
||||
protected final RepoWrapper repoWrapper;
|
||||
protected Set<Changes> changes;
|
||||
protected Set<String> commits = new LinkedHashSet<>();
|
||||
protected Set<String> restOfCommits = new LinkedHashSet<>();
|
||||
|
||||
public AbstractEvidenceTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
this.fixedRevision = fixedRev;
|
||||
this.repoPath = wrapper.getBasePath();
|
||||
this.repoWrapper = wrapper;
|
||||
Iterator<String> commitsIter = repoWrapper.getRevisionNumbers(fixedRev).iterator();
|
||||
this.vulnRevision = commitsIter.next();
|
||||
while (commitsIter.hasNext()) {
|
||||
restOfCommits.add(commitsIter.next());
|
||||
}
|
||||
String initDiff = repoWrapper.doDiff(vulnRevision, fixedRevision);
|
||||
this.changes = repoWrapper.inferChangesFromDiff(initDiff, vulnRevision, fixedRevision);
|
||||
}
|
||||
|
||||
public RepoWrapper getRepoWrapper() {
|
||||
return this.repoWrapper;
|
||||
}
|
||||
|
||||
public String getFixedRevision() {
|
||||
return this.fixedRevision;
|
||||
}
|
||||
|
||||
public Set<String> getProcessedCommits() {
|
||||
return this.commits;
|
||||
}
|
||||
|
||||
// apart from non-java files, filter the files that contain "test" in ther name as well
|
||||
protected Set<Changes> filterNonJavaChanges(Set<Changes> changes) {
|
||||
Set<Changes> filteredChanges = new HashSet<>();
|
||||
for (Changes change : changes) {
|
||||
if (!change.getPath().endsWith(".java") || change.getPath().toLowerCase().contains("test")) {
|
||||
filteredChanges.add(change);
|
||||
}
|
||||
this.repoWrapper.filterCommentsAndBlanks(change.getDeletions());
|
||||
this.repoWrapper.filterCommentsAndBlanks(change.getAdditions());
|
||||
}
|
||||
changes.removeAll(filteredChanges);
|
||||
return changes;
|
||||
}
|
||||
|
||||
public abstract void trackEvidence() throws Exception;
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
package it.unitn.molerat.repos.trackers.changes;
|
||||
|
||||
import it.unitn.molerat.evidence.ChangeEvidence;
|
||||
import it.unitn.molerat.repos.trackers.AbstractEvidenceTracker;
|
||||
import it.unitn.molerat.repos.utils.CommitMetrics;
|
||||
import it.unitn.molerat.repos.utils.SignatureExtractor;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class ChangeEvidenceTracker extends AbstractEvidenceTracker {
|
||||
|
||||
protected final Map<String, Set<ChangeEvidence>> evidences = new TreeMap<>();
|
||||
protected Map<String, Set<String>> fixConstructs;
|
||||
|
||||
protected ChangeEvidenceTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
super(wrapper, fixedRev);
|
||||
}
|
||||
|
||||
public ChangeEvidenceTracker(RepoWrapper repoWrapper, String fixedCommit, Set<String> commits) throws Exception {
|
||||
this(repoWrapper, fixedCommit);
|
||||
this.commits = commits;
|
||||
this.fixConstructs = extractSignatures(this.fixedRevision);
|
||||
}
|
||||
|
||||
protected Map<String, Set<String>> extractSignatures(String commit) throws Exception {
|
||||
Map<String, Set<String>> result = new TreeMap<>();
|
||||
Map<String, String> files = CommitMetrics.getFileContentsPerRevision(commit, this.repoWrapper);
|
||||
for (Map.Entry<String, String> file : files.entrySet()) {
|
||||
SignatureExtractor se = new SignatureExtractor(file.getValue());
|
||||
Set<String> signatures = new HashSet<>();
|
||||
for (String signature : se.getSignaturesWithLines().keySet()) {
|
||||
signatures.add(signature);
|
||||
}
|
||||
result.put(file.getKey(), signatures);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void trackEvidence() throws Exception {
|
||||
for (String commit : this.commits) {
|
||||
// long timeNow = System.currentTimeMillis();
|
||||
Map<String, Set<String>> currentSignatures = extractSignatures(commit);
|
||||
for (Map.Entry<String, Set<String>> currentSignature : currentSignatures.entrySet()) {
|
||||
Set<String> temp = this.fixConstructs.get(currentSignature.getKey());
|
||||
if (temp == null) {
|
||||
for (String sign : currentSignature.getValue()) {
|
||||
ChangeEvidence evidence = new ChangeEvidence(
|
||||
currentSignature.getKey(),
|
||||
commit,
|
||||
sign,
|
||||
true
|
||||
);
|
||||
if (evidence.isPublicMethodOrConstructor()) {
|
||||
addEvidence(evidence);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (String sign : currentSignature.getValue()) {
|
||||
boolean removed = true;
|
||||
for (String fixSign : temp) {
|
||||
if (sign.equals(fixSign)) {
|
||||
removed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ChangeEvidence evidence = new ChangeEvidence(
|
||||
currentSignature.getKey(),
|
||||
commit,
|
||||
sign,
|
||||
removed
|
||||
);
|
||||
if (evidence.isPublicMethodOrConstructor()) {
|
||||
addEvidence(evidence);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void addEvidence(ChangeEvidence evidence) {
|
||||
if (this.evidences.containsKey(evidence.getCommit())) {
|
||||
this.evidences.get(evidence.getCommit()).add(evidence);
|
||||
}
|
||||
else {
|
||||
Set<ChangeEvidence> set = new HashSet<>();
|
||||
set.add(evidence);
|
||||
this.evidences.put(evidence.getCommit(), set);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<ChangeEvidence> getEvidence(String commit) {
|
||||
Set<ChangeEvidence> evd = this.evidences.get(commit);
|
||||
return (evd != null) ? evd : new HashSet<>();
|
||||
}
|
||||
|
||||
public Map<String, Set<ChangeEvidence>> getEvidences() {
|
||||
return this.evidences;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package it.unitn.molerat.repos.trackers.changes;
|
||||
|
||||
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
|
||||
public class FullChangeEvidenceTracker extends ChangeEvidenceTracker {
|
||||
|
||||
public FullChangeEvidenceTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
super(wrapper, fixedRev);
|
||||
this.commits = wrapper.getRevisionNumbers(fixedRev);
|
||||
this.fixConstructs = extractSignatures(this.fixedRevision);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package it.unitn.molerat.repos.trackers.vuln;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class DeletionVulnerabilityEvidenceTracker extends VulnerabilityEvidenceTracker {
|
||||
|
||||
public DeletionVulnerabilityEvidenceTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
super(wrapper, fixedRev);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getInitialVulnerabilityEvidence(Changes changes) throws Exception {
|
||||
return this.recordVulnerabilityEvidence(changes.getDeletions(), changes);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getVulnerabilityEvidence(String currentEvidenceCommit, String previousEvidenceCommit, Set<Changes> changes) throws Exception {
|
||||
Set<VulnerabilityEvidence> newEvidences = new HashSet<>();
|
||||
Set<VulnerabilityEvidence> previousEvidences = getEvidences(previousEvidenceCommit);
|
||||
|
||||
Set<VulnerabilityEvidence> changedEvidence = new HashSet<>();
|
||||
Set<Changes> changesToProcess = new HashSet<>();
|
||||
Set<VulnerabilityEvidence> stillEvidence = new HashSet<>();
|
||||
|
||||
// filter non-Java files
|
||||
changes = filterNonJavaChanges(changes);
|
||||
|
||||
if (previousEvidences == null) {
|
||||
return newEvidences;
|
||||
}
|
||||
|
||||
for (VulnerabilityEvidence previousEvidence : previousEvidences) {
|
||||
for (Changes change : changes ) {
|
||||
// The file has been just renamed
|
||||
if (change.wasRenamed()) {
|
||||
if (change.getRenamedTo().equals(previousEvidence.getPath())) {
|
||||
previousEvidence.setPath(change.getPath());
|
||||
}
|
||||
}
|
||||
// The file has been changed
|
||||
else if (previousEvidence.getPath().equals(change.getPath())) {
|
||||
changedEvidence.add(previousEvidence);
|
||||
changesToProcess.add(change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stillEvidence.addAll(previousEvidences);
|
||||
stillEvidence.removeAll(changedEvidence);
|
||||
|
||||
// "Refresh" the molerat.evidence when a file was not changed
|
||||
for (VulnerabilityEvidence e : stillEvidence) {
|
||||
VulnerabilityEvidence newEvidence = new VulnerabilityEvidence(
|
||||
e.getPath(),
|
||||
currentEvidenceCommit,
|
||||
e.getContainer(),
|
||||
e.getLineNumber(),
|
||||
e.getLineContents()
|
||||
);
|
||||
newEvidences.add(newEvidence);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// "Triage" the molerat.evidence when a file was changed
|
||||
for (Changes change : changesToProcess) {
|
||||
Set<VulnerabilityEvidence> retain = new HashSet<>();
|
||||
for (VulnerabilityEvidence e : changedEvidence) {
|
||||
if (e.getPath().equals(change.getPath())) {
|
||||
retain.add(e);
|
||||
}
|
||||
}
|
||||
Map<Integer, String> linesToKeep = this.updateChangedLines(
|
||||
change.getPath(),
|
||||
change.getLeftRevision(),
|
||||
change.getRightRevision(),
|
||||
retain,
|
||||
change
|
||||
);
|
||||
if (linesToKeep != null) {
|
||||
newEvidences.addAll(this.recordVulnerabilityEvidence(linesToKeep, change));
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
return newEvidences;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
package it.unitn.molerat.repos.trackers.vuln;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
import it.unitn.molerat.repos.utils.SignatureExtractor;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class EnhancedDeletionVulnerabilityEvidenceTracker extends DeletionVulnerabilityEvidenceTracker{
|
||||
|
||||
public EnhancedDeletionVulnerabilityEvidenceTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
super(wrapper, fixedRev);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getInitialVulnerabilityEvidence(Changes changes) throws Exception {
|
||||
if (changes.getDeletions().size() != 0) {
|
||||
return super.getInitialVulnerabilityEvidence(changes);
|
||||
}
|
||||
else {
|
||||
SignatureExtractor se = new SignatureExtractor(repoWrapper.doCat(changes.getPath(), changes.getRightRevision()));
|
||||
Map<String, Set<Integer>> rightSignatures = se.getSignaturesWithLines();
|
||||
|
||||
Set<String> relevantSignatures = new HashSet<>();
|
||||
|
||||
for (int line : changes.getAdditions().keySet()) {
|
||||
for (Map.Entry<String, Set<Integer>> entry : rightSignatures.entrySet()) {
|
||||
if (entry.getValue().contains(line)) {
|
||||
relevantSignatures.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String leftFile = repoWrapper.doCat(changes.getPath(), changes.getLeftRevision());
|
||||
Map<Integer, String> lineMappings = repoWrapper.getLineMappings(leftFile);
|
||||
se = new SignatureExtractor(leftFile);
|
||||
Map<String, Set<Integer>> leftSignatures = se.getSignaturesWithLines();
|
||||
|
||||
for (int line : changes.getDeletions().keySet()) {
|
||||
for (Map.Entry<String, Set<Integer>> entry : leftSignatures.entrySet()) {
|
||||
if (entry.getValue().contains(line)) {
|
||||
relevantSignatures.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set<VulnerabilityEvidence> initialEvidence = new HashSet<>();
|
||||
for (String signature : relevantSignatures) {
|
||||
for (Map.Entry<String, Set<Integer>> entry : leftSignatures.entrySet()) {
|
||||
if (signature.equals(entry.getKey())) {
|
||||
for (int line : entry.getValue()) {
|
||||
VulnerabilityEvidence evd = new VulnerabilityEvidence(
|
||||
changes.getPath(),
|
||||
changes.getLeftRevision(),
|
||||
signature,
|
||||
line,
|
||||
lineMappings.get(line)
|
||||
);
|
||||
initialEvidence.add(evd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return initialEvidence;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package it.unitn.molerat.repos.trackers.vuln;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
public class FixStatisticsVulnerabilityEvidenceTracker extends VulnerabilityEvidenceTracker {
|
||||
private int addedLines = 0;
|
||||
private int deletedLines = 0;
|
||||
private int touchedFiles = 0;
|
||||
private int touchedMethods = 0;
|
||||
|
||||
public FixStatisticsVulnerabilityEvidenceTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
super(wrapper, fixedRev);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getInitialVulnerabilityEvidence(Changes changes) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getVulnerabilityEvidence(String currentEvidenceCommit, String previousEvidenceCommit, Set<Changes> changes) throws Exception {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackEvidence() throws Exception {
|
||||
this.changes = filterNonJavaChanges(this.changes);
|
||||
Iterator<Changes> it = changes.iterator();
|
||||
while (it.hasNext()) {
|
||||
Changes currentChanges = it.next();
|
||||
touchedFiles++;
|
||||
addedLines += currentChanges.getAdditions().size();
|
||||
deletedLines += currentChanges.getDeletions().size();
|
||||
|
||||
Set<String> methods = new HashSet<>();
|
||||
Set<VulnerabilityEvidence> evidences = recordVulnerabilityEvidenceForRightFile(currentChanges.getAdditions(), currentChanges);
|
||||
evidences.addAll(recordVulnerabilityEvidence(currentChanges.getDeletions(), currentChanges));
|
||||
for (VulnerabilityEvidence evd : evidences) {
|
||||
if (!evd.getLineContents().contains("private") &&
|
||||
!evd.getLineContents().contains("protected") &&
|
||||
!evd.getLineContents().contains("public")) {
|
||||
methods.add(evd.getContainer());
|
||||
}
|
||||
}
|
||||
touchedMethods += methods.size();
|
||||
commits.add(currentChanges.getLeftRevision());
|
||||
}
|
||||
}
|
||||
|
||||
public int getNumberOfAddedLines() {
|
||||
return addedLines;
|
||||
}
|
||||
|
||||
public int getNumberOfDeletedLines() {
|
||||
return deletedLines;
|
||||
}
|
||||
|
||||
public int getNumberOfTouchedMethods() {
|
||||
return touchedMethods;
|
||||
}
|
||||
|
||||
public int getNumberOfTouchedFiles() {
|
||||
return touchedFiles;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,148 @@
|
|||
package it.unitn.molerat.repos.trackers.vuln;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
import it.unitn.molerat.repos.utils.SignatureExtractor;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class PatchedMethodBodyTracker extends VulnerabilityEvidenceTracker {
|
||||
|
||||
public PatchedMethodBodyTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
super(wrapper, fixedRev);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getInitialVulnerabilityEvidence(Changes changes) throws Exception {
|
||||
SignatureExtractor se = new SignatureExtractor(repoWrapper.doCat(changes.getPath(), changes.getRightRevision()));
|
||||
Map<String, Set<Integer>> rightSignatures = se.getSignaturesWithLines();
|
||||
|
||||
Set<String> relevantSignatures = new HashSet<>();
|
||||
|
||||
for (int line : changes.getAdditions().keySet()) {
|
||||
for (Map.Entry<String, Set<Integer>> entry : rightSignatures.entrySet()) {
|
||||
if (entry.getValue().contains(line)) {
|
||||
relevantSignatures.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String leftFile = repoWrapper.doCat(changes.getPath(), changes.getLeftRevision());
|
||||
Map<Integer, String> lineMappings = repoWrapper.getLineMappings(leftFile);
|
||||
se = new SignatureExtractor(leftFile);
|
||||
Map<String, Set<Integer>> leftSignatures = se.getSignaturesWithLines();
|
||||
|
||||
for (int line : changes.getDeletions().keySet()) {
|
||||
for (Map.Entry<String, Set<Integer>> entry : leftSignatures.entrySet()) {
|
||||
if (entry.getValue().contains(line)) {
|
||||
relevantSignatures.add(entry.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Set<VulnerabilityEvidence> initialEvidence = new HashSet<>();
|
||||
for (String signature : relevantSignatures) {
|
||||
for (Map.Entry<String, Set<Integer>> entry : leftSignatures.entrySet()) {
|
||||
if (signature.equals(entry.getKey())) {
|
||||
for (int line : entry.getValue()) {
|
||||
VulnerabilityEvidence evd = new VulnerabilityEvidence(
|
||||
changes.getPath(),
|
||||
changes.getLeftRevision(),
|
||||
signature,
|
||||
line,
|
||||
lineMappings.get(line)
|
||||
);
|
||||
initialEvidence.add(evd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return initialEvidence;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getVulnerabilityEvidence(String currentEvidenceCommit, String previousEvidenceCommit, Set<Changes> changes) throws Exception {
|
||||
Set<VulnerabilityEvidence> newEvidences = new HashSet<>();
|
||||
Set<VulnerabilityEvidence> previousEvidences = getEvidences(previousEvidenceCommit);
|
||||
|
||||
Set<VulnerabilityEvidence> changedEvidence = new HashSet<>();
|
||||
Set<Changes> changesToProcess = new HashSet<>();
|
||||
Set<VulnerabilityEvidence> stillEvidence = new HashSet<>();
|
||||
|
||||
// filter non-Java files
|
||||
changes = filterNonJavaChanges(changes);
|
||||
|
||||
if (previousEvidences == null) {
|
||||
return newEvidences;
|
||||
}
|
||||
|
||||
for (VulnerabilityEvidence previousEvidence : previousEvidences) {
|
||||
for (Changes change : changes ) {
|
||||
// The file has been just renamed
|
||||
if (change.wasRenamed()) {
|
||||
if (change.getRenamedTo().equals(previousEvidence.getPath())) {
|
||||
previousEvidence.setPath(change.getPath());
|
||||
}
|
||||
}
|
||||
// The file has been changed
|
||||
else if (previousEvidence.getPath().equals(change.getPath())) {
|
||||
changedEvidence.add(previousEvidence);
|
||||
changesToProcess.add(change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stillEvidence.addAll(previousEvidences);
|
||||
stillEvidence.removeAll(changedEvidence);
|
||||
|
||||
// "Refresh" the molerat.evidence when a file was not changed
|
||||
for (VulnerabilityEvidence e : stillEvidence) {
|
||||
VulnerabilityEvidence newEvidence = new VulnerabilityEvidence(
|
||||
e.getPath(),
|
||||
currentEvidenceCommit,
|
||||
e.getContainer(),
|
||||
e.getLineNumber(),
|
||||
e.getLineContents()
|
||||
);
|
||||
newEvidences.add(newEvidence);
|
||||
}
|
||||
|
||||
// "Triage" the molerat.evidence when a file was changed
|
||||
for (Changes change : changesToProcess) {
|
||||
Set<String> relevantSignatures = new HashSet<>();
|
||||
for (VulnerabilityEvidence e : changedEvidence) {
|
||||
relevantSignatures.add(e.getContainer());
|
||||
}
|
||||
|
||||
String leftFile = repoWrapper.doCat(change.getPath(), change.getLeftRevision());
|
||||
Map<Integer, String> lineMappings = repoWrapper.getLineMappings(leftFile);
|
||||
SignatureExtractor se = new SignatureExtractor(leftFile);
|
||||
Map<String, Set<Integer>> leftSignatures = se.getSignaturesWithLines();
|
||||
|
||||
for (String signature : relevantSignatures) {
|
||||
for (Map.Entry<String, Set<Integer>> entry : leftSignatures.entrySet()) {
|
||||
if (signature.equals(entry.getKey())) {
|
||||
for (int line : entry.getValue()) {
|
||||
VulnerabilityEvidence evd = new VulnerabilityEvidence(
|
||||
change.getPath(),
|
||||
change.getLeftRevision(),
|
||||
signature,
|
||||
line,
|
||||
lineMappings.get(line)
|
||||
);
|
||||
newEvidences.add(evd);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return newEvidences;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package it.unitn.molerat.repos.trackers.vuln;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class SliceDecayVulnerabilityEvidenceTracker extends SliceVulnerabilityEvidenceTracker {
|
||||
|
||||
public SliceDecayVulnerabilityEvidenceTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
super(wrapper, fixedRev);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getVulnerabilityEvidence(String currentEvidenceCommit, String previousEvidenceCommit, Set<Changes> changes) throws Exception {
|
||||
Set<VulnerabilityEvidence> newEvidences = new HashSet<>();
|
||||
Set<VulnerabilityEvidence> previousEvidences = getEvidences(previousEvidenceCommit);
|
||||
Set<VulnerabilityEvidence> changedEvidence = new HashSet<>();
|
||||
|
||||
Set<Changes> changesToProcess = new HashSet<>();
|
||||
Set<VulnerabilityEvidence> stillEvidence = new HashSet<>();
|
||||
|
||||
// filter non-Java files
|
||||
changes = filterNonJavaChanges(changes);
|
||||
|
||||
if (previousEvidences == null) {
|
||||
return newEvidences;
|
||||
}
|
||||
|
||||
for (VulnerabilityEvidence previousEvidence : previousEvidences) {
|
||||
for (Changes change : changes ) {
|
||||
// The file has been just renamed
|
||||
if (change.wasRenamed()) {
|
||||
if (change.getRenamedTo().equals(previousEvidence.getPath())) {
|
||||
previousEvidence.setPath(change.getPath());
|
||||
}
|
||||
}
|
||||
// The file has been changed
|
||||
else if (previousEvidence.getPath().equals(change.getPath())) {
|
||||
changedEvidence.add(previousEvidence);
|
||||
changesToProcess.add(change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stillEvidence.addAll(previousEvidences);
|
||||
stillEvidence.removeAll(changedEvidence);
|
||||
|
||||
// "Refresh" the molerat.evidence when a file was not changed
|
||||
for (VulnerabilityEvidence e : stillEvidence) {
|
||||
VulnerabilityEvidence newEvidence = new VulnerabilityEvidence(
|
||||
e.getPath(),
|
||||
currentEvidenceCommit,
|
||||
e.getContainer(),
|
||||
e.getLineNumber(),
|
||||
e.getLineContents()
|
||||
);
|
||||
newEvidences.add(newEvidence);
|
||||
}
|
||||
|
||||
// "Triage" the molerat.evidence when a file was changed
|
||||
for (Changes change : changesToProcess) {
|
||||
Set<VulnerabilityEvidence> retain = new HashSet<>();
|
||||
for (VulnerabilityEvidence e : changedEvidence) {
|
||||
if (e.getPath().equals(change.getPath())) {
|
||||
retain.add(e);
|
||||
}
|
||||
}
|
||||
Map<Integer, String> linesToKeep = this.updateChangedLines(
|
||||
change.getPath(),
|
||||
change.getLeftRevision(),
|
||||
change.getRightRevision(),
|
||||
retain,
|
||||
change
|
||||
);
|
||||
if (linesToKeep != null) {
|
||||
newEvidences.addAll(this.recordVulnerabilityEvidence(linesToKeep, change));
|
||||
}
|
||||
}
|
||||
return newEvidences;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,139 @@
|
|||
package it.unitn.molerat.repos.trackers.vuln;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
import it.unitn.repoman.core.lang.LanguageFactory;
|
||||
import it.unitn.repoman.core.slicers.LightweightSlice;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class SliceVulnerabilityEvidenceTracker extends VulnerabilityEvidenceTracker {
|
||||
|
||||
public SliceVulnerabilityEvidenceTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
super(wrapper, fixedRev);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getInitialVulnerabilityEvidence(Changes changes) throws Exception {
|
||||
// 1. Take the added lines as the slicing criteria and obtain the slice on the fixed revision
|
||||
Map<Integer, String> slicingCriteria = changes.getAdditions();
|
||||
String rightFile = this.repoWrapper.doCat(changes.getPath(), changes.getRightRevision());
|
||||
Map<Integer, String> sliced = this.doSlice(slicingCriteria, rightFile);
|
||||
|
||||
Set<VulnerabilityEvidence> slicedEvd = this.recordVulnerabilityEvidenceForRightFile(sliced, changes);
|
||||
|
||||
// 2. we need to check which lines from the "fixed" slice are present in the vulnerable revision
|
||||
// 2.1 we "correlate" the lines from the "fixed" slice to the vulnerable revision
|
||||
Map<Integer, String> propagated = this.updateChangedLines(changes.getPath(), changes.getLeftRevision(),
|
||||
changes.getRightRevision(), slicedEvd, changes);
|
||||
|
||||
// 2.2 take deleted lines + "correlated" changes from the fixed slice and take a new slice on the vulnerable revision
|
||||
propagated.putAll(changes.getDeletions());
|
||||
|
||||
// 3.1 make the final slice on the vulnerable revision
|
||||
slicingCriteria = propagated;
|
||||
String leftFile = this.repoWrapper.doCat(changes.getPath(), changes.getLeftRevision());
|
||||
sliced = this.doSlice(slicingCriteria, leftFile);
|
||||
propagated.putAll(sliced);
|
||||
|
||||
Set<VulnerabilityEvidence> initialEvidence = this.recordVulnerabilityEvidence(propagated, changes);
|
||||
return initialEvidence;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected Set<VulnerabilityEvidence> getVulnerabilityEvidence(String currentEvidenceCommit, String previousEvidenceCommit, Set<Changes> changes) throws Exception {
|
||||
Set<VulnerabilityEvidence> newEvidences = new HashSet<>();
|
||||
Set<VulnerabilityEvidence> previousEvidences = getEvidences(previousEvidenceCommit);
|
||||
|
||||
Set<VulnerabilityEvidence> changedEvidence = new HashSet<>();
|
||||
Set<Changes> changesToProcess = new HashSet<>();
|
||||
Set<VulnerabilityEvidence> stillEvidence = new HashSet<>();
|
||||
|
||||
// filter non-Java files
|
||||
changes = filterNonJavaChanges(changes);
|
||||
|
||||
if (previousEvidences == null) {
|
||||
return newEvidences;
|
||||
}
|
||||
|
||||
for (VulnerabilityEvidence previousEvidence : previousEvidences) {
|
||||
for (Changes change : changes ) {
|
||||
// The file has been just renamed
|
||||
if (change.wasRenamed()) {
|
||||
if (change.getRenamedTo().equals(previousEvidence.getPath())) {
|
||||
previousEvidence.setPath(change.getPath());
|
||||
}
|
||||
}
|
||||
// The file has been changed
|
||||
else if (previousEvidence.getPath().equals(change.getPath())) {
|
||||
changedEvidence.add(previousEvidence);
|
||||
changesToProcess.add(change);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stillEvidence.addAll(previousEvidences);
|
||||
stillEvidence.removeAll(changedEvidence);
|
||||
|
||||
// "Refresh" the molerat.evidence when a file was not changed
|
||||
for (VulnerabilityEvidence e : stillEvidence) {
|
||||
VulnerabilityEvidence newEvidence = new VulnerabilityEvidence(
|
||||
e.getPath(),
|
||||
currentEvidenceCommit,
|
||||
e.getContainer(),
|
||||
e.getLineNumber(),
|
||||
e.getLineContents()
|
||||
);
|
||||
newEvidences.add(newEvidence);
|
||||
}
|
||||
|
||||
// "Triage" the molerat.evidence when a file was changed
|
||||
for (Changes change : changesToProcess) {
|
||||
// --------------------------------------
|
||||
Map<Integer, String> slicingCriteria = new TreeMap<>();
|
||||
for (VulnerabilityEvidence e : changedEvidence) {
|
||||
if (e.getPath().equals(change.getPath())) {
|
||||
slicingCriteria.put(e.getLineNumber(), e.getLineContents());
|
||||
}
|
||||
}
|
||||
String rightFile = this.repoWrapper.doCat(change.getPath(), change.getRightRevision());
|
||||
Map<Integer, String> slice = this.doSlice(slicingCriteria, rightFile);
|
||||
Set<VulnerabilityEvidence> slicedEvd = this.recordVulnerabilityEvidenceForRightFile(slice, change);
|
||||
|
||||
Map<Integer, String> linesToKeep = this.updateChangedLines(
|
||||
change.getPath(),
|
||||
change.getLeftRevision(),
|
||||
change.getRightRevision(),
|
||||
slicedEvd,
|
||||
change
|
||||
);
|
||||
if (linesToKeep != null) {
|
||||
String leftFile = this.repoWrapper.doCat(change.getPath(), change.getLeftRevision());
|
||||
slice = this.doSlice(linesToKeep, leftFile);
|
||||
newEvidences.addAll(this.recordVulnerabilityEvidence(slice, change));
|
||||
}
|
||||
}
|
||||
return newEvidences;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected Map<Integer, String> doSlice(Map<Integer, String> slicingCriteria, String fileContents) {
|
||||
Map<Integer, String> sliced = this.repoWrapper.getLineMappings(fileContents);
|
||||
LanguageFactory.init("Java", fileContents);
|
||||
LightweightSlice slice;
|
||||
try {
|
||||
slice = new LightweightSlice(LanguageFactory.getRoot(), slicingCriteria.keySet());
|
||||
sliced.keySet().retainAll(slice.getSelectedLines());
|
||||
} catch (Exception e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
return sliced;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,234 @@
|
|||
package it.unitn.molerat.repos.trackers.vuln;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
import it.unitn.molerat.repos.trackers.AbstractEvidenceTracker;
|
||||
import it.unitn.molerat.repos.utils.SignatureExtractor;
|
||||
import it.unitn.molerat.evidence.VulnerabilityEvidence;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class VulnerabilityEvidenceTracker extends AbstractEvidenceTracker {
|
||||
|
||||
protected Map<String, Set<VulnerabilityEvidence>> evidences = new LinkedHashMap<String, Set<VulnerabilityEvidence>>();
|
||||
|
||||
public VulnerabilityEvidenceTracker(RepoWrapper wrapper, String fixedRev) throws Exception {
|
||||
super(wrapper, fixedRev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void trackEvidence() throws Exception {
|
||||
// I. Filter all non-Java files that have been changed
|
||||
this.changes = filterNonJavaChanges(this.changes);
|
||||
// -------------------------------------------------
|
||||
// II. Get the initial molerat.evidence from the fix
|
||||
Iterator<Changes> it = changes.iterator();
|
||||
while (it.hasNext()) {
|
||||
Changes currentChanges = it.next();
|
||||
Set<VulnerabilityEvidence> tempVulnEvidences = getInitialVulnerabilityEvidence(currentChanges);
|
||||
for (VulnerabilityEvidence evidence : tempVulnEvidences) {
|
||||
addEvidence(evidence);
|
||||
}
|
||||
commits.add(currentChanges.getLeftRevision());
|
||||
}
|
||||
// -------------------------------------------------
|
||||
// III. Collect evidences across the rest of commits
|
||||
String rightCommit = this.vulnRevision;
|
||||
|
||||
Iterator<String> commitIterator = restOfCommits.iterator();
|
||||
String commit = "";
|
||||
while (commitIterator.hasNext()) {
|
||||
commit = commitIterator.next();
|
||||
// Get the current changes
|
||||
String leftCommit = commit;
|
||||
String diffTxt = repoWrapper.doDiff(leftCommit, rightCommit);
|
||||
Set<Changes> currentChanges = repoWrapper.inferChangesFromDiff(diffTxt, leftCommit, rightCommit);
|
||||
|
||||
Set<VulnerabilityEvidence> newEvidences = new HashSet<>();
|
||||
newEvidences = getVulnerabilityEvidence(leftCommit, rightCommit, currentChanges);
|
||||
|
||||
// did the method/file/molerat.evidence disappear?
|
||||
if (newEvidences.size() == 0) {
|
||||
break;
|
||||
} else {
|
||||
for (VulnerabilityEvidence evidence : newEvidences) {
|
||||
addEvidence(evidence);
|
||||
}
|
||||
rightCommit = leftCommit;
|
||||
commits.add(commit);
|
||||
}
|
||||
}
|
||||
if (commit.equals("")) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public Set<VulnerabilityEvidence> getEvidences(String commit) {
|
||||
Set<VulnerabilityEvidence> evd = this.evidences.get(commit);
|
||||
return (evd != null) ? evd : new HashSet<>();
|
||||
}
|
||||
|
||||
public Map<String, Integer> countEvidenceInFiles(String commit) {
|
||||
Map<String, Integer> counts = new TreeMap<>();
|
||||
Set<VulnerabilityEvidence> evd = getEvidences(commit);
|
||||
for (VulnerabilityEvidence e : evd) {
|
||||
String filename = e.getPath();
|
||||
if (!counts.containsKey(filename)) {
|
||||
if (e.getLineNumber() != 0) {
|
||||
counts.put(filename, 1);
|
||||
}
|
||||
else {
|
||||
counts.put(filename, 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (e.getLineNumber() == 0) {
|
||||
counts.replace(filename, 0);
|
||||
}
|
||||
else {
|
||||
int locCount = counts.get(filename);
|
||||
locCount++;
|
||||
counts.replace(filename, locCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
return counts;
|
||||
}
|
||||
|
||||
public Map<String, Set<VulnerabilityEvidence>> getEvidences() {
|
||||
return this.evidences;
|
||||
}
|
||||
|
||||
protected void addEvidence(VulnerabilityEvidence evidence) {
|
||||
if (this.evidences.containsKey(evidence.getCommit())) {
|
||||
evidences.get(evidence.getCommit()).add(evidence);
|
||||
}
|
||||
else {
|
||||
Set<VulnerabilityEvidence> set = new HashSet<>();
|
||||
set.add(evidence);
|
||||
this.evidences.put(evidence.getCommit(), set);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Set<VulnerabilityEvidence> getInitialVulnerabilityEvidence(Changes changes) throws Exception;
|
||||
|
||||
protected abstract Set<VulnerabilityEvidence> getVulnerabilityEvidence(String currentEvidenceCommit, String previousEvidenceCommit, Set<Changes> changes) throws Exception;
|
||||
|
||||
protected Set<VulnerabilityEvidence> recordVulnerabilityEvidence(Map<Integer, String> lines, Changes changes) throws Exception {
|
||||
Set<VulnerabilityEvidence> evidences = new HashSet<>();
|
||||
String fileContents = this.repoWrapper.doCat(changes.getPath(), changes.getLeftRevision());
|
||||
SignatureExtractor se = new SignatureExtractor(fileContents);
|
||||
Map<String, Set<Integer>> containers = se.getSignaturesWithLines();
|
||||
for (Map.Entry<String, Set<Integer>> containerEntry : containers.entrySet()) {
|
||||
for (Map.Entry<Integer, String> lineEntry : lines.entrySet()) {
|
||||
if (containerEntry.getValue().contains(lineEntry.getKey())) {
|
||||
VulnerabilityEvidence evidence = new VulnerabilityEvidence(
|
||||
changes.getPath(),
|
||||
changes.getLeftRevision(),
|
||||
containerEntry.getKey(),
|
||||
lineEntry.getKey(),
|
||||
lineEntry.getValue()
|
||||
);
|
||||
evidences.add(evidence);
|
||||
}
|
||||
}
|
||||
}
|
||||
return evidences;
|
||||
}
|
||||
|
||||
protected Set<VulnerabilityEvidence> recordVulnerabilityEvidenceForRightFile(Map<Integer, String> lines, Changes changes) throws Exception {
|
||||
Set<VulnerabilityEvidence> evidences = new HashSet<>();
|
||||
String fileContents = this.repoWrapper.doCat(changes.getPath(), changes.getRightRevision());
|
||||
SignatureExtractor se = new SignatureExtractor(fileContents);
|
||||
Map<String, Set<Integer>> containers = se.getSignaturesWithLines();
|
||||
for (Map.Entry<String, Set<Integer>> containerEntry : containers.entrySet()) {
|
||||
for (Map.Entry<Integer, String> lineEntry : lines.entrySet()) {
|
||||
if (containerEntry.getValue().contains(lineEntry.getKey())) {
|
||||
VulnerabilityEvidence evidence = new VulnerabilityEvidence(
|
||||
changes.getPath(),
|
||||
changes.getRightRevision(),
|
||||
containerEntry.getKey(),
|
||||
lineEntry.getKey(),
|
||||
lineEntry.getValue()
|
||||
);
|
||||
evidences.add(evidence);
|
||||
}
|
||||
}
|
||||
}
|
||||
return evidences;
|
||||
}
|
||||
|
||||
|
||||
protected Map<Integer, String> updateChangedLines(String path, String leftRev, String rightRev, Set<VulnerabilityEvidence> retain, Changes change) throws Exception {
|
||||
Map<Integer, String> linesToKeep = new TreeMap<>();
|
||||
String leftFile = this.repoWrapper.doCat(path, leftRev);
|
||||
String rightFile = this.repoWrapper.doCat(path, rightRev);
|
||||
|
||||
SignatureExtractor rightSignatures = new SignatureExtractor(rightFile);
|
||||
Map<String, Set<Integer>> rightLineSignatures = rightSignatures.getSignaturesWithLines();
|
||||
Map<Integer, String> rightLineMappings = this.repoWrapper.getLineMappings(rightFile);
|
||||
|
||||
SignatureExtractor leftSignatures = new SignatureExtractor(leftFile);
|
||||
Map<String, Set<Integer>> leftLineSignatures = leftSignatures.getSignaturesWithLines();
|
||||
Map<Integer, String> leftLineMappings = this.repoWrapper.getLineMappings(leftFile);
|
||||
|
||||
for (VulnerabilityEvidence evd : retain) {
|
||||
String container = evd.getContainer();
|
||||
Set<Integer> lineNumbers = leftLineSignatures.get(container);
|
||||
|
||||
Map<Integer, String> leftChunk = new TreeMap<>();
|
||||
|
||||
// the left container might not exist anymore...
|
||||
if (lineNumbers == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// otherwise, process
|
||||
for (int lineNumber : lineNumbers) {
|
||||
leftChunk.put(lineNumber, leftLineMappings.get(lineNumber));
|
||||
}
|
||||
|
||||
lineNumbers = rightLineSignatures.get(container);
|
||||
Map<Integer, String> rightChunk = new TreeMap<>();
|
||||
for (int lineNumber : lineNumbers) {
|
||||
rightChunk.put(lineNumber, rightLineMappings.get(lineNumber));
|
||||
}
|
||||
|
||||
String leftLine = leftChunk.get(evd.getLineNumber());
|
||||
String rightLine = rightChunk.get(evd.getLineNumber());
|
||||
|
||||
if (leftLine != null && rightLine != null && leftLine.equals(rightLine)) {
|
||||
linesToKeep.put(evd.getLineNumber(), evd.getLineContents());
|
||||
continue;
|
||||
} else {
|
||||
if (rightLine != null && rightLine.equals(evd.getLineContents())) {
|
||||
Map<Integer, String> eligibleCandidates = new TreeMap<>();
|
||||
for (Map.Entry<Integer, String> candidateLine : leftChunk.entrySet()) {
|
||||
if (candidateLine.getValue().equals(evd.getLineContents())) {
|
||||
eligibleCandidates.put(candidateLine.getKey(), evd.getLineContents());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (eligibleCandidates.size() > 1) {
|
||||
Iterator<Map.Entry<Integer, String>> it = eligibleCandidates.entrySet().iterator();
|
||||
int leftLineNumber = it.next().getKey();
|
||||
int rightLineNumber = evd.getLineNumber();
|
||||
int minimumDistance = rightLineNumber - leftLineNumber;
|
||||
while (it.hasNext()) {
|
||||
leftLineNumber = it.next().getKey();
|
||||
int tempMinimumDistance = rightLineNumber - leftLineNumber;
|
||||
minimumDistance = (Math.abs(tempMinimumDistance) < Math.abs(minimumDistance)) ? tempMinimumDistance : minimumDistance;
|
||||
}
|
||||
int newLineNumber = rightLineNumber - minimumDistance;
|
||||
String newLineContents = eligibleCandidates.get(newLineNumber);
|
||||
linesToKeep.put(newLineNumber, newLineContents);
|
||||
}
|
||||
else {
|
||||
linesToKeep.putAll(eligibleCandidates);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return linesToKeep;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package it.unitn.molerat.repos.trackers.vuln;
|
||||
|
||||
import it.unitn.molerat.repos.wrappers.GitRepoWrapper;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
import it.unitn.molerat.repos.wrappers.SvnRepoWrapper;
|
||||
|
||||
public class VulnerabilityEvidenceTrackerFactory {
|
||||
|
||||
public static VulnerabilityEvidenceTracker getTracker(String repoRoot, String fixedRev, String wrapperType, String trackerType) throws Exception {
|
||||
RepoWrapper wrapper = null;
|
||||
switch (wrapperType.toLowerCase()) {
|
||||
case "svn":
|
||||
wrapper = new SvnRepoWrapper(repoRoot);
|
||||
break;
|
||||
|
||||
case "git":
|
||||
wrapper = new GitRepoWrapper(repoRoot);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("There is currently no support for '" + wrapperType + "'");
|
||||
}
|
||||
VulnerabilityEvidenceTracker vulnerabilityEvidenceTracker = null;
|
||||
switch (trackerType.toLowerCase()) {
|
||||
case "deletionvulnerabilityevidencetracker":
|
||||
vulnerabilityEvidenceTracker = new DeletionVulnerabilityEvidenceTracker(wrapper, fixedRev);
|
||||
break;
|
||||
|
||||
case "slicevulnerabilityevidencetracker":
|
||||
vulnerabilityEvidenceTracker = new SliceVulnerabilityEvidenceTracker(wrapper, fixedRev);
|
||||
break;
|
||||
|
||||
case "slicedecayvulnerabilityevidencetracker":
|
||||
vulnerabilityEvidenceTracker = new SliceDecayVulnerabilityEvidenceTracker(wrapper, fixedRev);
|
||||
break;
|
||||
|
||||
case "patchedmethodbodytracker":
|
||||
vulnerabilityEvidenceTracker = new PatchedMethodBodyTracker(wrapper, fixedRev);
|
||||
break;
|
||||
|
||||
case "enhanceddeletionvulnerabilityevidencetracker":
|
||||
vulnerabilityEvidenceTracker = new EnhancedDeletionVulnerabilityEvidenceTracker(wrapper, fixedRev);
|
||||
break;
|
||||
|
||||
case "fixstatisticsvulnerabilityevidencetracker":
|
||||
vulnerabilityEvidenceTracker = new FixStatisticsVulnerabilityEvidenceTracker(wrapper, fixedRev);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new Exception("There is no such molerat.evidence tracker as '" + trackerType + "'");
|
||||
}
|
||||
return vulnerabilityEvidenceTracker;
|
||||
}
|
||||
|
||||
public static String getTrackersList() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("--------------------\n");
|
||||
builder.append("The list of available vulnerability molerat.evidence trackers:\n");
|
||||
builder.append("--------------------\n");
|
||||
builder.append("\n");
|
||||
builder.append("\t\"SliceDecayVulnerabilityEvidenceTracker\" - track intra-procedural slice over the fixed lines.\n");
|
||||
builder.append("\n");
|
||||
builder.append("\t\"DeletionVulnerabilityEvidenceTracker\" - track only the lines deleted during a fix.\n");
|
||||
builder.append("\n");
|
||||
builder.append("\t\"PatchedMethodBodyTracker\" - track the entire fixed methods.\n");
|
||||
builder.append("\n");
|
||||
builder.append("\t\"EnhancedDeletionVulnerabilityEvidenceTracker\" - track only the lines deleted during a fix, " +
|
||||
"or the entire fixed methods if there are no deleted lines.\n");
|
||||
builder.append("\n");
|
||||
builder.append("--------------------\n");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
package it.unitn.molerat.repos.utils;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
import it.unitn.molerat.repos.wrappers.RepoWrapper;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class CommitMetrics {
|
||||
|
||||
private static final Pattern deletedPublicMethodPattern = Pattern.compile("public .*\\([^\\)]*\\)[^;]*$");
|
||||
|
||||
public static int getGlobalPublicMethodsRemoved(String leftRev, String rightRev, RepoWrapper wrapper) throws Exception {
|
||||
int removed = 0;
|
||||
String diff = wrapper.doDiff(leftRev, rightRev);
|
||||
Set<Changes> changes = wrapper.inferChangesFromDiff(diff, leftRev, rightRev);
|
||||
for (Changes change : changes) {
|
||||
if (!change.getPath().endsWith(".java")) {
|
||||
continue;
|
||||
}
|
||||
Map<Integer, String> deletions = change.getDeletions();
|
||||
wrapper.filterCommentsAndBlanks(deletions);
|
||||
for (String del : deletions.values()) {
|
||||
del = StringUtils.trim(del);
|
||||
Matcher matcher = deletedPublicMethodPattern.matcher(del);
|
||||
if (matcher.matches()) {
|
||||
removed++;
|
||||
}
|
||||
matcher.reset();
|
||||
}
|
||||
}
|
||||
return removed;
|
||||
}
|
||||
|
||||
public static int getNumberOfPublicMethodsPerRevision(String rev, RepoWrapper wrapper) throws Exception {
|
||||
int pubAPICount = 0;
|
||||
Set<String> files = wrapper.getRevisionFiles(rev, ".java");
|
||||
for (String f : files) {
|
||||
String fc = wrapper.doCat(f, rev);
|
||||
pubAPICount += countPublicMethodDeclarationsInFile(fc);
|
||||
}
|
||||
return pubAPICount;
|
||||
}
|
||||
|
||||
public static Map<String, String> getFileContentsPerRevision(String rev, RepoWrapper wrapper) throws Exception {
|
||||
Map<String,String> result = new TreeMap<>();
|
||||
Set<String> files = wrapper.getRevisionFiles(rev, ".java");
|
||||
for (String file : files) {
|
||||
String contents = wrapper.doCat(file, rev);
|
||||
result.put(file, contents);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static int countPublicMethodDeclarationsInFile(String fileContents) {
|
||||
int pubAPICount = 0;
|
||||
String[] lines = StringUtils.split(fileContents, System.getProperty("line.separator"));
|
||||
for (int i=0; i<lines.length; i++) {
|
||||
String line = StringUtils.replace(lines[i], "\t", " ");
|
||||
line = StringUtils.trim(line);
|
||||
if (StringUtils.startsWith(line, "public ")) {
|
||||
int indexOfPublic = StringUtils.indexOf(line, "public");
|
||||
int firstOpenBracket = StringUtils.indexOf(line, '(');
|
||||
int lastOpenBracket = StringUtils.indexOf(line, '(');
|
||||
int firstCloseBracket = StringUtils.indexOf(line, ')');
|
||||
int lastCloseBracket = StringUtils.indexOf(line, ')');
|
||||
|
||||
if ((indexOfPublic < firstOpenBracket) && (firstOpenBracket == lastOpenBracket) &&
|
||||
(firstCloseBracket == lastCloseBracket) && (firstOpenBracket < firstCloseBracket)) {
|
||||
int semicolonIndex = StringUtils.indexOf(line, ';');
|
||||
if (semicolonIndex == -1) {
|
||||
StringBuilder chunk = new StringBuilder();
|
||||
String nextLine = "";
|
||||
for (int j=i; j<lines.length; j++) {
|
||||
nextLine = StringUtils.replace(lines[j], "\t", " ");
|
||||
nextLine = StringUtils.trim(nextLine);
|
||||
if (StringUtils.indexOf(nextLine, ';') != -1) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
chunk.append(nextLine);
|
||||
}
|
||||
}
|
||||
if (StringUtils.contains(chunk.toString(), '{')) {
|
||||
pubAPICount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return pubAPICount;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
package it.unitn.molerat.repos.utils;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import it.unitn.molerat.data.csv.InputDataPoint;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
public final class IORoutines {
|
||||
|
||||
private static File throwExceptionIfDoesNotExist(String path) throws FileNotFoundException {
|
||||
File javaFile = new File(path);
|
||||
if (!javaFile.exists()) {
|
||||
throw new FileNotFoundException(path);
|
||||
}
|
||||
return javaFile;
|
||||
}
|
||||
|
||||
public static String readFile(String path) throws IOException {
|
||||
File javaFile = throwExceptionIfDoesNotExist(path);
|
||||
BufferedReader in = new BufferedReader(new FileReader(javaFile));
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
String line = null;
|
||||
try {
|
||||
while ( (line = in.readLine()) != null) {
|
||||
buffer.append(line);
|
||||
buffer.append('\n');
|
||||
}
|
||||
}
|
||||
finally {
|
||||
in.close();
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public static void writeFile(String path, String contents) throws IOException {
|
||||
File file = null;
|
||||
FileOutputStream outStream = null;
|
||||
try {
|
||||
file = new File(path);
|
||||
outStream = new FileOutputStream(file, true);
|
||||
if (!file.exists()) {
|
||||
file.createNewFile();
|
||||
}
|
||||
byte[] bytes = contents.getBytes();
|
||||
outStream.write(bytes);
|
||||
} catch (IOException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
throw new IOException(e.getMessage());
|
||||
} finally {
|
||||
try {
|
||||
if (outStream != null) {
|
||||
outStream.flush();
|
||||
outStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> readFileBrokenByLines(String path) throws IOException {
|
||||
File javaFile = throwExceptionIfDoesNotExist(path);
|
||||
Set<String> lines = new LinkedHashSet<String>();
|
||||
BufferedReader in = new BufferedReader(new FileReader(javaFile));
|
||||
String line = null;
|
||||
try {
|
||||
while ( (line = in.readLine()) != null) {
|
||||
lines.add(line);
|
||||
}
|
||||
}
|
||||
finally {
|
||||
in.close();
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
public static void readFilesRecursively(File source, Set<String> results) {
|
||||
if (!source.exists()) {
|
||||
return;
|
||||
}
|
||||
else if (source.isDirectory()) {
|
||||
String[] files = source.list();
|
||||
for (String file : files) {
|
||||
readFilesRecursively(new File(source,file), results);
|
||||
}
|
||||
}
|
||||
else {
|
||||
try {
|
||||
String result = readFile(source.getAbsolutePath());
|
||||
results.add(result);
|
||||
} catch (IOException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<InputDataPoint> readInputDataPoints(String path) throws Exception {
|
||||
Set<InputDataPoint> dataPointSet = new HashSet<>();
|
||||
File file2Parse = new File(path);
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
String line = "";
|
||||
reader = new BufferedReader(new FileReader(file2Parse));
|
||||
while ((line = reader.readLine()) != null) {
|
||||
InputDataPoint inputDataPoint = new InputDataPoint(line);
|
||||
dataPointSet.add(inputDataPoint);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (Exception e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
return dataPointSet;
|
||||
}
|
||||
|
||||
|
||||
public static File joinpaths(String path1, String path2) {
|
||||
return new File(path1, path2);
|
||||
}
|
||||
|
||||
public static void mkdir(File dir) {
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void copyFolders(File source, File destination) {
|
||||
if (source.isDirectory() && destination.isDirectory()) {
|
||||
try {
|
||||
FileUtils.copyDirectory(source, destination);
|
||||
} catch (IOException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,233 @@
|
|||
package it.unitn.molerat.repos.utils;
|
||||
|
||||
import it.unitn.repoman.core.lang.LanguageFactory;
|
||||
import it.unitn.repoman.core.lang.parsers.java.JavaBaseListener;
|
||||
import it.unitn.repoman.core.lang.parsers.java.JavaParser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeWalker;
|
||||
import org.antlr.v4.runtime.tree.TerminalNodeImpl;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Queue;
|
||||
import java.util.HashSet;
|
||||
|
||||
public class SignatureExtractor extends JavaBaseListener {
|
||||
|
||||
private String className = "";
|
||||
private String packageName = "";
|
||||
private String currentSignature = "";
|
||||
private final Map<String, Set<Integer>> lines = new TreeMap<>();
|
||||
private final Queue<ParserRuleContext> modifiers = new LinkedList<>();
|
||||
|
||||
|
||||
public SignatureExtractor(String fileContents) {
|
||||
LanguageFactory.init("java", fileContents);
|
||||
ParseTreeWalker walker = new ParseTreeWalker();
|
||||
walker.walk(this, LanguageFactory.getRoot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterPackageDeclaration(JavaParser.PackageDeclarationContext ctx) {
|
||||
packageName = ctx.getChild(1).getText();
|
||||
currentSignature = packageName;
|
||||
processLine(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitPackageDeclaration(JavaParser.PackageDeclarationContext ctx) {
|
||||
currentSignature = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterClassOrInterfaceModifier(JavaParser.ClassOrInterfaceModifierContext ctx) {
|
||||
modifiers.add(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterMethodDeclaration(JavaParser.MethodDeclarationContext ctx) {
|
||||
StringBuilder methodDeclBuilder = new StringBuilder();
|
||||
getMethodSignature(ctx,methodDeclBuilder);
|
||||
String currentModifiers = retrieveModifiers();
|
||||
|
||||
StringBuilder signatureBuilder = new StringBuilder();
|
||||
signatureBuilder.append(currentModifiers);
|
||||
signatureBuilder.append(": ");
|
||||
signatureBuilder.append(joinPackageNameWithClassName());
|
||||
signatureBuilder.append(".");
|
||||
signatureBuilder.append(methodDeclBuilder.toString());
|
||||
currentSignature = signatureBuilder.toString();
|
||||
}
|
||||
|
||||
private String joinPackageNameWithClassName() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (!packageName.equals("")) {
|
||||
builder.append(packageName);
|
||||
builder.append(".");
|
||||
}
|
||||
builder.append(className);
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitMethodDeclaration(JavaParser.MethodDeclarationContext ctx) {
|
||||
currentSignature = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterConstructorDeclaration(JavaParser.ConstructorDeclarationContext ctx) {
|
||||
StringBuilder constrDeclBuilder = new StringBuilder();
|
||||
getConstructorSignature(ctx,constrDeclBuilder);
|
||||
String currentModifiers = retrieveModifiers();
|
||||
|
||||
StringBuilder signatureBuilder = new StringBuilder();
|
||||
signatureBuilder.append(currentModifiers);
|
||||
signatureBuilder.append(": ");
|
||||
signatureBuilder.append(joinPackageNameWithClassName());
|
||||
signatureBuilder.append(".");
|
||||
signatureBuilder.append(constrDeclBuilder.toString());
|
||||
currentSignature = signatureBuilder.toString();
|
||||
|
||||
processLine(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitConstructorDeclaration(JavaParser.ConstructorDeclarationContext ctx) {
|
||||
currentSignature = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterClassDeclaration(JavaParser.ClassDeclarationContext ctx) {
|
||||
if (!className.equals("")) {
|
||||
return;
|
||||
}
|
||||
className = ctx.getChild(1).getText();
|
||||
String currentModifiers = retrieveModifiers();
|
||||
|
||||
StringBuilder signatureBuilder = new StringBuilder();
|
||||
signatureBuilder.append(currentModifiers);
|
||||
signatureBuilder.append(": ");
|
||||
signatureBuilder.append(joinPackageNameWithClassName());
|
||||
currentSignature = signatureBuilder.toString();
|
||||
|
||||
processLine(ctx);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void exitClassDeclaration(JavaParser.ClassDeclarationContext ctx) {
|
||||
currentSignature = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterStatement(JavaParser.StatementContext ctx) {
|
||||
processLine(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterFieldDeclaration(JavaParser.FieldDeclarationContext ctx) {
|
||||
String currentModifiers = retrieveModifiers();
|
||||
String fieldName = ctx.getChild(1).getChild(0).getChild(0).getText();
|
||||
|
||||
StringBuilder signatureBuilder = new StringBuilder();
|
||||
signatureBuilder.append(currentModifiers);
|
||||
signatureBuilder.append(": ");
|
||||
signatureBuilder.append(joinPackageNameWithClassName());
|
||||
signatureBuilder.append(".");
|
||||
signatureBuilder.append(fieldName);
|
||||
currentSignature = signatureBuilder.toString();
|
||||
|
||||
processLine(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitFieldDeclaration(JavaParser.FieldDeclarationContext ctx) {
|
||||
currentSignature = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterLocalVariableDeclaration(JavaParser.LocalVariableDeclarationContext ctx) {
|
||||
processLine(ctx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterCatchClause(JavaParser.CatchClauseContext ctx) {
|
||||
processLine(ctx);
|
||||
}
|
||||
|
||||
private void processLine(ParserRuleContext ctx) {
|
||||
int line = ctx.getStart().getLine();
|
||||
if (currentSignature != null) {
|
||||
Set<Integer> tempLines = lines.get(currentSignature);
|
||||
if (tempLines != null) {
|
||||
lines.remove(currentSignature);
|
||||
} else {
|
||||
tempLines = new HashSet<>();
|
||||
}
|
||||
tempLines.add(line);
|
||||
lines.put(currentSignature, tempLines);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a method signature recursively
|
||||
* @param method
|
||||
* @param builder
|
||||
*/
|
||||
private void getMethodSignature(ParseTree method, StringBuilder builder) {
|
||||
int start = (method.getClass().equals(JavaParser.MethodDeclarationContext.class)) ? 1 : 0;
|
||||
for (int i=start; i<method.getChildCount(); i++) {
|
||||
ParseTree node = method.getChild(i);
|
||||
if (node.getClass().equals(TerminalNodeImpl.class)) {
|
||||
builder.append(node.getText());
|
||||
}
|
||||
else if (!node.getClass().equals(JavaParser.MethodBodyContext.class) &&
|
||||
!node.getClass().equals(JavaParser.VariableDeclaratorIdContext.class)) {
|
||||
getMethodSignature(node, builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a constructor signature recursively
|
||||
* @param constructor
|
||||
* @param builder
|
||||
*/
|
||||
private void getConstructorSignature(ParseTree constructor, StringBuilder builder) {
|
||||
for (int i=0; i < constructor.getChildCount(); i++) {
|
||||
ParseTree node = constructor.getChild(i);
|
||||
if (node.getClass().equals(TerminalNodeImpl.class)) {
|
||||
builder.append(node.getText());
|
||||
}
|
||||
else if (!node.getClass().equals(JavaParser.ConstructorBodyContext.class) &&
|
||||
!node.getClass().equals(JavaParser.VariableDeclaratorIdContext.class)) {
|
||||
getConstructorSignature(node, builder);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the modifier keywords
|
||||
* @return
|
||||
*/
|
||||
private String retrieveModifiers() {
|
||||
StringBuilder currentModifier = new StringBuilder();
|
||||
while (modifiers.size() != 0) {
|
||||
ParserRuleContext modifier = modifiers.poll();
|
||||
if (!modifier.getText().startsWith("@")) {
|
||||
currentModifier.append(modifier.getText() + " ");
|
||||
}
|
||||
}
|
||||
return currentModifier.toString();
|
||||
}
|
||||
|
||||
|
||||
public Map<String, Set<Integer>> getSignaturesWithLines() {
|
||||
return this.lines;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
package it.unitn.molerat.repos.wrappers;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.*;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.diff.DiffEntry;
|
||||
import org.eclipse.jgit.diff.DiffFormatter;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectReader;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.eclipse.jgit.revwalk.RevTree;
|
||||
import org.eclipse.jgit.revwalk.RevWalk;
|
||||
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
|
||||
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
|
||||
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.treewalk.filter.PathSuffixFilter;
|
||||
import org.eclipse.jgit.lib.Ref;
|
||||
|
||||
public final class GitRepoWrapper extends RepoWrapper {
|
||||
|
||||
private final String repoRoot;
|
||||
private final Repository repo;
|
||||
private final Git git;
|
||||
|
||||
public GitRepoWrapper(String root) throws IOException {
|
||||
this.diffFilePrefix = "diff --git a";
|
||||
this.repoRoot = root;
|
||||
FileRepositoryBuilder builder = new FileRepositoryBuilder();
|
||||
builder.setGitDir(new File(this.repoRoot + "/.git"));
|
||||
this.repo = builder.build();
|
||||
this.git = new Git(this.repo);
|
||||
}
|
||||
|
||||
public Map<String, String> getTagsAndCommits() throws Exception {
|
||||
Map<String, String> tags = new HashMap<>();
|
||||
List<Ref> call = git.tagList().call();
|
||||
for (Ref tagref : call) {
|
||||
tags.put(tagref.getName(), tagref.getPeeledObjectId().getName());
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doDiff(String path, String leftRev, String rightRev) throws Exception {
|
||||
if (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
OutputStream out = new ByteArrayOutputStream();
|
||||
try { DiffFormatter df = new DiffFormatter(out);
|
||||
df.setRepository(this.git.getRepository());
|
||||
df.setDetectRenames(true);
|
||||
List<DiffEntry> entries = df.scan(getTreeIterator(leftRev), getTreeIterator(rightRev));
|
||||
df.close();
|
||||
df.format(entries);
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("[JGit error] " + e.getMessage());
|
||||
throw new Exception(e);
|
||||
}
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doDiff(String leftRev, String rightRev) throws Exception {
|
||||
return this.doDiff("", leftRev, rightRev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doCat(String path, String rev) throws Exception {
|
||||
if (path.startsWith("/")) {
|
||||
path = path.substring(1);
|
||||
}
|
||||
String output = "";
|
||||
final ObjectId id = this.repo.resolve(rev);
|
||||
ObjectReader reader = this.repo.newObjectReader();
|
||||
RevWalk walk = null;
|
||||
try {
|
||||
walk = new RevWalk(reader);
|
||||
RevCommit commit = walk.parseCommit(id);
|
||||
RevTree tree = commit.getTree();
|
||||
TreeWalk treewalk = TreeWalk.forPath(reader, path, tree);
|
||||
if (treewalk != null) {
|
||||
byte[] data = reader.open(treewalk.getObjectId(0)).getBytes();
|
||||
output = new String(data, "utf-8");
|
||||
}
|
||||
} finally {
|
||||
reader.close();
|
||||
if (walk != null) {
|
||||
walk.close();
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBasePath() {
|
||||
return this.repoRoot;
|
||||
}
|
||||
|
||||
private AbstractTreeIterator getTreeIterator(String name) throws IOException {
|
||||
final ObjectId id = this.repo.resolve(name);
|
||||
if (id == null) {
|
||||
throw new IllegalArgumentException(name);
|
||||
}
|
||||
final CanonicalTreeParser p = new CanonicalTreeParser();
|
||||
try (ObjectReader or = this.repo.newObjectReader();
|
||||
RevWalk rw = new RevWalk(this.repo)) {
|
||||
p.reset(or, rw.parseTree(id));
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: UNIMPLEMENTED
|
||||
@Override
|
||||
public void annotate(String path, String rev, Object callback) throws Exception {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<String> getRevisionNumbers(String topRev) throws Exception {
|
||||
Set<String> commits = new LinkedHashSet<>();
|
||||
for (RevCommit commit : git.log().add(this.repo.resolve(topRev + "~1")).call()) {
|
||||
commits.add(commit.getName());
|
||||
}
|
||||
return commits;
|
||||
}
|
||||
|
||||
// TODO: UNIMPLEMENTED
|
||||
@Override
|
||||
public Map<Integer, String> determineOriginatingRevision(String filePath, String revision, Map<Integer, String> lines) throws Exception {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
// TODO: UNIMPLEMENTED
|
||||
@Override
|
||||
protected String getReleaseTag(String release) throws Exception {
|
||||
/*
|
||||
Map<String, String> tags = this.getTagsAndCommits();
|
||||
for (String key : tags.keySet()) {
|
||||
String candidate = key.replace("refs/tags/", "");
|
||||
System.out.println("KEY: " + candidate);
|
||||
}
|
||||
*/
|
||||
return ("refs/tags/" + release);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReleaseCommit(String release) throws Exception {
|
||||
String tagName = getReleaseTag(release);
|
||||
String tagCommit = this.getTagsAndCommits().get(tagName);
|
||||
Iterator<RevCommit> iter = git.log().add(this.repo.resolve(tagCommit)).call().iterator();
|
||||
iter.next();
|
||||
return iter.next().getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getRevisionFiles(String rev, String filter) throws Exception {
|
||||
Set<String> files = new LinkedHashSet<>();
|
||||
RevWalk revWalk = null;
|
||||
TreeWalk treeWalk = null;
|
||||
try {
|
||||
ObjectId revId = this.repo.resolve(rev);
|
||||
revWalk = new RevWalk(this.repo);
|
||||
RevCommit commit = revWalk.parseCommit(revId);
|
||||
RevTree tree = commit.getTree();
|
||||
treeWalk = new TreeWalk(this.repo);
|
||||
treeWalk.addTree(tree);
|
||||
treeWalk.setRecursive(true);
|
||||
|
||||
treeWalk.setFilter(PathSuffixFilter.create(filter));
|
||||
while(treeWalk.next()) {
|
||||
files.add(treeWalk.getPathString());
|
||||
}
|
||||
} catch(Exception e) {
|
||||
throw new Exception("[JGit error] " + e.getMessage());
|
||||
} finally {
|
||||
if (revWalk != null){
|
||||
revWalk.close();
|
||||
}
|
||||
if (treeWalk != null){
|
||||
treeWalk.close();
|
||||
}
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllRepositoryTransactions() throws Exception {
|
||||
Iterable<RevCommit> logs = git.log().call();
|
||||
Set<String> commits = new LinkedHashSet<>();
|
||||
Iterator<RevCommit> it = logs.iterator();
|
||||
if (it.hasNext()) {
|
||||
String latestCommit = it.next().getName();
|
||||
commits.add(latestCommit);
|
||||
commits.addAll(this.getRevisionNumbers(latestCommit));
|
||||
}
|
||||
return commits;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
package it.unitn.molerat.repos.wrappers;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import it.unitn.molerat.evidence.Changes;
|
||||
|
||||
public abstract class RepoWrapper {
|
||||
|
||||
protected String diffFilePrefix;
|
||||
|
||||
protected final Pattern hunkRegexPattern = Pattern.compile("@@[ ]*\\-([0-9]+)[\\,0-9 ]+\\+([0-9]+)[\\,0-9 ]+@@");
|
||||
|
||||
protected final Pattern commentsPattern = Pattern.compile("(\\*|\\/\\*|\\*\\/|\\/\\/)(.*)");
|
||||
|
||||
public abstract String doDiff(String leftRev, String rightRev) throws Exception;
|
||||
|
||||
public abstract String doDiff(String path, String leftRev, String rightRev) throws Exception;
|
||||
|
||||
public abstract void annotate(String path, String rev, Object callback) throws Exception;
|
||||
|
||||
public abstract String doCat(String path, String rev) throws Exception;
|
||||
|
||||
public abstract String getBasePath();
|
||||
|
||||
public abstract Set<String> getRevisionFiles(String rev, String filter) throws Exception;
|
||||
|
||||
public abstract Set<String> getRevisionNumbers(String topRev) throws Exception;
|
||||
|
||||
public abstract Map<Integer, String> determineOriginatingRevision(final String filePath, final String revision, final Map<Integer, String> lines) throws Exception;
|
||||
|
||||
public Set<Changes> inferChangesFromDiff(String diffText, String leftRev, String rightRev) throws IOException {
|
||||
Set<Changes> relevantChanges = new LinkedHashSet<>();
|
||||
|
||||
Changes newRelevantChanges = null;
|
||||
int deletionRange = -1;
|
||||
int additionRange = -1;
|
||||
boolean additionRangeNotSet = true;
|
||||
boolean deletionRangeNotSet = true;
|
||||
|
||||
String[] diffLines = diffText.split(System.getProperty("line.separator"));
|
||||
//for (String line : diffLines) {
|
||||
for (int i=0; i<diffLines.length; i++) {
|
||||
String line = diffLines[i];
|
||||
if (line.startsWith(this.diffFilePrefix)) {
|
||||
line = line.replaceAll(this.diffFilePrefix, "");
|
||||
// do some additional filename filtering ----------
|
||||
StringBuilder filename = new StringBuilder();
|
||||
for (int j=0; j<line.length(); j++) {
|
||||
char c = line.charAt(j);
|
||||
if (String.valueOf(c).equals(" ")) {
|
||||
break;
|
||||
}
|
||||
filename.append(c);
|
||||
}
|
||||
//--------------------------------------------------
|
||||
// Here we check if a file was simply renamed...
|
||||
//--------------------------------------------------
|
||||
String renameTo = "";
|
||||
if (diffLines[i+1].startsWith("similarity index 100%")) {
|
||||
renameTo = diffLines[i+3].replace("rename to ", "");
|
||||
}
|
||||
//--------------------------------------------------
|
||||
if (!renameTo.equals("")) {
|
||||
newRelevantChanges = new Changes(filename.toString(), "/"+renameTo, leftRev, rightRev);
|
||||
}
|
||||
else {
|
||||
newRelevantChanges = new Changes(filename.toString(), leftRev, rightRev);
|
||||
}
|
||||
relevantChanges.add(newRelevantChanges);
|
||||
}
|
||||
else if (newRelevantChanges != null && line.startsWith("@@") && line.endsWith("@@")) {
|
||||
Matcher hunkMatcher = this.hunkRegexPattern.matcher(line);
|
||||
hunkMatcher.matches();
|
||||
deletionRange = Integer.parseInt(hunkMatcher.group(1));
|
||||
additionRange = Integer.parseInt(hunkMatcher.group(2));
|
||||
hunkMatcher.reset();
|
||||
}
|
||||
else if (newRelevantChanges != null) {
|
||||
if (line.startsWith("-") && !line.startsWith("---")) {
|
||||
line = line.substring(1).trim().replace("\t","");
|
||||
newRelevantChanges.putDeletedLine(deletionRange, line);
|
||||
if (deletionRangeNotSet) {
|
||||
deletionRangeNotSet = false;
|
||||
}
|
||||
deletionRange++;
|
||||
continue;
|
||||
}
|
||||
else if (line.startsWith("+") && !line.startsWith("+++")) {
|
||||
line = line.substring(1).trim().replace("\t","");
|
||||
newRelevantChanges.putAddedLine(additionRange, line);
|
||||
if (additionRangeNotSet) {
|
||||
additionRangeNotSet = false;
|
||||
}
|
||||
additionRange++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
deletionRange++;
|
||||
additionRange++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return relevantChanges;
|
||||
}
|
||||
|
||||
public int countNumberOfHunksInDiff(String diffText) {
|
||||
int numberOfHunks = 0;
|
||||
String[] diffLines = diffText.split(System.getProperty("line.separator"));
|
||||
for (String line : diffLines) {
|
||||
if (line.startsWith("@@") && line.endsWith("@@")) {
|
||||
numberOfHunks++;
|
||||
}
|
||||
}
|
||||
return numberOfHunks;
|
||||
}
|
||||
|
||||
|
||||
public void filterCommentsAndBlanks(Map<Integer, String> lines) {
|
||||
Iterator<Map.Entry<Integer,String>> it = lines.entrySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
String line = it.next().getValue();
|
||||
Matcher commentMatcher = this.commentsPattern.matcher(line.trim());
|
||||
if (line.trim().isEmpty() || commentMatcher.matches()) {
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Map<Integer, String> getLineMappings(final String fileContents) {
|
||||
Map<Integer, String> lineMappings = new TreeMap<Integer, String>();
|
||||
String[] lines = fileContents.split(System.getProperty("line.separator"));
|
||||
int lineNumber = 1;
|
||||
for (String line : lines) {
|
||||
line = line.trim().replace("\t","");
|
||||
lineMappings.put(lineNumber++, line);
|
||||
}
|
||||
return lineMappings;
|
||||
}
|
||||
|
||||
public int getNumberOfLoc(final String fileContents) {
|
||||
return this.getLineMappings(fileContents).size();
|
||||
}
|
||||
|
||||
public int getNumberOfLocFiltered(final String fileContents) {
|
||||
Map<Integer, String> locs = this.getLineMappings(fileContents);
|
||||
this.filterCommentsAndBlanks(locs);
|
||||
return locs.size();
|
||||
}
|
||||
|
||||
protected abstract String getReleaseTag(String release) throws Exception;
|
||||
public abstract String getReleaseCommit(String release) throws Exception;
|
||||
public abstract Set<String> getAllRepositoryTransactions() throws Exception;
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
package it.unitn.molerat.repos.wrappers;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import org.tmatesoft.svn.core.SVNException;
|
||||
import org.tmatesoft.svn.core.SVNLogEntry;
|
||||
import org.tmatesoft.svn.core.SVNURL;
|
||||
import org.tmatesoft.svn.core.io.SVNRepository;
|
||||
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
|
||||
import org.tmatesoft.svn.core.wc.SVNRevision;
|
||||
import org.tmatesoft.svn.core.wc2.ISvnObjectReceiver;
|
||||
import org.tmatesoft.svn.core.wc2.SvnAnnotate;
|
||||
import org.tmatesoft.svn.core.wc2.SvnAnnotateItem;
|
||||
import org.tmatesoft.svn.core.wc2.SvnCat;
|
||||
import org.tmatesoft.svn.core.wc2.SvnDiff;
|
||||
import org.tmatesoft.svn.core.wc2.SvnLog;
|
||||
import org.tmatesoft.svn.core.wc2.SvnOperationFactory;
|
||||
import org.tmatesoft.svn.core.wc2.SvnRevisionRange;
|
||||
import org.tmatesoft.svn.core.wc2.SvnTarget;
|
||||
|
||||
public final class SvnRepoWrapper extends RepoWrapper {
|
||||
|
||||
private final SVNURL url;
|
||||
protected SVNRepository repo = null;
|
||||
protected final SvnOperationFactory opFactory = new SvnOperationFactory();
|
||||
|
||||
public SvnRepoWrapper(String url) throws SVNException {
|
||||
this.diffFilePrefix = "Index: ";
|
||||
this.url = SVNURL.parseURIEncoded(url);
|
||||
this.repo = SVNRepositoryFactory.create(this.url);
|
||||
}
|
||||
|
||||
protected String doDiff(SvnTarget leftRev, SvnTarget rightRev) throws SVNException {
|
||||
final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
SvnDiff diff = opFactory.createDiff();
|
||||
diff.setOutput(output);
|
||||
diff.setSources(leftRev, rightRev);
|
||||
diff.run();
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
public Set<String> getRevisionNumbers(String topRev) throws SVNException {
|
||||
Set<String> revNumbers = new LinkedHashSet<>();
|
||||
LinkedList<SVNLogEntry> logEntries = new LinkedList<>();
|
||||
SvnLog log = opFactory.createLog();
|
||||
SvnTarget target = SvnTarget.fromURL(this.url);
|
||||
log.addRange(SvnRevisionRange.create(SVNRevision.create(0), SVNRevision.create(Long.parseLong(topRev))));
|
||||
log.setSingleTarget(target);
|
||||
log.run(logEntries);
|
||||
Iterator<SVNLogEntry> it = logEntries.descendingIterator();
|
||||
if (it.hasNext()) {
|
||||
it.next(); // discard the topRev
|
||||
}
|
||||
while (it.hasNext()) {
|
||||
SVNLogEntry entry = it.next();
|
||||
revNumbers.add(String.valueOf(entry.getRevision()));
|
||||
}
|
||||
return revNumbers;
|
||||
}
|
||||
|
||||
|
||||
protected void annotate(final SvnTarget target, ISvnObjectReceiver<SvnAnnotateItem> callback) throws SVNException {
|
||||
SvnAnnotate annotate = opFactory.createAnnotate();
|
||||
annotate.setSingleTarget(target);
|
||||
final SVNRevision startRev = SVNRevision.create(1);
|
||||
final SVNRevision endRev = target.getPegRevision();
|
||||
annotate.setStartRevision(startRev);
|
||||
annotate.setEndRevision(endRev);
|
||||
annotate.setReceiver(callback);
|
||||
annotate.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void annotate(String path, String rev, Object callback) throws Exception {
|
||||
long revLong = Long.parseLong(rev);
|
||||
SvnTarget target = SvnTarget.fromURL(SVNURL.parseURIEncoded(this.getBasePath() + path), SVNRevision.create(revLong));
|
||||
this.annotate(target, ((ISvnObjectReceiver<SvnAnnotateItem>)callback));
|
||||
}
|
||||
|
||||
protected String doCat(final SvnTarget target) throws SVNException {
|
||||
final ByteArrayOutputStream output = new ByteArrayOutputStream();
|
||||
SvnCat cat = this.opFactory.createCat();
|
||||
cat.addTarget(target);
|
||||
cat.setOutput(output);
|
||||
cat.run();
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doDiff(String leftRev, String rightRev) throws SVNException {
|
||||
return this.doDiff("", leftRev, rightRev);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doDiff(String path, String leftRev, String rightRev) throws SVNException {
|
||||
long leftLong = Long.parseLong(leftRev);
|
||||
long rightLong = Long.parseLong(rightRev);
|
||||
SvnTarget left = SvnTarget.fromURL(SVNURL.parseURIEncoded(this.url + path), SVNRevision.create(leftLong));
|
||||
SvnTarget right = SvnTarget.fromURL(SVNURL.parseURIEncoded(this.url + path), SVNRevision.create(rightLong));
|
||||
return this.doDiff(left, right);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getBasePath() {
|
||||
return this.url.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String doCat(String path, String rev) throws SVNException {
|
||||
long revLong = Long.parseLong(rev);
|
||||
SvnTarget target = SvnTarget.fromURL(SVNURL.parseURIEncoded(this.url + path), SVNRevision.create(revLong));
|
||||
return this.doCat(target);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
public String getTopmostRevision(String url) throws SVNException {
|
||||
SvnLog log = opFactory.createLog();
|
||||
SvnTarget target = SvnTarget.fromURL(SVNURL.parseURIEncoded(url));
|
||||
log.addRange(SvnRevisionRange.create(null, null));
|
||||
log.setSingleTarget(target);
|
||||
SVNLogEntry entry = log.run();
|
||||
return String.valueOf(entry.getRevision());
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
||||
/*----------------------------------------------------------------------------------------------------
|
||||
* example found at: http://blog.gmane.org/gmane.comp.version-control.subversion.javasvn.user/month=20131101
|
||||
----------------------------------------------------------------------------------------------------*/
|
||||
@Override
|
||||
public Map<Integer, String> determineOriginatingRevision(final String filePath,
|
||||
final String revision, final Map<Integer, String> lines) throws Exception {
|
||||
final Map<Integer, String> originating = new TreeMap<Integer, String>();
|
||||
final long startRev = 1;
|
||||
final long endRev = Long.parseLong(revision);
|
||||
this.annotate(filePath, String.valueOf(endRev), new ISvnObjectReceiver<SvnAnnotateItem>() {
|
||||
@Override
|
||||
public void receive(SvnTarget target, SvnAnnotateItem itm) throws SVNException {
|
||||
if (itm.isLine()) {
|
||||
final long revision = itm.getRevision();
|
||||
final int lineNumber = itm.getLineNumber() + 1;
|
||||
if (startRev < revision && revision <= endRev) {
|
||||
if (lines.containsKey(lineNumber)) {
|
||||
originating.put(lineNumber, String.valueOf(revision));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return originating;
|
||||
}
|
||||
|
||||
// TODO: UNIMPLEMENTED
|
||||
@Override
|
||||
protected String getReleaseTag(String release) throws Exception {
|
||||
return "";
|
||||
}
|
||||
|
||||
// TODO: UNIMPLEMENTED
|
||||
@Override
|
||||
public String getReleaseCommit(String release) throws Exception {
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// TODO: UNIMPLEMENTED
|
||||
@Override
|
||||
public Set<String> getRevisionFiles(String rev, String filter) throws Exception {
|
||||
return new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
// TODO: UNIMPLEMENTED
|
||||
@Override
|
||||
public Set<String> getAllRepositoryTransactions() throws Exception {
|
||||
return new LinkedHashSet<>();
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>it.unitn</groupId>
|
||||
<artifactId>foss-vuln-tracker</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<properties>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
</properties>
|
||||
<modules>
|
||||
<module>molerat</module>
|
||||
<module>repoman</module>
|
||||
</modules>
|
||||
</project>
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<!-- parent project -->
|
||||
<parent>
|
||||
<groupId>it.unitn</groupId>
|
||||
<artifactId>foss-vuln-tracker</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>it.unitn.repoman</groupId>
|
||||
<artifactId>repoman</artifactId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<!-- declare dependencies -->
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
<version>4.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- build plugins -->
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-dependency-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>copy-dependencies</id>
|
||||
<phase>prepare-package</phase>
|
||||
<goals>
|
||||
<goal>copy-dependencies</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<outputDirectory>
|
||||
${project.build.directory}/libs
|
||||
</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<configuration>
|
||||
<archive>
|
||||
<manifest>
|
||||
<addClasspath>true</addClasspath>
|
||||
<classpathPrefix>libs/</classpathPrefix>
|
||||
<mainClass>it.unitn.repoman.cmd.Main</mainClass>
|
||||
</manifest>
|
||||
</archive>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
|
@ -0,0 +1,87 @@
|
|||
package it.unitn.repoman.cmd;
|
||||
|
||||
import it.unitn.repoman.core.lang.LanguageFactory;
|
||||
import it.unitn.repoman.core.slicers.LightweightSlice;
|
||||
import it.unitn.repoman.core.utils.printers.ConsolePrinterListener;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
import org.apache.commons.cli.*;
|
||||
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Options opts = new Options();
|
||||
|
||||
Option fileOpt = Option.builder("f")
|
||||
.argName("e.g, ./Code.java")
|
||||
.longOpt("file")
|
||||
.required(true)
|
||||
.hasArg()
|
||||
.desc(".java file")
|
||||
.build();
|
||||
opts.addOption(fileOpt);
|
||||
|
||||
Option lineNumbersOpt = Option.builder("l")
|
||||
.argName("e.g, '1 2 3 4 ...'")
|
||||
.longOpt("line-numbers")
|
||||
.desc("Seed lines (line numbers separated with spaces)")
|
||||
.required(true)
|
||||
.hasArgs()
|
||||
.build();
|
||||
opts.addOption(lineNumbersOpt);
|
||||
|
||||
CommandLineParser cmdParser = new DefaultParser();
|
||||
HelpFormatter helpFormatter = new HelpFormatter();
|
||||
CommandLine cmd;
|
||||
try {
|
||||
cmd = cmdParser.parse(opts, args);
|
||||
String file = cmd.getOptionValue("f");
|
||||
|
||||
LanguageFactory.init("Java", readFile(file));
|
||||
String[] argLines = cmd.getOptionValues("l");
|
||||
Set<Integer> lines = new LinkedHashSet<>();
|
||||
for (int i=0; i<argLines.length; i++) {
|
||||
lines.add(Integer.parseInt(argLines[i]));
|
||||
}
|
||||
Parser parser = LanguageFactory.getParser();
|
||||
LightweightSlice slice = new LightweightSlice(LanguageFactory.getRoot(), lines);
|
||||
ParseTreeListener printer = new ConsolePrinterListener(parser, slice);
|
||||
System.out.println(printer);
|
||||
}
|
||||
catch (ParseException e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
helpFormatter.printHelp("utility-name", opts);
|
||||
}
|
||||
catch (Exception e) {
|
||||
System.out.println("ERROR: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private static String readFile(String filename) throws IOException {
|
||||
File javaFile = new File(filename);
|
||||
if (!javaFile.exists())
|
||||
throw new FileNotFoundException(filename);
|
||||
|
||||
BufferedReader in = new BufferedReader(new FileReader(javaFile));
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
String line = null;
|
||||
try {
|
||||
while ( (line = in.readLine()) != null) {
|
||||
buffer.append(line);
|
||||
buffer.append('\n');
|
||||
}
|
||||
}
|
||||
finally {
|
||||
in.close();
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package it.unitn.repoman.core.exceptions;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class InvalidLineException extends Exception {
|
||||
|
||||
public InvalidLineException(int line) {
|
||||
super("ERROR! Invalid line number --> " + line);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
package it.unitn.repoman.core.lang;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
import it.unitn.repoman.core.lang.wrappers.c.CWrapper;
|
||||
import it.unitn.repoman.core.lang.wrappers.java.JavaWrapper;
|
||||
import it.unitn.repoman.core.lang.wrappers.generic.Wrapper;
|
||||
import it.unitn.repoman.core.lang.parsers.c.CLexer;
|
||||
import it.unitn.repoman.core.lang.parsers.c.CParser;
|
||||
import it.unitn.repoman.core.lang.parsers.java.JavaLexer;
|
||||
import it.unitn.repoman.core.lang.parsers.java.JavaParser;
|
||||
|
||||
public class LanguageFactory {
|
||||
|
||||
private static Wrapper wrapper;
|
||||
private static Parser parser;
|
||||
private static ParserRuleContext root;
|
||||
|
||||
private LanguageFactory() {}
|
||||
|
||||
public static void init(String language, String contents) {
|
||||
try {
|
||||
if (language.toLowerCase().equals("java")) {
|
||||
wrapper = new JavaWrapper();
|
||||
JavaLexer lexer = new JavaLexer(CharStreams.fromString(contents));
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
parser = new JavaParser(tokens);
|
||||
root = ((JavaParser)parser).compilationUnit();
|
||||
}
|
||||
else if (language.toLowerCase().equals("c")) {
|
||||
wrapper = new CWrapper();
|
||||
CLexer lexer = new CLexer(CharStreams.fromString(contents));
|
||||
CommonTokenStream tokens = new CommonTokenStream(lexer);
|
||||
parser = new CParser(tokens);
|
||||
root = ((CParser)parser).compilationUnit();
|
||||
}
|
||||
/*
|
||||
else if (language.toLowerCase().equals("javascript")) {
|
||||
//TODO
|
||||
}
|
||||
*/
|
||||
}
|
||||
catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Wrapper getWrapper() {
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
public static Parser getParser() {
|
||||
return parser;
|
||||
}
|
||||
|
||||
public static ParserRuleContext getRoot() {
|
||||
return root;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
Enum=25
|
||||
AndAssign=97
|
||||
Or=79
|
||||
Break=16
|
||||
LeftShift=69
|
||||
GreaterEqual=68
|
||||
Bool=52
|
||||
ThreadLocal=58
|
||||
LeftBracket=61
|
||||
RightBrace=64
|
||||
Equal=100
|
||||
Directives=117
|
||||
Restrict=35
|
||||
Sizeof=39
|
||||
StarAssign=90
|
||||
Arrow=102
|
||||
NotEqual=101
|
||||
LessEqual=66
|
||||
Dot=103
|
||||
RightParen=60
|
||||
XorAssign=98
|
||||
Float=27
|
||||
Switch=42
|
||||
Typedef=43
|
||||
StringLiteral=107
|
||||
If=30
|
||||
Minus=73
|
||||
MinusAssign=94
|
||||
LeftParen=59
|
||||
Newline=114
|
||||
Union=44
|
||||
Case=17
|
||||
Extern=26
|
||||
Complex=53
|
||||
RightShiftAssign=96
|
||||
Comma=88
|
||||
Star=75
|
||||
Char=18
|
||||
ComplexDefine=108
|
||||
T__3=11
|
||||
T__2=12
|
||||
T__1=13
|
||||
Question=85
|
||||
T__0=14
|
||||
OrOr=81
|
||||
LineAfterPreprocessing=110
|
||||
Inline=31
|
||||
Default=21
|
||||
Alignas=49
|
||||
Div=76
|
||||
RightBracket=62
|
||||
Register=34
|
||||
Else=24
|
||||
Assign=89
|
||||
AndAnd=80
|
||||
LineDirective=111
|
||||
LineComment=116
|
||||
RightShift=70
|
||||
LeftShiftAssign=95
|
||||
Identifier=105
|
||||
T__11=3
|
||||
T__12=2
|
||||
T__13=1
|
||||
Void=46
|
||||
Plus=71
|
||||
AsmBlock=109
|
||||
StaticAssert=57
|
||||
Less=65
|
||||
Short=37
|
||||
T__10=4
|
||||
BlockComment=115
|
||||
T__9=5
|
||||
Goto=29
|
||||
T__8=6
|
||||
T__7=7
|
||||
T__6=8
|
||||
T__5=9
|
||||
Signed=38
|
||||
T__4=10
|
||||
Const=19
|
||||
Imaginary=55
|
||||
For=28
|
||||
Semi=87
|
||||
OrAssign=99
|
||||
Do=22
|
||||
Double=23
|
||||
Not=83
|
||||
And=78
|
||||
Long=33
|
||||
Static=40
|
||||
Caret=82
|
||||
Alignof=50
|
||||
Generic=54
|
||||
Constant=106
|
||||
Atomic=51
|
||||
Continue=20
|
||||
Int=32
|
||||
MinusMinus=74
|
||||
Whitespace=113
|
||||
Struct=41
|
||||
Auto=15
|
||||
PlusPlus=72
|
||||
PlusAssign=93
|
||||
Colon=86
|
||||
DivAssign=91
|
||||
LeftBrace=63
|
||||
Return=36
|
||||
Mod=77
|
||||
Ellipsis=104
|
||||
Tilde=84
|
||||
PragmaDirective=112
|
||||
While=48
|
||||
Noreturn=56
|
||||
Volatile=47
|
||||
ModAssign=92
|
||||
Unsigned=45
|
||||
Greater=67
|
||||
'-'=73
|
||||
'typedef'=43
|
||||
'else'=24
|
||||
'_Static_assert'=57
|
||||
'%'=77
|
||||
'__builtin_offsetof'=14
|
||||
'>'=67
|
||||
'--'=74
|
||||
'=='=100
|
||||
'_Complex'=53
|
||||
'...'=104
|
||||
'case'=17
|
||||
'->'=102
|
||||
'.'=103
|
||||
'_Thread_local'=58
|
||||
'__m128'=13
|
||||
'&'=78
|
||||
'__inline__'=12
|
||||
'double'=23
|
||||
'break'=16
|
||||
'short'=37
|
||||
'<='=66
|
||||
'enum'=25
|
||||
'?'=85
|
||||
'__attribute__'=11
|
||||
'if'=30
|
||||
'_Generic'=54
|
||||
'goto'=29
|
||||
'<<'=69
|
||||
'inline'=31
|
||||
'||'=81
|
||||
'return'=36
|
||||
'__m128i'=10
|
||||
'_Imaginary'=55
|
||||
'unsigned'=45
|
||||
'continue'=20
|
||||
'/'=76
|
||||
'_Bool'=52
|
||||
'__m128d'=9
|
||||
'signed'=38
|
||||
'__asm'=8
|
||||
'register'=34
|
||||
'sizeof'=39
|
||||
'static'=40
|
||||
'__typeof__'=7
|
||||
'++'=72
|
||||
'__builtin_va_arg'=6
|
||||
'const'=19
|
||||
'volatile'=47
|
||||
'/='=91
|
||||
'__declspec'=5
|
||||
'do'=22
|
||||
'('=59
|
||||
'|='=99
|
||||
'for'=28
|
||||
'void'=46
|
||||
'{'=63
|
||||
'float'=27
|
||||
'+='=93
|
||||
')'=60
|
||||
'__asm__'=4
|
||||
'auto'=15
|
||||
'!'=83
|
||||
'|'=79
|
||||
'['=61
|
||||
':'=86
|
||||
'_Atomic'=51
|
||||
'*'=75
|
||||
'switch'=42
|
||||
'_Alignas'=49
|
||||
'_Alignof'=50
|
||||
'__stdcall'=3
|
||||
'}'=64
|
||||
';'=87
|
||||
'>>='=96
|
||||
'&='=97
|
||||
'*='=90
|
||||
'struct'=41
|
||||
'+'=71
|
||||
'~'=84
|
||||
']'=62
|
||||
'<'=65
|
||||
'_Noreturn'=56
|
||||
'>='=68
|
||||
'long'=33
|
||||
','=88
|
||||
'-='=94
|
||||
'union'=44
|
||||
'int'=32
|
||||
'__volatile__'=2
|
||||
'^'=82
|
||||
'<<='=95
|
||||
'='=89
|
||||
'restrict'=35
|
||||
'>>'=70
|
||||
'&&'=80
|
||||
'^='=98
|
||||
'while'=48
|
||||
'!='=101
|
||||
'__extension__'=1
|
||||
'char'=18
|
||||
'%='=92
|
||||
'extern'=26
|
||||
'default'=21
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,618 @@
|
|||
// Generated from C.g4 by ANTLR 4.4
|
||||
package it.unitn.repoman.core.lang.parsers.c;
|
||||
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class CLexer extends Lexer {
|
||||
static { RuntimeMetaData.checkVersion("4.4", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
T__13=1, T__12=2, T__11=3, T__10=4, T__9=5, T__8=6, T__7=7, T__6=8, T__5=9,
|
||||
T__4=10, T__3=11, T__2=12, T__1=13, T__0=14, Auto=15, Break=16, Case=17,
|
||||
Char=18, Const=19, Continue=20, Default=21, Do=22, Double=23, Else=24,
|
||||
Enum=25, Extern=26, Float=27, For=28, Goto=29, If=30, Inline=31, Int=32,
|
||||
Long=33, Register=34, Restrict=35, Return=36, Short=37, Signed=38, Sizeof=39,
|
||||
Static=40, Struct=41, Switch=42, Typedef=43, Union=44, Unsigned=45, Void=46,
|
||||
Volatile=47, While=48, Alignas=49, Alignof=50, Atomic=51, Bool=52, Complex=53,
|
||||
Generic=54, Imaginary=55, Noreturn=56, StaticAssert=57, ThreadLocal=58,
|
||||
LeftParen=59, RightParen=60, LeftBracket=61, RightBracket=62, LeftBrace=63,
|
||||
RightBrace=64, Less=65, LessEqual=66, Greater=67, GreaterEqual=68, LeftShift=69,
|
||||
RightShift=70, Plus=71, PlusPlus=72, Minus=73, MinusMinus=74, Star=75,
|
||||
Div=76, Mod=77, And=78, Or=79, AndAnd=80, OrOr=81, Caret=82, Not=83, Tilde=84,
|
||||
Question=85, Colon=86, Semi=87, Comma=88, Assign=89, StarAssign=90, DivAssign=91,
|
||||
ModAssign=92, PlusAssign=93, MinusAssign=94, LeftShiftAssign=95, RightShiftAssign=96,
|
||||
AndAssign=97, XorAssign=98, OrAssign=99, Equal=100, NotEqual=101, Arrow=102,
|
||||
Dot=103, Ellipsis=104, Identifier=105, Constant=106, StringLiteral=107,
|
||||
ComplexDefine=108, AsmBlock=109, LineAfterPreprocessing=110, LineDirective=111,
|
||||
PragmaDirective=112, Whitespace=113, Newline=114, BlockComment=115, LineComment=116,
|
||||
Directives=117;
|
||||
public static String[] modeNames = {
|
||||
"DEFAULT_MODE"
|
||||
};
|
||||
|
||||
public static final String[] tokenNames = {
|
||||
"'\\u0000'", "'\\u0001'", "'\\u0002'", "'\\u0003'", "'\\u0004'", "'\\u0005'",
|
||||
"'\\u0006'", "'\\u0007'", "'\b'", "'\t'", "'\n'", "'\\u000B'", "'\f'",
|
||||
"'\r'", "'\\u000E'", "'\\u000F'", "'\\u0010'", "'\\u0011'", "'\\u0012'",
|
||||
"'\\u0013'", "'\\u0014'", "'\\u0015'", "'\\u0016'", "'\\u0017'", "'\\u0018'",
|
||||
"'\\u0019'", "'\\u001A'", "'\\u001B'", "'\\u001C'", "'\\u001D'", "'\\u001E'",
|
||||
"'\\u001F'", "' '", "'!'", "'\"'", "'#'", "'$'", "'%'", "'&'", "'''",
|
||||
"'('", "')'", "'*'", "'+'", "','", "'-'", "'.'", "'/'", "'0'", "'1'",
|
||||
"'2'", "'3'", "'4'", "'5'", "'6'", "'7'", "'8'", "'9'", "':'", "';'",
|
||||
"'<'", "'='", "'>'", "'?'", "'@'", "'A'", "'B'", "'C'", "'D'", "'E'",
|
||||
"'F'", "'G'", "'H'", "'I'", "'J'", "'K'", "'L'", "'M'", "'N'", "'O'",
|
||||
"'P'", "'Q'", "'R'", "'S'", "'T'", "'U'", "'V'", "'W'", "'X'", "'Y'",
|
||||
"'Z'", "'['", "'\\'", "']'", "'^'", "'_'", "'`'", "'a'", "'b'", "'c'",
|
||||
"'d'", "'e'", "'f'", "'g'", "'h'", "'i'", "'j'", "'k'", "'l'", "'m'",
|
||||
"'n'", "'o'", "'p'", "'q'", "'r'", "'s'", "'t'", "'u'"
|
||||
};
|
||||
public static final String[] ruleNames = {
|
||||
"T__13", "T__12", "T__11", "T__10", "T__9", "T__8", "T__7", "T__6", "T__5",
|
||||
"T__4", "T__3", "T__2", "T__1", "T__0", "Auto", "Break", "Case", "Char",
|
||||
"Const", "Continue", "Default", "Do", "Double", "Else", "Enum", "Extern",
|
||||
"Float", "For", "Goto", "If", "Inline", "Int", "Long", "Register", "Restrict",
|
||||
"Return", "Short", "Signed", "Sizeof", "Static", "Struct", "Switch", "Typedef",
|
||||
"Union", "Unsigned", "Void", "Volatile", "While", "Alignas", "Alignof",
|
||||
"Atomic", "Bool", "Complex", "Generic", "Imaginary", "Noreturn", "StaticAssert",
|
||||
"ThreadLocal", "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", "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", "EncodingPrefix", "SCharSequence",
|
||||
"SChar", "ComplexDefine", "AsmBlock", "LineAfterPreprocessing", "LineDirective",
|
||||
"PragmaDirective", "Whitespace", "Newline", "BlockComment", "LineComment",
|
||||
"Directives"
|
||||
};
|
||||
|
||||
|
||||
public CLexer(CharStream input) {
|
||||
super(input);
|
||||
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "C.g4"; }
|
||||
|
||||
@Override
|
||||
public String[] getTokenNames() { return tokenNames; }
|
||||
|
||||
@Override
|
||||
public String[] getRuleNames() { return ruleNames; }
|
||||
|
||||
@Override
|
||||
public String getSerializedATN() { return _serializedATN; }
|
||||
|
||||
@Override
|
||||
public String[] getModeNames() { return modeNames; }
|
||||
|
||||
@Override
|
||||
public ATN getATN() { return _ATN; }
|
||||
|
||||
public static final String _serializedATN =
|
||||
"\3\u0430\ud6d1\u8206\uad2d\u4417\uaef1\u8d80\uaadd\2w\u0543\b\1\4\2\t"+
|
||||
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
|
||||
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
|
||||
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
|
||||
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
|
||||
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
|
||||
",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+
|
||||
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
|
||||
"\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+
|
||||
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
|
||||
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+
|
||||
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k\t"+
|
||||
"k\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv\4"+
|
||||
"w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t\u0080"+
|
||||
"\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084\4\u0085"+
|
||||
"\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089\t\u0089"+
|
||||
"\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d\4\u008e"+
|
||||
"\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092\t\u0092"+
|
||||
"\4\u0093\t\u0093\4\u0094\t\u0094\4\u0095\t\u0095\4\u0096\t\u0096\4\u0097"+
|
||||
"\t\u0097\4\u0098\t\u0098\4\u0099\t\u0099\4\u009a\t\u009a\4\u009b\t\u009b"+
|
||||
"\4\u009c\t\u009c\4\u009d\t\u009d\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3"+
|
||||
"\2\3\2\3\2\3\2\3\2\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3\3"+
|
||||
"\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\5\3\5\3\5\3\5\3\5\3"+
|
||||
"\5\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7"+
|
||||
"\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\b\3"+
|
||||
"\b\3\b\3\b\3\b\3\b\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\n"+
|
||||
"\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3"+
|
||||
"\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\r"+
|
||||
"\3\r\3\16\3\16\3\16\3\16\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17"+
|
||||
"\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20"+
|
||||
"\3\20\3\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22"+
|
||||
"\3\22\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3\25\3\25"+
|
||||
"\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26\3\26\3\26"+
|
||||
"\3\26\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31"+
|
||||
"\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\33\3\33\3\33"+
|
||||
"\3\34\3\34\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36"+
|
||||
"\3\36\3\37\3\37\3\37\3 \3 \3 \3 \3 \3 \3 \3!\3!\3!\3!\3\"\3\"\3\"\3\""+
|
||||
"\3\"\3#\3#\3#\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3$\3$\3$\3%\3%\3%\3"+
|
||||
"%\3%\3%\3%\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\3(\3"+
|
||||
"(\3(\3(\3)\3)\3)\3)\3)\3)\3)\3*\3*\3*\3*\3*\3*\3*\3+\3+\3+\3+\3+\3+\3"+
|
||||
"+\3,\3,\3,\3,\3,\3,\3,\3,\3-\3-\3-\3-\3-\3-\3.\3.\3.\3.\3.\3.\3.\3.\3"+
|
||||
".\3/\3/\3/\3/\3/\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\60\3\61\3\61"+
|
||||
"\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\63"+
|
||||
"\3\63\3\63\3\63\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\3\64\3\64"+
|
||||
"\3\64\3\64\3\65\3\65\3\65\3\65\3\65\3\65\3\66\3\66\3\66\3\66\3\66\3\66"+
|
||||
"\3\66\3\66\3\66\3\67\3\67\3\67\3\67\3\67\3\67\3\67\3\67\3\67\38\38\38"+
|
||||
"\38\38\38\38\38\38\38\38\39\39\39\39\39\39\39\39\39\39\3:\3:\3:\3:\3:"+
|
||||
"\3:\3:\3:\3:\3:\3:\3:\3:\3:\3:\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;\3;"+
|
||||
"\3;\3<\3<\3=\3=\3>\3>\3?\3?\3@\3@\3A\3A\3B\3B\3C\3C\3C\3D\3D\3E\3E\3E"+
|
||||
"\3F\3F\3F\3G\3G\3G\3H\3H\3I\3I\3I\3J\3J\3K\3K\3K\3L\3L\3M\3M\3N\3N\3O"+
|
||||
"\3O\3P\3P\3Q\3Q\3Q\3R\3R\3R\3S\3S\3T\3T\3U\3U\3V\3V\3W\3W\3X\3X\3Y\3Y"+
|
||||
"\3Z\3Z\3[\3[\3[\3\\\3\\\3\\\3]\3]\3]\3^\3^\3^\3_\3_\3_\3`\3`\3`\3`\3a"+
|
||||
"\3a\3a\3a\3b\3b\3b\3c\3c\3c\3d\3d\3d\3e\3e\3e\3f\3f\3f\3g\3g\3g\3h\3h"+
|
||||
"\3i\3i\3i\3i\3j\3j\3j\7j\u038b\nj\fj\16j\u038e\13j\3k\3k\5k\u0392\nk\3"+
|
||||
"l\3l\3m\3m\3n\3n\3n\3n\3n\3n\3n\3n\3n\3n\5n\u03a2\nn\3o\3o\3o\3o\3o\3"+
|
||||
"p\3p\3p\5p\u03ac\np\3q\3q\5q\u03b0\nq\3q\3q\5q\u03b4\nq\3q\3q\5q\u03b8"+
|
||||
"\nq\3q\5q\u03bb\nq\3r\3r\3r\6r\u03c0\nr\rr\16r\u03c1\3s\3s\7s\u03c6\n"+
|
||||
"s\fs\16s\u03c9\13s\3t\3t\7t\u03cd\nt\ft\16t\u03d0\13t\3u\3u\6u\u03d4\n"+
|
||||
"u\ru\16u\u03d5\3v\3v\3v\3w\3w\3x\3x\3y\3y\3z\3z\5z\u03e3\nz\3z\3z\3z\3"+
|
||||
"z\3z\5z\u03ea\nz\3z\3z\5z\u03ee\nz\5z\u03f0\nz\3{\3{\3|\3|\3}\3}\3}\3"+
|
||||
"}\5}\u03fa\n}\3~\3~\5~\u03fe\n~\3\177\3\177\5\177\u0402\n\177\3\177\5"+
|
||||
"\177\u0405\n\177\3\177\3\177\3\177\5\177\u040a\n\177\5\177\u040c\n\177"+
|
||||
"\3\u0080\3\u0080\3\u0080\3\u0080\5\u0080\u0412\n\u0080\3\u0080\3\u0080"+
|
||||
"\3\u0080\3\u0080\5\u0080\u0418\n\u0080\5\u0080\u041a\n\u0080\3\u0081\5"+
|
||||
"\u0081\u041d\n\u0081\3\u0081\3\u0081\3\u0081\3\u0081\3\u0081\5\u0081\u0424"+
|
||||
"\n\u0081\3\u0082\3\u0082\5\u0082\u0428\n\u0082\3\u0082\3\u0082\3\u0082"+
|
||||
"\5\u0082\u042d\n\u0082\3\u0082\5\u0082\u0430\n\u0082\3\u0083\3\u0083\3"+
|
||||
"\u0084\6\u0084\u0435\n\u0084\r\u0084\16\u0084\u0436\3\u0085\5\u0085\u043a"+
|
||||
"\n\u0085\3\u0085\3\u0085\3\u0085\3\u0085\3\u0085\5\u0085\u0441\n\u0085"+
|
||||
"\3\u0086\3\u0086\5\u0086\u0445\n\u0086\3\u0086\3\u0086\3\u0086\5\u0086"+
|
||||
"\u044a\n\u0086\3\u0086\5\u0086\u044d\n\u0086\3\u0087\6\u0087\u0450\n\u0087"+
|
||||
"\r\u0087\16\u0087\u0451\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089\3\u0089"+
|
||||
"\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089"+
|
||||
"\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089\3\u0089"+
|
||||
"\5\u0089\u046c\n\u0089\3\u008a\6\u008a\u046f\n\u008a\r\u008a\16\u008a"+
|
||||
"\u0470\3\u008b\3\u008b\5\u008b\u0475\n\u008b\3\u008c\3\u008c\3\u008c\3"+
|
||||
"\u008c\5\u008c\u047b\n\u008c\3\u008d\3\u008d\3\u008d\3\u008e\3\u008e\3"+
|
||||
"\u008e\3\u008e\3\u008e\3\u008e\3\u008e\3\u008e\3\u008e\3\u008e\3\u008e"+
|
||||
"\5\u008e\u048b\n\u008e\3\u008f\3\u008f\3\u008f\3\u008f\6\u008f\u0491\n"+
|
||||
"\u008f\r\u008f\16\u008f\u0492\3\u0090\5\u0090\u0496\n\u0090\3\u0090\3"+
|
||||
"\u0090\5\u0090\u049a\n\u0090\3\u0090\3\u0090\3\u0091\3\u0091\3\u0091\5"+
|
||||
"\u0091\u04a1\n\u0091\3\u0092\6\u0092\u04a4\n\u0092\r\u0092\16\u0092\u04a5"+
|
||||
"\3\u0093\3\u0093\3\u0093\3\u0093\3\u0093\3\u0093\3\u0093\5\u0093\u04af"+
|
||||
"\n\u0093\3\u0094\3\u0094\5\u0094\u04b3\n\u0094\3\u0094\3\u0094\3\u0094"+
|
||||
"\3\u0094\3\u0094\3\u0094\3\u0094\3\u0094\7\u0094\u04bd\n\u0094\f\u0094"+
|
||||
"\16\u0094\u04c0\13\u0094\3\u0094\3\u0094\3\u0095\3\u0095\3\u0095\3\u0095"+
|
||||
"\3\u0095\7\u0095\u04c9\n\u0095\f\u0095\16\u0095\u04cc\13\u0095\3\u0095"+
|
||||
"\3\u0095\7\u0095\u04d0\n\u0095\f\u0095\16\u0095\u04d3\13\u0095\3\u0095"+
|
||||
"\3\u0095\3\u0095\3\u0095\3\u0096\3\u0096\3\u0096\3\u0096\3\u0096\3\u0096"+
|
||||
"\3\u0096\7\u0096\u04e0\n\u0096\f\u0096\16\u0096\u04e3\13\u0096\3\u0096"+
|
||||
"\7\u0096\u04e6\n\u0096\f\u0096\16\u0096\u04e9\13\u0096\3\u0096\3\u0096"+
|
||||
"\3\u0097\3\u0097\5\u0097\u04ef\n\u0097\3\u0097\3\u0097\5\u0097\u04f3\n"+
|
||||
"\u0097\3\u0097\3\u0097\7\u0097\u04f7\n\u0097\f\u0097\16\u0097\u04fa\13"+
|
||||
"\u0097\3\u0097\3\u0097\3\u0098\3\u0098\5\u0098\u0500\n\u0098\3\u0098\3"+
|
||||
"\u0098\3\u0098\3\u0098\3\u0098\3\u0098\3\u0098\3\u0098\3\u0098\7\u0098"+
|
||||
"\u050b\n\u0098\f\u0098\16\u0098\u050e\13\u0098\3\u0098\3\u0098\3\u0099"+
|
||||
"\6\u0099\u0513\n\u0099\r\u0099\16\u0099\u0514\3\u0099\3\u0099\3\u009a"+
|
||||
"\3\u009a\5\u009a\u051b\n\u009a\3\u009a\5\u009a\u051e\n\u009a\3\u009a\3"+
|
||||
"\u009a\3\u009b\3\u009b\3\u009b\3\u009b\7\u009b\u0526\n\u009b\f\u009b\16"+
|
||||
"\u009b\u0529\13\u009b\3\u009b\3\u009b\3\u009b\3\u009b\3\u009b\3\u009c"+
|
||||
"\3\u009c\3\u009c\3\u009c\7\u009c\u0534\n\u009c\f\u009c\16\u009c\u0537"+
|
||||
"\13\u009c\3\u009c\3\u009c\3\u009d\3\u009d\7\u009d\u053d\n\u009d\f\u009d"+
|
||||
"\16\u009d\u0540\13\u009d\3\u009d\3\u009d\3\u0527\2\u009e\3\3\5\4\7\5\t"+
|
||||
"\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23"+
|
||||
"%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G"+
|
||||
"%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\66k\67m8o9q:s;u<w=y>{"+
|
||||
"?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089F\u008bG\u008dH\u008fI\u0091"+
|
||||
"J\u0093K\u0095L\u0097M\u0099N\u009bO\u009dP\u009fQ\u00a1R\u00a3S\u00a5"+
|
||||
"T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1Z\u00b3[\u00b5\\\u00b7]\u00b9"+
|
||||
"^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5d\u00c7e\u00c9f\u00cbg\u00cd"+
|
||||
"h\u00cfi\u00d1j\u00d3k\u00d5\2\u00d7\2\u00d9\2\u00db\2\u00dd\2\u00dfl"+
|
||||
"\u00e1\2\u00e3\2\u00e5\2\u00e7\2\u00e9\2\u00eb\2\u00ed\2\u00ef\2\u00f1"+
|
||||
"\2\u00f3\2\u00f5\2\u00f7\2\u00f9\2\u00fb\2\u00fd\2\u00ff\2\u0101\2\u0103"+
|
||||
"\2\u0105\2\u0107\2\u0109\2\u010b\2\u010d\2\u010f\2\u0111\2\u0113\2\u0115"+
|
||||
"\2\u0117\2\u0119\2\u011b\2\u011d\2\u011fm\u0121\2\u0123\2\u0125\2\u0127"+
|
||||
"n\u0129o\u012bp\u012dq\u012fr\u0131s\u0133t\u0135u\u0137v\u0139w\3\2\27"+
|
||||
"\5\2C\\aac|\3\2\62;\4\2DDdd\3\2\62\63\4\2ZZzz\3\2\63;\3\2\629\5\2\62;"+
|
||||
"CHch\4\2WWww\4\2NNnn\4\2--//\6\2HHNNhhnn\6\2\f\f\17\17))^^\f\2$$))AA^"+
|
||||
"^cdhhppttvvxx\5\2NNWWww\6\2\f\f\17\17$$^^\3\2%%\3\2}}\3\2\177\177\4\2"+
|
||||
"\f\f\17\17\4\2\13\13\"\"\u0569\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t"+
|
||||
"\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2"+
|
||||
"\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2"+
|
||||
"\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2"+
|
||||
"+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2"+
|
||||
"\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2"+
|
||||
"C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3"+
|
||||
"\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2"+
|
||||
"\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2"+
|
||||
"i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2\2\2s\3\2\2\2\2u\3"+
|
||||
"\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2\177\3\2\2\2\2\u0081"+
|
||||
"\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3\2\2\2\2\u0089\3\2\2"+
|
||||
"\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2\2\u0091\3\2\2\2\2\u0093"+
|
||||
"\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099\3\2\2\2\2\u009b\3\2\2"+
|
||||
"\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2\2\2\u00a3\3\2\2\2\2\u00a5"+
|
||||
"\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab\3\2\2\2\2\u00ad\3\2\2"+
|
||||
"\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2\2\2\u00b5\3\2\2\2\2\u00b7"+
|
||||
"\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd\3\2\2\2\2\u00bf\3\2\2"+
|
||||
"\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9"+
|
||||
"\3\2\2\2\2\u00cb\3\2\2\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2"+
|
||||
"\2\2\u00d3\3\2\2\2\2\u00df\3\2\2\2\2\u011f\3\2\2\2\2\u0127\3\2\2\2\2\u0129"+
|
||||
"\3\2\2\2\2\u012b\3\2\2\2\2\u012d\3\2\2\2\2\u012f\3\2\2\2\2\u0131\3\2\2"+
|
||||
"\2\2\u0133\3\2\2\2\2\u0135\3\2\2\2\2\u0137\3\2\2\2\2\u0139\3\2\2\2\3\u013b"+
|
||||
"\3\2\2\2\5\u0149\3\2\2\2\7\u0156\3\2\2\2\t\u0160\3\2\2\2\13\u0168\3\2"+
|
||||
"\2\2\r\u0173\3\2\2\2\17\u0184\3\2\2\2\21\u018f\3\2\2\2\23\u0195\3\2\2"+
|
||||
"\2\25\u019d\3\2\2\2\27\u01a5\3\2\2\2\31\u01b3\3\2\2\2\33\u01be\3\2\2\2"+
|
||||
"\35\u01c5\3\2\2\2\37\u01d8\3\2\2\2!\u01dd\3\2\2\2#\u01e3\3\2\2\2%\u01e8"+
|
||||
"\3\2\2\2\'\u01ed\3\2\2\2)\u01f3\3\2\2\2+\u01fc\3\2\2\2-\u0204\3\2\2\2"+
|
||||
"/\u0207\3\2\2\2\61\u020e\3\2\2\2\63\u0213\3\2\2\2\65\u0218\3\2\2\2\67"+
|
||||
"\u021f\3\2\2\29\u0225\3\2\2\2;\u0229\3\2\2\2=\u022e\3\2\2\2?\u0231\3\2"+
|
||||
"\2\2A\u0238\3\2\2\2C\u023c\3\2\2\2E\u0241\3\2\2\2G\u024a\3\2\2\2I\u0253"+
|
||||
"\3\2\2\2K\u025a\3\2\2\2M\u0260\3\2\2\2O\u0267\3\2\2\2Q\u026e\3\2\2\2S"+
|
||||
"\u0275\3\2\2\2U\u027c\3\2\2\2W\u0283\3\2\2\2Y\u028b\3\2\2\2[\u0291\3\2"+
|
||||
"\2\2]\u029a\3\2\2\2_\u029f\3\2\2\2a\u02a8\3\2\2\2c\u02ae\3\2\2\2e\u02b7"+
|
||||
"\3\2\2\2g\u02c0\3\2\2\2i\u02c8\3\2\2\2k\u02ce\3\2\2\2m\u02d7\3\2\2\2o"+
|
||||
"\u02e0\3\2\2\2q\u02eb\3\2\2\2s\u02f5\3\2\2\2u\u0304\3\2\2\2w\u0312\3\2"+
|
||||
"\2\2y\u0314\3\2\2\2{\u0316\3\2\2\2}\u0318\3\2\2\2\177\u031a\3\2\2\2\u0081"+
|
||||
"\u031c\3\2\2\2\u0083\u031e\3\2\2\2\u0085\u0320\3\2\2\2\u0087\u0323\3\2"+
|
||||
"\2\2\u0089\u0325\3\2\2\2\u008b\u0328\3\2\2\2\u008d\u032b\3\2\2\2\u008f"+
|
||||
"\u032e\3\2\2\2\u0091\u0330\3\2\2\2\u0093\u0333\3\2\2\2\u0095\u0335\3\2"+
|
||||
"\2\2\u0097\u0338\3\2\2\2\u0099\u033a\3\2\2\2\u009b\u033c\3\2\2\2\u009d"+
|
||||
"\u033e\3\2\2\2\u009f\u0340\3\2\2\2\u00a1\u0342\3\2\2\2\u00a3\u0345\3\2"+
|
||||
"\2\2\u00a5\u0348\3\2\2\2\u00a7\u034a\3\2\2\2\u00a9\u034c\3\2\2\2\u00ab"+
|
||||
"\u034e\3\2\2\2\u00ad\u0350\3\2\2\2\u00af\u0352\3\2\2\2\u00b1\u0354\3\2"+
|
||||
"\2\2\u00b3\u0356\3\2\2\2\u00b5\u0358\3\2\2\2\u00b7\u035b\3\2\2\2\u00b9"+
|
||||
"\u035e\3\2\2\2\u00bb\u0361\3\2\2\2\u00bd\u0364\3\2\2\2\u00bf\u0367\3\2"+
|
||||
"\2\2\u00c1\u036b\3\2\2\2\u00c3\u036f\3\2\2\2\u00c5\u0372\3\2\2\2\u00c7"+
|
||||
"\u0375\3\2\2\2\u00c9\u0378\3\2\2\2\u00cb\u037b\3\2\2\2\u00cd\u037e\3\2"+
|
||||
"\2\2\u00cf\u0381\3\2\2\2\u00d1\u0383\3\2\2\2\u00d3\u0387\3\2\2\2\u00d5"+
|
||||
"\u0391\3\2\2\2\u00d7\u0393\3\2\2\2\u00d9\u0395\3\2\2\2\u00db\u03a1\3\2"+
|
||||
"\2\2\u00dd\u03a3\3\2\2\2\u00df\u03ab\3\2\2\2\u00e1\u03ba\3\2\2\2\u00e3"+
|
||||
"\u03bc\3\2\2\2\u00e5\u03c3\3\2\2\2\u00e7\u03ca\3\2\2\2\u00e9\u03d1\3\2"+
|
||||
"\2\2\u00eb\u03d7\3\2\2\2\u00ed\u03da\3\2\2\2\u00ef\u03dc\3\2\2\2\u00f1"+
|
||||
"\u03de\3\2\2\2\u00f3\u03ef\3\2\2\2\u00f5\u03f1\3\2\2\2\u00f7\u03f3\3\2"+
|
||||
"\2\2\u00f9\u03f9\3\2\2\2\u00fb\u03fd\3\2\2\2\u00fd\u040b\3\2\2\2\u00ff"+
|
||||
"\u0419\3\2\2\2\u0101\u0423\3\2\2\2\u0103\u042f\3\2\2\2\u0105\u0431\3\2"+
|
||||
"\2\2\u0107\u0434\3\2\2\2\u0109\u0440\3\2\2\2\u010b\u044c\3\2\2\2\u010d"+
|
||||
"\u044f\3\2\2\2\u010f\u0453\3\2\2\2\u0111\u046b\3\2\2\2\u0113\u046e\3\2"+
|
||||
"\2\2\u0115\u0474\3\2\2\2\u0117\u047a\3\2\2\2\u0119\u047c\3\2\2\2\u011b"+
|
||||
"\u048a\3\2\2\2\u011d\u048c\3\2\2\2\u011f\u0495\3\2\2\2\u0121\u04a0\3\2"+
|
||||
"\2\2\u0123\u04a3\3\2\2\2\u0125\u04ae\3\2\2\2\u0127\u04b0\3\2\2\2\u0129"+
|
||||
"\u04c3\3\2\2\2\u012b\u04d8\3\2\2\2\u012d\u04ec\3\2\2\2\u012f\u04fd\3\2"+
|
||||
"\2\2\u0131\u0512\3\2\2\2\u0133\u051d\3\2\2\2\u0135\u0521\3\2\2\2\u0137"+
|
||||
"\u052f\3\2\2\2\u0139\u053a\3\2\2\2\u013b\u013c\7a\2\2\u013c\u013d\7a\2"+
|
||||
"\2\u013d\u013e\7g\2\2\u013e\u013f\7z\2\2\u013f\u0140\7v\2\2\u0140\u0141"+
|
||||
"\7g\2\2\u0141\u0142\7p\2\2\u0142\u0143\7u\2\2\u0143\u0144\7k\2\2\u0144"+
|
||||
"\u0145\7q\2\2\u0145\u0146\7p\2\2\u0146\u0147\7a\2\2\u0147\u0148\7a\2\2"+
|
||||
"\u0148\4\3\2\2\2\u0149\u014a\7a\2\2\u014a\u014b\7a\2\2\u014b\u014c\7x"+
|
||||
"\2\2\u014c\u014d\7q\2\2\u014d\u014e\7n\2\2\u014e\u014f\7c\2\2\u014f\u0150"+
|
||||
"\7v\2\2\u0150\u0151\7k\2\2\u0151\u0152\7n\2\2\u0152\u0153\7g\2\2\u0153"+
|
||||
"\u0154\7a\2\2\u0154\u0155\7a\2\2\u0155\6\3\2\2\2\u0156\u0157\7a\2\2\u0157"+
|
||||
"\u0158\7a\2\2\u0158\u0159\7u\2\2\u0159\u015a\7v\2\2\u015a\u015b\7f\2\2"+
|
||||
"\u015b\u015c\7e\2\2\u015c\u015d\7c\2\2\u015d\u015e\7n\2\2\u015e\u015f"+
|
||||
"\7n\2\2\u015f\b\3\2\2\2\u0160\u0161\7a\2\2\u0161\u0162\7a\2\2\u0162\u0163"+
|
||||
"\7c\2\2\u0163\u0164\7u\2\2\u0164\u0165\7o\2\2\u0165\u0166\7a\2\2\u0166"+
|
||||
"\u0167\7a\2\2\u0167\n\3\2\2\2\u0168\u0169\7a\2\2\u0169\u016a\7a\2\2\u016a"+
|
||||
"\u016b\7f\2\2\u016b\u016c\7g\2\2\u016c\u016d\7e\2\2\u016d\u016e\7n\2\2"+
|
||||
"\u016e\u016f\7u\2\2\u016f\u0170\7r\2\2\u0170\u0171\7g\2\2\u0171\u0172"+
|
||||
"\7e\2\2\u0172\f\3\2\2\2\u0173\u0174\7a\2\2\u0174\u0175\7a\2\2\u0175\u0176"+
|
||||
"\7d\2\2\u0176\u0177\7w\2\2\u0177\u0178\7k\2\2\u0178\u0179\7n\2\2\u0179"+
|
||||
"\u017a\7v\2\2\u017a\u017b\7k\2\2\u017b\u017c\7p\2\2\u017c\u017d\7a\2\2"+
|
||||
"\u017d\u017e\7x\2\2\u017e\u017f\7c\2\2\u017f\u0180\7a\2\2\u0180\u0181"+
|
||||
"\7c\2\2\u0181\u0182\7t\2\2\u0182\u0183\7i\2\2\u0183\16\3\2\2\2\u0184\u0185"+
|
||||
"\7a\2\2\u0185\u0186\7a\2\2\u0186\u0187\7v\2\2\u0187\u0188\7{\2\2\u0188"+
|
||||
"\u0189\7r\2\2\u0189\u018a\7g\2\2\u018a\u018b\7q\2\2\u018b\u018c\7h\2\2"+
|
||||
"\u018c\u018d\7a\2\2\u018d\u018e\7a\2\2\u018e\20\3\2\2\2\u018f\u0190\7"+
|
||||
"a\2\2\u0190\u0191\7a\2\2\u0191\u0192\7c\2\2\u0192\u0193\7u\2\2\u0193\u0194"+
|
||||
"\7o\2\2\u0194\22\3\2\2\2\u0195\u0196\7a\2\2\u0196\u0197\7a\2\2\u0197\u0198"+
|
||||
"\7o\2\2\u0198\u0199\7\63\2\2\u0199\u019a\7\64\2\2\u019a\u019b\7:\2\2\u019b"+
|
||||
"\u019c\7f\2\2\u019c\24\3\2\2\2\u019d\u019e\7a\2\2\u019e\u019f\7a\2\2\u019f"+
|
||||
"\u01a0\7o\2\2\u01a0\u01a1\7\63\2\2\u01a1\u01a2\7\64\2\2\u01a2\u01a3\7"+
|
||||
":\2\2\u01a3\u01a4\7k\2\2\u01a4\26\3\2\2\2\u01a5\u01a6\7a\2\2\u01a6\u01a7"+
|
||||
"\7a\2\2\u01a7\u01a8\7c\2\2\u01a8\u01a9\7v\2\2\u01a9\u01aa\7v\2\2\u01aa"+
|
||||
"\u01ab\7t\2\2\u01ab\u01ac\7k\2\2\u01ac\u01ad\7d\2\2\u01ad\u01ae\7w\2\2"+
|
||||
"\u01ae\u01af\7v\2\2\u01af\u01b0\7g\2\2\u01b0\u01b1\7a\2\2\u01b1\u01b2"+
|
||||
"\7a\2\2\u01b2\30\3\2\2\2\u01b3\u01b4\7a\2\2\u01b4\u01b5\7a\2\2\u01b5\u01b6"+
|
||||
"\7k\2\2\u01b6\u01b7\7p\2\2\u01b7\u01b8\7n\2\2\u01b8\u01b9\7k\2\2\u01b9"+
|
||||
"\u01ba\7p\2\2\u01ba\u01bb\7g\2\2\u01bb\u01bc\7a\2\2\u01bc\u01bd\7a\2\2"+
|
||||
"\u01bd\32\3\2\2\2\u01be\u01bf\7a\2\2\u01bf\u01c0\7a\2\2\u01c0\u01c1\7"+
|
||||
"o\2\2\u01c1\u01c2\7\63\2\2\u01c2\u01c3\7\64\2\2\u01c3\u01c4\7:\2\2\u01c4"+
|
||||
"\34\3\2\2\2\u01c5\u01c6\7a\2\2\u01c6\u01c7\7a\2\2\u01c7\u01c8\7d\2\2\u01c8"+
|
||||
"\u01c9\7w\2\2\u01c9\u01ca\7k\2\2\u01ca\u01cb\7n\2\2\u01cb\u01cc\7v\2\2"+
|
||||
"\u01cc\u01cd\7k\2\2\u01cd\u01ce\7p\2\2\u01ce\u01cf\7a\2\2\u01cf\u01d0"+
|
||||
"\7q\2\2\u01d0\u01d1\7h\2\2\u01d1\u01d2\7h\2\2\u01d2\u01d3\7u\2\2\u01d3"+
|
||||
"\u01d4\7g\2\2\u01d4\u01d5\7v\2\2\u01d5\u01d6\7q\2\2\u01d6\u01d7\7h\2\2"+
|
||||
"\u01d7\36\3\2\2\2\u01d8\u01d9\7c\2\2\u01d9\u01da\7w\2\2\u01da\u01db\7"+
|
||||
"v\2\2\u01db\u01dc\7q\2\2\u01dc \3\2\2\2\u01dd\u01de\7d\2\2\u01de\u01df"+
|
||||
"\7t\2\2\u01df\u01e0\7g\2\2\u01e0\u01e1\7c\2\2\u01e1\u01e2\7m\2\2\u01e2"+
|
||||
"\"\3\2\2\2\u01e3\u01e4\7e\2\2\u01e4\u01e5\7c\2\2\u01e5\u01e6\7u\2\2\u01e6"+
|
||||
"\u01e7\7g\2\2\u01e7$\3\2\2\2\u01e8\u01e9\7e\2\2\u01e9\u01ea\7j\2\2\u01ea"+
|
||||
"\u01eb\7c\2\2\u01eb\u01ec\7t\2\2\u01ec&\3\2\2\2\u01ed\u01ee\7e\2\2\u01ee"+
|
||||
"\u01ef\7q\2\2\u01ef\u01f0\7p\2\2\u01f0\u01f1\7u\2\2\u01f1\u01f2\7v\2\2"+
|
||||
"\u01f2(\3\2\2\2\u01f3\u01f4\7e\2\2\u01f4\u01f5\7q\2\2\u01f5\u01f6\7p\2"+
|
||||
"\2\u01f6\u01f7\7v\2\2\u01f7\u01f8\7k\2\2\u01f8\u01f9\7p\2\2\u01f9\u01fa"+
|
||||
"\7w\2\2\u01fa\u01fb\7g\2\2\u01fb*\3\2\2\2\u01fc\u01fd\7f\2\2\u01fd\u01fe"+
|
||||
"\7g\2\2\u01fe\u01ff\7h\2\2\u01ff\u0200\7c\2\2\u0200\u0201\7w\2\2\u0201"+
|
||||
"\u0202\7n\2\2\u0202\u0203\7v\2\2\u0203,\3\2\2\2\u0204\u0205\7f\2\2\u0205"+
|
||||
"\u0206\7q\2\2\u0206.\3\2\2\2\u0207\u0208\7f\2\2\u0208\u0209\7q\2\2\u0209"+
|
||||
"\u020a\7w\2\2\u020a\u020b\7d\2\2\u020b\u020c\7n\2\2\u020c\u020d\7g\2\2"+
|
||||
"\u020d\60\3\2\2\2\u020e\u020f\7g\2\2\u020f\u0210\7n\2\2\u0210\u0211\7"+
|
||||
"u\2\2\u0211\u0212\7g\2\2\u0212\62\3\2\2\2\u0213\u0214\7g\2\2\u0214\u0215"+
|
||||
"\7p\2\2\u0215\u0216\7w\2\2\u0216\u0217\7o\2\2\u0217\64\3\2\2\2\u0218\u0219"+
|
||||
"\7g\2\2\u0219\u021a\7z\2\2\u021a\u021b\7v\2\2\u021b\u021c\7g\2\2\u021c"+
|
||||
"\u021d\7t\2\2\u021d\u021e\7p\2\2\u021e\66\3\2\2\2\u021f\u0220\7h\2\2\u0220"+
|
||||
"\u0221\7n\2\2\u0221\u0222\7q\2\2\u0222\u0223\7c\2\2\u0223\u0224\7v\2\2"+
|
||||
"\u02248\3\2\2\2\u0225\u0226\7h\2\2\u0226\u0227\7q\2\2\u0227\u0228\7t\2"+
|
||||
"\2\u0228:\3\2\2\2\u0229\u022a\7i\2\2\u022a\u022b\7q\2\2\u022b\u022c\7"+
|
||||
"v\2\2\u022c\u022d\7q\2\2\u022d<\3\2\2\2\u022e\u022f\7k\2\2\u022f\u0230"+
|
||||
"\7h\2\2\u0230>\3\2\2\2\u0231\u0232\7k\2\2\u0232\u0233\7p\2\2\u0233\u0234"+
|
||||
"\7n\2\2\u0234\u0235\7k\2\2\u0235\u0236\7p\2\2\u0236\u0237\7g\2\2\u0237"+
|
||||
"@\3\2\2\2\u0238\u0239\7k\2\2\u0239\u023a\7p\2\2\u023a\u023b\7v\2\2\u023b"+
|
||||
"B\3\2\2\2\u023c\u023d\7n\2\2\u023d\u023e\7q\2\2\u023e\u023f\7p\2\2\u023f"+
|
||||
"\u0240\7i\2\2\u0240D\3\2\2\2\u0241\u0242\7t\2\2\u0242\u0243\7g\2\2\u0243"+
|
||||
"\u0244\7i\2\2\u0244\u0245\7k\2\2\u0245\u0246\7u\2\2\u0246\u0247\7v\2\2"+
|
||||
"\u0247\u0248\7g\2\2\u0248\u0249\7t\2\2\u0249F\3\2\2\2\u024a\u024b\7t\2"+
|
||||
"\2\u024b\u024c\7g\2\2\u024c\u024d\7u\2\2\u024d\u024e\7v\2\2\u024e\u024f"+
|
||||
"\7t\2\2\u024f\u0250\7k\2\2\u0250\u0251\7e\2\2\u0251\u0252\7v\2\2\u0252"+
|
||||
"H\3\2\2\2\u0253\u0254\7t\2\2\u0254\u0255\7g\2\2\u0255\u0256\7v\2\2\u0256"+
|
||||
"\u0257\7w\2\2\u0257\u0258\7t\2\2\u0258\u0259\7p\2\2\u0259J\3\2\2\2\u025a"+
|
||||
"\u025b\7u\2\2\u025b\u025c\7j\2\2\u025c\u025d\7q\2\2\u025d\u025e\7t\2\2"+
|
||||
"\u025e\u025f\7v\2\2\u025fL\3\2\2\2\u0260\u0261\7u\2\2\u0261\u0262\7k\2"+
|
||||
"\2\u0262\u0263\7i\2\2\u0263\u0264\7p\2\2\u0264\u0265\7g\2\2\u0265\u0266"+
|
||||
"\7f\2\2\u0266N\3\2\2\2\u0267\u0268\7u\2\2\u0268\u0269\7k\2\2\u0269\u026a"+
|
||||
"\7|\2\2\u026a\u026b\7g\2\2\u026b\u026c\7q\2\2\u026c\u026d\7h\2\2\u026d"+
|
||||
"P\3\2\2\2\u026e\u026f\7u\2\2\u026f\u0270\7v\2\2\u0270\u0271\7c\2\2\u0271"+
|
||||
"\u0272\7v\2\2\u0272\u0273\7k\2\2\u0273\u0274\7e\2\2\u0274R\3\2\2\2\u0275"+
|
||||
"\u0276\7u\2\2\u0276\u0277\7v\2\2\u0277\u0278\7t\2\2\u0278\u0279\7w\2\2"+
|
||||
"\u0279\u027a\7e\2\2\u027a\u027b\7v\2\2\u027bT\3\2\2\2\u027c\u027d\7u\2"+
|
||||
"\2\u027d\u027e\7y\2\2\u027e\u027f\7k\2\2\u027f\u0280\7v\2\2\u0280\u0281"+
|
||||
"\7e\2\2\u0281\u0282\7j\2\2\u0282V\3\2\2\2\u0283\u0284\7v\2\2\u0284\u0285"+
|
||||
"\7{\2\2\u0285\u0286\7r\2\2\u0286\u0287\7g\2\2\u0287\u0288\7f\2\2\u0288"+
|
||||
"\u0289\7g\2\2\u0289\u028a\7h\2\2\u028aX\3\2\2\2\u028b\u028c\7w\2\2\u028c"+
|
||||
"\u028d\7p\2\2\u028d\u028e\7k\2\2\u028e\u028f\7q\2\2\u028f\u0290\7p\2\2"+
|
||||
"\u0290Z\3\2\2\2\u0291\u0292\7w\2\2\u0292\u0293\7p\2\2\u0293\u0294\7u\2"+
|
||||
"\2\u0294\u0295\7k\2\2\u0295\u0296\7i\2\2\u0296\u0297\7p\2\2\u0297\u0298"+
|
||||
"\7g\2\2\u0298\u0299\7f\2\2\u0299\\\3\2\2\2\u029a\u029b\7x\2\2\u029b\u029c"+
|
||||
"\7q\2\2\u029c\u029d\7k\2\2\u029d\u029e\7f\2\2\u029e^\3\2\2\2\u029f\u02a0"+
|
||||
"\7x\2\2\u02a0\u02a1\7q\2\2\u02a1\u02a2\7n\2\2\u02a2\u02a3\7c\2\2\u02a3"+
|
||||
"\u02a4\7v\2\2\u02a4\u02a5\7k\2\2\u02a5\u02a6\7n\2\2\u02a6\u02a7\7g\2\2"+
|
||||
"\u02a7`\3\2\2\2\u02a8\u02a9\7y\2\2\u02a9\u02aa\7j\2\2\u02aa\u02ab\7k\2"+
|
||||
"\2\u02ab\u02ac\7n\2\2\u02ac\u02ad\7g\2\2\u02adb\3\2\2\2\u02ae\u02af\7"+
|
||||
"a\2\2\u02af\u02b0\7C\2\2\u02b0\u02b1\7n\2\2\u02b1\u02b2\7k\2\2\u02b2\u02b3"+
|
||||
"\7i\2\2\u02b3\u02b4\7p\2\2\u02b4\u02b5\7c\2\2\u02b5\u02b6\7u\2\2\u02b6"+
|
||||
"d\3\2\2\2\u02b7\u02b8\7a\2\2\u02b8\u02b9\7C\2\2\u02b9\u02ba\7n\2\2\u02ba"+
|
||||
"\u02bb\7k\2\2\u02bb\u02bc\7i\2\2\u02bc\u02bd\7p\2\2\u02bd\u02be\7q\2\2"+
|
||||
"\u02be\u02bf\7h\2\2\u02bff\3\2\2\2\u02c0\u02c1\7a\2\2\u02c1\u02c2\7C\2"+
|
||||
"\2\u02c2\u02c3\7v\2\2\u02c3\u02c4\7q\2\2\u02c4\u02c5\7o\2\2\u02c5\u02c6"+
|
||||
"\7k\2\2\u02c6\u02c7\7e\2\2\u02c7h\3\2\2\2\u02c8\u02c9\7a\2\2\u02c9\u02ca"+
|
||||
"\7D\2\2\u02ca\u02cb\7q\2\2\u02cb\u02cc\7q\2\2\u02cc\u02cd\7n\2\2\u02cd"+
|
||||
"j\3\2\2\2\u02ce\u02cf\7a\2\2\u02cf\u02d0\7E\2\2\u02d0\u02d1\7q\2\2\u02d1"+
|
||||
"\u02d2\7o\2\2\u02d2\u02d3\7r\2\2\u02d3\u02d4\7n\2\2\u02d4\u02d5\7g\2\2"+
|
||||
"\u02d5\u02d6\7z\2\2\u02d6l\3\2\2\2\u02d7\u02d8\7a\2\2\u02d8\u02d9\7I\2"+
|
||||
"\2\u02d9\u02da\7g\2\2\u02da\u02db\7p\2\2\u02db\u02dc\7g\2\2\u02dc\u02dd"+
|
||||
"\7t\2\2\u02dd\u02de\7k\2\2\u02de\u02df\7e\2\2\u02dfn\3\2\2\2\u02e0\u02e1"+
|
||||
"\7a\2\2\u02e1\u02e2\7K\2\2\u02e2\u02e3\7o\2\2\u02e3\u02e4\7c\2\2\u02e4"+
|
||||
"\u02e5\7i\2\2\u02e5\u02e6\7k\2\2\u02e6\u02e7\7p\2\2\u02e7\u02e8\7c\2\2"+
|
||||
"\u02e8\u02e9\7t\2\2\u02e9\u02ea\7{\2\2\u02eap\3\2\2\2\u02eb\u02ec\7a\2"+
|
||||
"\2\u02ec\u02ed\7P\2\2\u02ed\u02ee\7q\2\2\u02ee\u02ef\7t\2\2\u02ef\u02f0"+
|
||||
"\7g\2\2\u02f0\u02f1\7v\2\2\u02f1\u02f2\7w\2\2\u02f2\u02f3\7t\2\2\u02f3"+
|
||||
"\u02f4\7p\2\2\u02f4r\3\2\2\2\u02f5\u02f6\7a\2\2\u02f6\u02f7\7U\2\2\u02f7"+
|
||||
"\u02f8\7v\2\2\u02f8\u02f9\7c\2\2\u02f9\u02fa\7v\2\2\u02fa\u02fb\7k\2\2"+
|
||||
"\u02fb\u02fc\7e\2\2\u02fc\u02fd\7a\2\2\u02fd\u02fe\7c\2\2\u02fe\u02ff"+
|
||||
"\7u\2\2\u02ff\u0300\7u\2\2\u0300\u0301\7g\2\2\u0301\u0302\7t\2\2\u0302"+
|
||||
"\u0303\7v\2\2\u0303t\3\2\2\2\u0304\u0305\7a\2\2\u0305\u0306\7V\2\2\u0306"+
|
||||
"\u0307\7j\2\2\u0307\u0308\7t\2\2\u0308\u0309\7g\2\2\u0309\u030a\7c\2\2"+
|
||||
"\u030a\u030b\7f\2\2\u030b\u030c\7a\2\2\u030c\u030d\7n\2\2\u030d\u030e"+
|
||||
"\7q\2\2\u030e\u030f\7e\2\2\u030f\u0310\7c\2\2\u0310\u0311\7n\2\2\u0311"+
|
||||
"v\3\2\2\2\u0312\u0313\7*\2\2\u0313x\3\2\2\2\u0314\u0315\7+\2\2\u0315z"+
|
||||
"\3\2\2\2\u0316\u0317\7]\2\2\u0317|\3\2\2\2\u0318\u0319\7_\2\2\u0319~\3"+
|
||||
"\2\2\2\u031a\u031b\7}\2\2\u031b\u0080\3\2\2\2\u031c\u031d\7\177\2\2\u031d"+
|
||||
"\u0082\3\2\2\2\u031e\u031f\7>\2\2\u031f\u0084\3\2\2\2\u0320\u0321\7>\2"+
|
||||
"\2\u0321\u0322\7?\2\2\u0322\u0086\3\2\2\2\u0323\u0324\7@\2\2\u0324\u0088"+
|
||||
"\3\2\2\2\u0325\u0326\7@\2\2\u0326\u0327\7?\2\2\u0327\u008a\3\2\2\2\u0328"+
|
||||
"\u0329\7>\2\2\u0329\u032a\7>\2\2\u032a\u008c\3\2\2\2\u032b\u032c\7@\2"+
|
||||
"\2\u032c\u032d\7@\2\2\u032d\u008e\3\2\2\2\u032e\u032f\7-\2\2\u032f\u0090"+
|
||||
"\3\2\2\2\u0330\u0331\7-\2\2\u0331\u0332\7-\2\2\u0332\u0092\3\2\2\2\u0333"+
|
||||
"\u0334\7/\2\2\u0334\u0094\3\2\2\2\u0335\u0336\7/\2\2\u0336\u0337\7/\2"+
|
||||
"\2\u0337\u0096\3\2\2\2\u0338\u0339\7,\2\2\u0339\u0098\3\2\2\2\u033a\u033b"+
|
||||
"\7\61\2\2\u033b\u009a\3\2\2\2\u033c\u033d\7\'\2\2\u033d\u009c\3\2\2\2"+
|
||||
"\u033e\u033f\7(\2\2\u033f\u009e\3\2\2\2\u0340\u0341\7~\2\2\u0341\u00a0"+
|
||||
"\3\2\2\2\u0342\u0343\7(\2\2\u0343\u0344\7(\2\2\u0344\u00a2\3\2\2\2\u0345"+
|
||||
"\u0346\7~\2\2\u0346\u0347\7~\2\2\u0347\u00a4\3\2\2\2\u0348\u0349\7`\2"+
|
||||
"\2\u0349\u00a6\3\2\2\2\u034a\u034b\7#\2\2\u034b\u00a8\3\2\2\2\u034c\u034d"+
|
||||
"\7\u0080\2\2\u034d\u00aa\3\2\2\2\u034e\u034f\7A\2\2\u034f\u00ac\3\2\2"+
|
||||
"\2\u0350\u0351\7<\2\2\u0351\u00ae\3\2\2\2\u0352\u0353\7=\2\2\u0353\u00b0"+
|
||||
"\3\2\2\2\u0354\u0355\7.\2\2\u0355\u00b2\3\2\2\2\u0356\u0357\7?\2\2\u0357"+
|
||||
"\u00b4\3\2\2\2\u0358\u0359\7,\2\2\u0359\u035a\7?\2\2\u035a\u00b6\3\2\2"+
|
||||
"\2\u035b\u035c\7\61\2\2\u035c\u035d\7?\2\2\u035d\u00b8\3\2\2\2\u035e\u035f"+
|
||||
"\7\'\2\2\u035f\u0360\7?\2\2\u0360\u00ba\3\2\2\2\u0361\u0362\7-\2\2\u0362"+
|
||||
"\u0363\7?\2\2\u0363\u00bc\3\2\2\2\u0364\u0365\7/\2\2\u0365\u0366\7?\2"+
|
||||
"\2\u0366\u00be\3\2\2\2\u0367\u0368\7>\2\2\u0368\u0369\7>\2\2\u0369\u036a"+
|
||||
"\7?\2\2\u036a\u00c0\3\2\2\2\u036b\u036c\7@\2\2\u036c\u036d\7@\2\2\u036d"+
|
||||
"\u036e\7?\2\2\u036e\u00c2\3\2\2\2\u036f\u0370\7(\2\2\u0370\u0371\7?\2"+
|
||||
"\2\u0371\u00c4\3\2\2\2\u0372\u0373\7`\2\2\u0373\u0374\7?\2\2\u0374\u00c6"+
|
||||
"\3\2\2\2\u0375\u0376\7~\2\2\u0376\u0377\7?\2\2\u0377\u00c8\3\2\2\2\u0378"+
|
||||
"\u0379\7?\2\2\u0379\u037a\7?\2\2\u037a\u00ca\3\2\2\2\u037b\u037c\7#\2"+
|
||||
"\2\u037c\u037d\7?\2\2\u037d\u00cc\3\2\2\2\u037e\u037f\7/\2\2\u037f\u0380"+
|
||||
"\7@\2\2\u0380\u00ce\3\2\2\2\u0381\u0382\7\60\2\2\u0382\u00d0\3\2\2\2\u0383"+
|
||||
"\u0384\7\60\2\2\u0384\u0385\7\60\2\2\u0385\u0386\7\60\2\2\u0386\u00d2"+
|
||||
"\3\2\2\2\u0387\u038c\5\u00d5k\2\u0388\u038b\5\u00d5k\2\u0389\u038b\5\u00d9"+
|
||||
"m\2\u038a\u0388\3\2\2\2\u038a\u0389\3\2\2\2\u038b\u038e\3\2\2\2\u038c"+
|
||||
"\u038a\3\2\2\2\u038c\u038d\3\2\2\2\u038d\u00d4\3\2\2\2\u038e\u038c\3\2"+
|
||||
"\2\2\u038f\u0392\5\u00d7l\2\u0390\u0392\5\u00dbn\2\u0391\u038f\3\2\2\2"+
|
||||
"\u0391\u0390\3\2\2\2\u0392\u00d6\3\2\2\2\u0393\u0394\t\2\2\2\u0394\u00d8"+
|
||||
"\3\2\2\2\u0395\u0396\t\3\2\2\u0396\u00da\3\2\2\2\u0397\u0398\7^\2\2\u0398"+
|
||||
"\u0399\7w\2\2\u0399\u039a\3\2\2\2\u039a\u03a2\5\u00ddo\2\u039b\u039c\7"+
|
||||
"^\2\2\u039c\u039d\7W\2\2\u039d\u039e\3\2\2\2\u039e\u039f\5\u00ddo\2\u039f"+
|
||||
"\u03a0\5\u00ddo\2\u03a0\u03a2\3\2\2\2\u03a1\u0397\3\2\2\2\u03a1\u039b"+
|
||||
"\3\2\2\2\u03a2\u00dc\3\2\2\2\u03a3\u03a4\5\u00f1y\2\u03a4\u03a5\5\u00f1"+
|
||||
"y\2\u03a5\u03a6\5\u00f1y\2\u03a6\u03a7\5\u00f1y\2\u03a7\u00de\3\2\2\2"+
|
||||
"\u03a8\u03ac\5\u00e1q\2\u03a9\u03ac\5\u00fb~\2\u03aa\u03ac\5\u0111\u0089"+
|
||||
"\2\u03ab\u03a8\3\2\2\2\u03ab\u03a9\3\2\2\2\u03ab\u03aa\3\2\2\2\u03ac\u00e0"+
|
||||
"\3\2\2\2\u03ad\u03af\5\u00e5s\2\u03ae\u03b0\5\u00f3z\2\u03af\u03ae\3\2"+
|
||||
"\2\2\u03af\u03b0\3\2\2\2\u03b0\u03bb\3\2\2\2\u03b1\u03b3\5\u00e7t\2\u03b2"+
|
||||
"\u03b4\5\u00f3z\2\u03b3\u03b2\3\2\2\2\u03b3\u03b4\3\2\2\2\u03b4\u03bb"+
|
||||
"\3\2\2\2\u03b5\u03b7\5\u00e9u\2\u03b6\u03b8\5\u00f3z\2\u03b7\u03b6\3\2"+
|
||||
"\2\2\u03b7\u03b8\3\2\2\2\u03b8\u03bb\3\2\2\2\u03b9\u03bb\5\u00e3r\2\u03ba"+
|
||||
"\u03ad\3\2\2\2\u03ba\u03b1\3\2\2\2\u03ba\u03b5\3\2\2\2\u03ba\u03b9\3\2"+
|
||||
"\2\2\u03bb\u00e2\3\2\2\2\u03bc\u03bd\7\62\2\2\u03bd\u03bf\t\4\2\2\u03be"+
|
||||
"\u03c0\t\5\2\2\u03bf\u03be\3\2\2\2\u03c0\u03c1\3\2\2\2\u03c1\u03bf\3\2"+
|
||||
"\2\2\u03c1\u03c2\3\2\2\2\u03c2\u00e4\3\2\2\2\u03c3\u03c7\5\u00edw\2\u03c4"+
|
||||
"\u03c6\5\u00d9m\2\u03c5\u03c4\3\2\2\2\u03c6\u03c9\3\2\2\2\u03c7\u03c5"+
|
||||
"\3\2\2\2\u03c7\u03c8\3\2\2\2\u03c8\u00e6\3\2\2\2\u03c9\u03c7\3\2\2\2\u03ca"+
|
||||
"\u03ce\7\62\2\2\u03cb\u03cd\5\u00efx\2\u03cc\u03cb\3\2\2\2\u03cd\u03d0"+
|
||||
"\3\2\2\2\u03ce\u03cc\3\2\2\2\u03ce\u03cf\3\2\2\2\u03cf\u00e8\3\2\2\2\u03d0"+
|
||||
"\u03ce\3\2\2\2\u03d1\u03d3\5\u00ebv\2\u03d2\u03d4\5\u00f1y\2\u03d3\u03d2"+
|
||||
"\3\2\2\2\u03d4\u03d5\3\2\2\2\u03d5\u03d3\3\2\2\2\u03d5\u03d6\3\2\2\2\u03d6"+
|
||||
"\u00ea\3\2\2\2\u03d7\u03d8\7\62\2\2\u03d8\u03d9\t\6\2\2\u03d9\u00ec\3"+
|
||||
"\2\2\2\u03da\u03db\t\7\2\2\u03db\u00ee\3\2\2\2\u03dc\u03dd\t\b\2\2\u03dd"+
|
||||
"\u00f0\3\2\2\2\u03de\u03df\t\t\2\2\u03df\u00f2\3\2\2\2\u03e0\u03e2\5\u00f5"+
|
||||
"{\2\u03e1\u03e3\5\u00f7|\2\u03e2\u03e1\3\2\2\2\u03e2\u03e3\3\2\2\2\u03e3"+
|
||||
"\u03f0\3\2\2\2\u03e4\u03e5\5\u00f5{\2\u03e5\u03e6\5\u00f9}\2\u03e6\u03f0"+
|
||||
"\3\2\2\2\u03e7\u03e9\5\u00f7|\2\u03e8\u03ea\5\u00f5{\2\u03e9\u03e8\3\2"+
|
||||
"\2\2\u03e9\u03ea\3\2\2\2\u03ea\u03f0\3\2\2\2\u03eb\u03ed\5\u00f9}\2\u03ec"+
|
||||
"\u03ee\5\u00f5{\2\u03ed\u03ec\3\2\2\2\u03ed\u03ee\3\2\2\2\u03ee\u03f0"+
|
||||
"\3\2\2\2\u03ef\u03e0\3\2\2\2\u03ef\u03e4\3\2\2\2\u03ef\u03e7\3\2\2\2\u03ef"+
|
||||
"\u03eb\3\2\2\2\u03f0\u00f4\3\2\2\2\u03f1\u03f2\t\n\2\2\u03f2\u00f6\3\2"+
|
||||
"\2\2\u03f3\u03f4\t\13\2\2\u03f4\u00f8\3\2\2\2\u03f5\u03f6\7n\2\2\u03f6"+
|
||||
"\u03fa\7n\2\2\u03f7\u03f8\7N\2\2\u03f8\u03fa\7N\2\2\u03f9\u03f5\3\2\2"+
|
||||
"\2\u03f9\u03f7\3\2\2\2\u03fa\u00fa\3\2\2\2\u03fb\u03fe\5\u00fd\177\2\u03fc"+
|
||||
"\u03fe\5\u00ff\u0080\2\u03fd\u03fb\3\2\2\2\u03fd\u03fc\3\2\2\2\u03fe\u00fc"+
|
||||
"\3\2\2\2\u03ff\u0401\5\u0101\u0081\2\u0400\u0402\5\u0103\u0082\2\u0401"+
|
||||
"\u0400\3\2\2\2\u0401\u0402\3\2\2\2\u0402\u0404\3\2\2\2\u0403\u0405\5\u010f"+
|
||||
"\u0088\2\u0404\u0403\3\2\2\2\u0404\u0405\3\2\2\2\u0405\u040c\3\2\2\2\u0406"+
|
||||
"\u0407\5\u0107\u0084\2\u0407\u0409\5\u0103\u0082\2\u0408\u040a\5\u010f"+
|
||||
"\u0088\2\u0409\u0408\3\2\2\2\u0409\u040a\3\2\2\2\u040a\u040c\3\2\2\2\u040b"+
|
||||
"\u03ff\3\2\2\2\u040b\u0406\3\2\2\2\u040c\u00fe\3\2\2\2\u040d\u040e\5\u00eb"+
|
||||
"v\2\u040e\u040f\5\u0109\u0085\2\u040f\u0411\5\u010b\u0086\2\u0410\u0412"+
|
||||
"\5\u010f\u0088\2\u0411\u0410\3\2\2\2\u0411\u0412\3\2\2\2\u0412\u041a\3"+
|
||||
"\2\2\2\u0413\u0414\5\u00ebv\2\u0414\u0415\5\u010d\u0087\2\u0415\u0417"+
|
||||
"\5\u010b\u0086\2\u0416\u0418\5\u010f\u0088\2\u0417\u0416\3\2\2\2\u0417"+
|
||||
"\u0418\3\2\2\2\u0418\u041a\3\2\2\2\u0419\u040d\3\2\2\2\u0419\u0413\3\2"+
|
||||
"\2\2\u041a\u0100\3\2\2\2\u041b\u041d\5\u0107\u0084\2\u041c\u041b\3\2\2"+
|
||||
"\2\u041c\u041d\3\2\2\2\u041d\u041e\3\2\2\2\u041e\u041f\7\60\2\2\u041f"+
|
||||
"\u0424\5\u0107\u0084\2\u0420\u0421\5\u0107\u0084\2\u0421\u0422\7\60\2"+
|
||||
"\2\u0422\u0424\3\2\2\2\u0423\u041c\3\2\2\2\u0423\u0420\3\2\2\2\u0424\u0102"+
|
||||
"\3\2\2\2\u0425\u0427\7g\2\2\u0426\u0428\5\u0105\u0083\2\u0427\u0426\3"+
|
||||
"\2\2\2\u0427\u0428\3\2\2\2\u0428\u0429\3\2\2\2\u0429\u0430\5\u0107\u0084"+
|
||||
"\2\u042a\u042c\7G\2\2\u042b\u042d\5\u0105\u0083\2\u042c\u042b\3\2\2\2"+
|
||||
"\u042c\u042d\3\2\2\2\u042d\u042e\3\2\2\2\u042e\u0430\5\u0107\u0084\2\u042f"+
|
||||
"\u0425\3\2\2\2\u042f\u042a\3\2\2\2\u0430\u0104\3\2\2\2\u0431\u0432\t\f"+
|
||||
"\2\2\u0432\u0106\3\2\2\2\u0433\u0435\5\u00d9m\2\u0434\u0433\3\2\2\2\u0435"+
|
||||
"\u0436\3\2\2\2\u0436\u0434\3\2\2\2\u0436\u0437\3\2\2\2\u0437\u0108\3\2"+
|
||||
"\2\2\u0438\u043a\5\u010d\u0087\2\u0439\u0438\3\2\2\2\u0439\u043a\3\2\2"+
|
||||
"\2\u043a\u043b\3\2\2\2\u043b\u043c\7\60\2\2\u043c\u0441\5\u010d\u0087"+
|
||||
"\2\u043d\u043e\5\u010d\u0087\2\u043e\u043f\7\60\2\2\u043f\u0441\3\2\2"+
|
||||
"\2\u0440\u0439\3\2\2\2\u0440\u043d\3\2\2\2\u0441\u010a\3\2\2\2\u0442\u0444"+
|
||||
"\7r\2\2\u0443\u0445\5\u0105\u0083\2\u0444\u0443\3\2\2\2\u0444\u0445\3"+
|
||||
"\2\2\2\u0445\u0446\3\2\2\2\u0446\u044d\5\u0107\u0084\2\u0447\u0449\7R"+
|
||||
"\2\2\u0448\u044a\5\u0105\u0083\2\u0449\u0448\3\2\2\2\u0449\u044a\3\2\2"+
|
||||
"\2\u044a\u044b\3\2\2\2\u044b\u044d\5\u0107\u0084\2\u044c\u0442\3\2\2\2"+
|
||||
"\u044c\u0447\3\2\2\2\u044d\u010c\3\2\2\2\u044e\u0450\5\u00f1y\2\u044f"+
|
||||
"\u044e\3\2\2\2\u0450\u0451\3\2\2\2\u0451\u044f\3\2\2\2\u0451\u0452\3\2"+
|
||||
"\2\2\u0452\u010e\3\2\2\2\u0453\u0454\t\r\2\2\u0454\u0110\3\2\2\2\u0455"+
|
||||
"\u0456\7)\2\2\u0456\u0457\5\u0113\u008a\2\u0457\u0458\7)\2\2\u0458\u046c"+
|
||||
"\3\2\2\2\u0459\u045a\7N\2\2\u045a\u045b\7)\2\2\u045b\u045c\3\2\2\2\u045c"+
|
||||
"\u045d\5\u0113\u008a\2\u045d\u045e\7)\2\2\u045e\u046c\3\2\2\2\u045f\u0460"+
|
||||
"\7w\2\2\u0460\u0461\7)\2\2\u0461\u0462\3\2\2\2\u0462\u0463\5\u0113\u008a"+
|
||||
"\2\u0463\u0464\7)\2\2\u0464\u046c\3\2\2\2\u0465\u0466\7W\2\2\u0466\u0467"+
|
||||
"\7)\2\2\u0467\u0468\3\2\2\2\u0468\u0469\5\u0113\u008a\2\u0469\u046a\7"+
|
||||
")\2\2\u046a\u046c\3\2\2\2\u046b\u0455\3\2\2\2\u046b\u0459\3\2\2\2\u046b"+
|
||||
"\u045f\3\2\2\2\u046b\u0465\3\2\2\2\u046c\u0112\3\2\2\2\u046d\u046f\5\u0115"+
|
||||
"\u008b\2\u046e\u046d\3\2\2\2\u046f\u0470\3\2\2\2\u0470\u046e\3\2\2\2\u0470"+
|
||||
"\u0471\3\2\2\2\u0471\u0114\3\2\2\2\u0472\u0475\n\16\2\2\u0473\u0475\5"+
|
||||
"\u0117\u008c\2\u0474\u0472\3\2\2\2\u0474\u0473\3\2\2\2\u0475\u0116\3\2"+
|
||||
"\2\2\u0476\u047b\5\u0119\u008d\2\u0477\u047b\5\u011b\u008e\2\u0478\u047b"+
|
||||
"\5\u011d\u008f\2\u0479\u047b\5\u00dbn\2\u047a\u0476\3\2\2\2\u047a\u0477"+
|
||||
"\3\2\2\2\u047a\u0478\3\2\2\2\u047a\u0479\3\2\2\2\u047b\u0118\3\2\2\2\u047c"+
|
||||
"\u047d\7^\2\2\u047d\u047e\t\17\2\2\u047e\u011a\3\2\2\2\u047f\u0480\7^"+
|
||||
"\2\2\u0480\u048b\5\u00efx\2\u0481\u0482\7^\2\2\u0482\u0483\5\u00efx\2"+
|
||||
"\u0483\u0484\5\u00efx\2\u0484\u048b\3\2\2\2\u0485\u0486\7^\2\2\u0486\u0487"+
|
||||
"\5\u00efx\2\u0487\u0488\5\u00efx\2\u0488\u0489\5\u00efx\2\u0489\u048b"+
|
||||
"\3\2\2\2\u048a\u047f\3\2\2\2\u048a\u0481\3\2\2\2\u048a\u0485\3\2\2\2\u048b"+
|
||||
"\u011c\3\2\2\2\u048c\u048d\7^\2\2\u048d\u048e\7z\2\2\u048e\u0490\3\2\2"+
|
||||
"\2\u048f\u0491\5\u00f1y\2\u0490\u048f\3\2\2\2\u0491\u0492\3\2\2\2\u0492"+
|
||||
"\u0490\3\2\2\2\u0492\u0493\3\2\2\2\u0493\u011e\3\2\2\2\u0494\u0496\5\u0121"+
|
||||
"\u0091\2\u0495\u0494\3\2\2\2\u0495\u0496\3\2\2\2\u0496\u0497\3\2\2\2\u0497"+
|
||||
"\u0499\7$\2\2\u0498\u049a\5\u0123\u0092\2\u0499\u0498\3\2\2\2\u0499\u049a"+
|
||||
"\3\2\2\2\u049a\u049b\3\2\2\2\u049b\u049c\7$\2\2\u049c\u0120\3\2\2\2\u049d"+
|
||||
"\u049e\7w\2\2\u049e\u04a1\7:\2\2\u049f\u04a1\t\20\2\2\u04a0\u049d\3\2"+
|
||||
"\2\2\u04a0\u049f\3\2\2\2\u04a1\u0122\3\2\2\2\u04a2\u04a4\5\u0125\u0093"+
|
||||
"\2\u04a3\u04a2\3\2\2\2\u04a4\u04a5\3\2\2\2\u04a5\u04a3\3\2\2\2\u04a5\u04a6"+
|
||||
"\3\2\2\2\u04a6\u0124\3\2\2\2\u04a7\u04af\n\21\2\2\u04a8\u04af\5\u0117"+
|
||||
"\u008c\2\u04a9\u04aa\7^\2\2\u04aa\u04af\7\f\2\2\u04ab\u04ac\7^\2\2\u04ac"+
|
||||
"\u04ad\7\17\2\2\u04ad\u04af\7\f\2\2\u04ae\u04a7\3\2\2\2\u04ae\u04a8\3"+
|
||||
"\2\2\2\u04ae\u04a9\3\2\2\2\u04ae\u04ab\3\2\2\2\u04af\u0126\3\2\2\2\u04b0"+
|
||||
"\u04b2\7%\2\2\u04b1\u04b3\5\u0131\u0099\2\u04b2\u04b1\3\2\2\2\u04b2\u04b3"+
|
||||
"\3\2\2\2\u04b3\u04b4\3\2\2\2\u04b4\u04b5\7f\2\2\u04b5\u04b6\7g\2\2\u04b6"+
|
||||
"\u04b7\7h\2\2\u04b7\u04b8\7k\2\2\u04b8\u04b9\7p\2\2\u04b9\u04ba\7g\2\2"+
|
||||
"\u04ba\u04be\3\2\2\2\u04bb\u04bd\n\22\2\2\u04bc\u04bb\3\2\2\2\u04bd\u04c0"+
|
||||
"\3\2\2\2\u04be\u04bc\3\2\2\2\u04be\u04bf\3\2\2\2\u04bf\u04c1\3\2\2\2\u04c0"+
|
||||
"\u04be\3\2\2\2\u04c1\u04c2\b\u0094\2\2\u04c2\u0128\3\2\2\2\u04c3\u04c4"+
|
||||
"\7c\2\2\u04c4\u04c5\7u\2\2\u04c5\u04c6\7o\2\2\u04c6\u04ca\3\2\2\2\u04c7"+
|
||||
"\u04c9\n\23\2\2\u04c8\u04c7\3\2\2\2\u04c9\u04cc\3\2\2\2\u04ca\u04c8\3"+
|
||||
"\2\2\2\u04ca\u04cb\3\2\2\2\u04cb\u04cd\3\2\2\2\u04cc\u04ca\3\2\2\2\u04cd"+
|
||||
"\u04d1\7}\2\2\u04ce\u04d0\n\24\2\2\u04cf\u04ce\3\2\2\2\u04d0\u04d3\3\2"+
|
||||
"\2\2\u04d1\u04cf\3\2\2\2\u04d1\u04d2\3\2\2\2\u04d2\u04d4\3\2\2\2\u04d3"+
|
||||
"\u04d1\3\2\2\2\u04d4\u04d5\7\177\2\2\u04d5\u04d6\3\2\2\2\u04d6\u04d7\b"+
|
||||
"\u0095\2\2\u04d7\u012a\3\2\2\2\u04d8\u04d9\7%\2\2\u04d9\u04da\7n\2\2\u04da"+
|
||||
"\u04db\7k\2\2\u04db\u04dc\7p\2\2\u04dc\u04dd\7g\2\2\u04dd\u04e1\3\2\2"+
|
||||
"\2\u04de\u04e0\5\u0131\u0099\2\u04df\u04de\3\2\2\2\u04e0\u04e3\3\2\2\2"+
|
||||
"\u04e1\u04df\3\2\2\2\u04e1\u04e2\3\2\2\2\u04e2\u04e7\3\2\2\2\u04e3\u04e1"+
|
||||
"\3\2\2\2\u04e4\u04e6\n\25\2\2\u04e5\u04e4\3\2\2\2\u04e6\u04e9\3\2\2\2"+
|
||||
"\u04e7\u04e5\3\2\2\2\u04e7\u04e8\3\2\2\2\u04e8\u04ea\3\2\2\2\u04e9\u04e7"+
|
||||
"\3\2\2\2\u04ea\u04eb\b\u0096\2\2\u04eb\u012c\3\2\2\2\u04ec\u04ee\7%\2"+
|
||||
"\2\u04ed\u04ef\5\u0131\u0099\2\u04ee\u04ed\3\2\2\2\u04ee\u04ef\3\2\2\2"+
|
||||
"\u04ef\u04f0\3\2\2\2\u04f0\u04f2\5\u00e5s\2\u04f1\u04f3\5\u0131\u0099"+
|
||||
"\2\u04f2\u04f1\3\2\2\2\u04f2\u04f3\3\2\2\2\u04f3\u04f4\3\2\2\2\u04f4\u04f8"+
|
||||
"\5\u011f\u0090\2\u04f5\u04f7\n\25\2\2\u04f6\u04f5\3\2\2\2\u04f7\u04fa"+
|
||||
"\3\2\2\2\u04f8\u04f6\3\2\2\2\u04f8\u04f9\3\2\2\2\u04f9\u04fb\3\2\2\2\u04fa"+
|
||||
"\u04f8\3\2\2\2\u04fb\u04fc\b\u0097\2\2\u04fc\u012e\3\2\2\2\u04fd\u04ff"+
|
||||
"\7%\2\2\u04fe\u0500\5\u0131\u0099\2\u04ff\u04fe\3\2\2\2\u04ff\u0500\3"+
|
||||
"\2\2\2\u0500\u0501\3\2\2\2\u0501\u0502\7r\2\2\u0502\u0503\7t\2\2\u0503"+
|
||||
"\u0504\7c\2\2\u0504\u0505\7i\2\2\u0505\u0506\7o\2\2\u0506\u0507\7c\2\2"+
|
||||
"\u0507\u0508\3\2\2\2\u0508\u050c\5\u0131\u0099\2\u0509\u050b\n\25\2\2"+
|
||||
"\u050a\u0509\3\2\2\2\u050b\u050e\3\2\2\2\u050c\u050a\3\2\2\2\u050c\u050d"+
|
||||
"\3\2\2\2\u050d\u050f\3\2\2\2\u050e\u050c\3\2\2\2\u050f\u0510\b\u0098\2"+
|
||||
"\2\u0510\u0130\3\2\2\2\u0511\u0513\t\26\2\2\u0512\u0511\3\2\2\2\u0513"+
|
||||
"\u0514\3\2\2\2\u0514\u0512\3\2\2\2\u0514\u0515\3\2\2\2\u0515\u0516\3\2"+
|
||||
"\2\2\u0516\u0517\b\u0099\2\2\u0517\u0132\3\2\2\2\u0518\u051a\7\17\2\2"+
|
||||
"\u0519\u051b\7\f\2\2\u051a\u0519\3\2\2\2\u051a\u051b\3\2\2\2\u051b\u051e"+
|
||||
"\3\2\2\2\u051c\u051e\7\f\2\2\u051d\u0518\3\2\2\2\u051d\u051c\3\2\2\2\u051e"+
|
||||
"\u051f\3\2\2\2\u051f\u0520\b\u009a\2\2\u0520\u0134\3\2\2\2\u0521\u0522"+
|
||||
"\7\61\2\2\u0522\u0523\7,\2\2\u0523\u0527\3\2\2\2\u0524\u0526\13\2\2\2"+
|
||||
"\u0525\u0524\3\2\2\2\u0526\u0529\3\2\2\2\u0527\u0528\3\2\2\2\u0527\u0525"+
|
||||
"\3\2\2\2\u0528\u052a\3\2\2\2\u0529\u0527\3\2\2\2\u052a\u052b\7,\2\2\u052b"+
|
||||
"\u052c\7\61\2\2\u052c\u052d\3\2\2\2\u052d\u052e\b\u009b\2\2\u052e\u0136"+
|
||||
"\3\2\2\2\u052f\u0530\7\61\2\2\u0530\u0531\7\61\2\2\u0531\u0535\3\2\2\2"+
|
||||
"\u0532\u0534\n\25\2\2\u0533\u0532\3\2\2\2\u0534\u0537\3\2\2\2\u0535\u0533"+
|
||||
"\3\2\2\2\u0535\u0536\3\2\2\2\u0536\u0538\3\2\2\2\u0537\u0535\3\2\2\2\u0538"+
|
||||
"\u0539\b\u009c\2\2\u0539\u0138\3\2\2\2\u053a\u053e\7%\2\2\u053b\u053d"+
|
||||
"\n\25\2\2\u053c\u053b\3\2\2\2\u053d\u0540\3\2\2\2\u053e\u053c\3\2\2\2"+
|
||||
"\u053e\u053f\3\2\2\2\u053f\u0541\3\2\2\2\u0540\u053e\3\2\2\2\u0541\u0542"+
|
||||
"\b\u009d\2\2\u0542\u013a\3\2\2\2E\2\u038a\u038c\u0391\u03a1\u03ab\u03af"+
|
||||
"\u03b3\u03b7\u03ba\u03c1\u03c7\u03ce\u03d5\u03e2\u03e9\u03ed\u03ef\u03f9"+
|
||||
"\u03fd\u0401\u0404\u0409\u040b\u0411\u0417\u0419\u041c\u0423\u0427\u042c"+
|
||||
"\u042f\u0436\u0439\u0440\u0444\u0449\u044c\u0451\u046b\u0470\u0474\u047a"+
|
||||
"\u048a\u0492\u0495\u0499\u04a0\u04a5\u04ae\u04b2\u04be\u04ca\u04d1\u04e1"+
|
||||
"\u04e7\u04ee\u04f2\u04f8\u04ff\u050c\u0514\u051a\u051d\u0527\u0535\u053e"+
|
||||
"\3\b\2\2";
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,221 @@
|
|||
Enum=25
|
||||
AndAssign=97
|
||||
Or=79
|
||||
Break=16
|
||||
LeftShift=69
|
||||
GreaterEqual=68
|
||||
Bool=52
|
||||
ThreadLocal=58
|
||||
LeftBracket=61
|
||||
RightBrace=64
|
||||
Equal=100
|
||||
Directives=117
|
||||
Restrict=35
|
||||
Sizeof=39
|
||||
StarAssign=90
|
||||
Arrow=102
|
||||
NotEqual=101
|
||||
LessEqual=66
|
||||
Dot=103
|
||||
RightParen=60
|
||||
XorAssign=98
|
||||
Float=27
|
||||
Switch=42
|
||||
Typedef=43
|
||||
StringLiteral=107
|
||||
If=30
|
||||
Minus=73
|
||||
MinusAssign=94
|
||||
LeftParen=59
|
||||
Newline=114
|
||||
Union=44
|
||||
Case=17
|
||||
Extern=26
|
||||
Complex=53
|
||||
RightShiftAssign=96
|
||||
Comma=88
|
||||
Star=75
|
||||
Char=18
|
||||
ComplexDefine=108
|
||||
T__3=11
|
||||
T__2=12
|
||||
T__1=13
|
||||
Question=85
|
||||
T__0=14
|
||||
OrOr=81
|
||||
LineAfterPreprocessing=110
|
||||
Inline=31
|
||||
Default=21
|
||||
Alignas=49
|
||||
Div=76
|
||||
RightBracket=62
|
||||
Register=34
|
||||
Else=24
|
||||
Assign=89
|
||||
AndAnd=80
|
||||
LineDirective=111
|
||||
LineComment=116
|
||||
RightShift=70
|
||||
LeftShiftAssign=95
|
||||
Identifier=105
|
||||
T__11=3
|
||||
T__12=2
|
||||
T__13=1
|
||||
Void=46
|
||||
Plus=71
|
||||
AsmBlock=109
|
||||
StaticAssert=57
|
||||
Less=65
|
||||
Short=37
|
||||
T__10=4
|
||||
BlockComment=115
|
||||
T__9=5
|
||||
Goto=29
|
||||
T__8=6
|
||||
T__7=7
|
||||
T__6=8
|
||||
T__5=9
|
||||
Signed=38
|
||||
T__4=10
|
||||
Const=19
|
||||
Imaginary=55
|
||||
For=28
|
||||
Semi=87
|
||||
OrAssign=99
|
||||
Do=22
|
||||
Double=23
|
||||
Not=83
|
||||
And=78
|
||||
Long=33
|
||||
Static=40
|
||||
Caret=82
|
||||
Alignof=50
|
||||
Generic=54
|
||||
Constant=106
|
||||
Atomic=51
|
||||
Continue=20
|
||||
Int=32
|
||||
MinusMinus=74
|
||||
Whitespace=113
|
||||
Struct=41
|
||||
Auto=15
|
||||
PlusPlus=72
|
||||
PlusAssign=93
|
||||
Colon=86
|
||||
DivAssign=91
|
||||
LeftBrace=63
|
||||
Return=36
|
||||
Mod=77
|
||||
Ellipsis=104
|
||||
Tilde=84
|
||||
PragmaDirective=112
|
||||
While=48
|
||||
Noreturn=56
|
||||
Volatile=47
|
||||
ModAssign=92
|
||||
Unsigned=45
|
||||
Greater=67
|
||||
'-'=73
|
||||
'typedef'=43
|
||||
'else'=24
|
||||
'_Static_assert'=57
|
||||
'%'=77
|
||||
'__builtin_offsetof'=14
|
||||
'>'=67
|
||||
'--'=74
|
||||
'=='=100
|
||||
'_Complex'=53
|
||||
'...'=104
|
||||
'case'=17
|
||||
'->'=102
|
||||
'.'=103
|
||||
'_Thread_local'=58
|
||||
'__m128'=13
|
||||
'&'=78
|
||||
'__inline__'=12
|
||||
'double'=23
|
||||
'break'=16
|
||||
'short'=37
|
||||
'<='=66
|
||||
'enum'=25
|
||||
'?'=85
|
||||
'__attribute__'=11
|
||||
'if'=30
|
||||
'_Generic'=54
|
||||
'goto'=29
|
||||
'<<'=69
|
||||
'inline'=31
|
||||
'||'=81
|
||||
'return'=36
|
||||
'__m128i'=10
|
||||
'_Imaginary'=55
|
||||
'unsigned'=45
|
||||
'continue'=20
|
||||
'/'=76
|
||||
'_Bool'=52
|
||||
'__m128d'=9
|
||||
'signed'=38
|
||||
'__asm'=8
|
||||
'register'=34
|
||||
'sizeof'=39
|
||||
'static'=40
|
||||
'__typeof__'=7
|
||||
'++'=72
|
||||
'__builtin_va_arg'=6
|
||||
'const'=19
|
||||
'volatile'=47
|
||||
'/='=91
|
||||
'__declspec'=5
|
||||
'do'=22
|
||||
'('=59
|
||||
'|='=99
|
||||
'for'=28
|
||||
'void'=46
|
||||
'{'=63
|
||||
'float'=27
|
||||
'+='=93
|
||||
')'=60
|
||||
'__asm__'=4
|
||||
'auto'=15
|
||||
'!'=83
|
||||
'|'=79
|
||||
'['=61
|
||||
':'=86
|
||||
'_Atomic'=51
|
||||
'*'=75
|
||||
'switch'=42
|
||||
'_Alignas'=49
|
||||
'_Alignof'=50
|
||||
'__stdcall'=3
|
||||
'}'=64
|
||||
';'=87
|
||||
'>>='=96
|
||||
'&='=97
|
||||
'*='=90
|
||||
'struct'=41
|
||||
'+'=71
|
||||
'~'=84
|
||||
']'=62
|
||||
'<'=65
|
||||
'_Noreturn'=56
|
||||
'>='=68
|
||||
'long'=33
|
||||
','=88
|
||||
'-='=94
|
||||
'union'=44
|
||||
'int'=32
|
||||
'__volatile__'=2
|
||||
'^'=82
|
||||
'<<='=95
|
||||
'='=89
|
||||
'restrict'=35
|
||||
'>>'=70
|
||||
'&&'=80
|
||||
'^='=98
|
||||
'while'=48
|
||||
'!='=101
|
||||
'__extension__'=1
|
||||
'char'=18
|
||||
'%='=92
|
||||
'extern'=26
|
||||
'default'=21
|
|
@ -0,0 +1,852 @@
|
|||
// Generated from C.g4 by ANTLR 4.4
|
||||
package it.unitn.repoman.core.lang.parsers.c;
|
||||
|
||||
import org.antlr.v4.runtime.misc.NotNull;
|
||||
import org.antlr.v4.runtime.tree.ParseTreeListener;
|
||||
|
||||
/**
|
||||
* This interface defines a complete listener for a parse tree produced by
|
||||
* {@link CParser}.
|
||||
*/
|
||||
public interface CListener extends ParseTreeListener {
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#structDeclarationList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStructDeclarationList(@NotNull CParser.StructDeclarationListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#structDeclarationList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStructDeclarationList(@NotNull CParser.StructDeclarationListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#unaryOperator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterUnaryOperator(@NotNull CParser.UnaryOperatorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#unaryOperator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitUnaryOperator(@NotNull CParser.UnaryOperatorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#structOrUnionSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStructOrUnionSpecifier(@NotNull CParser.StructOrUnionSpecifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#structOrUnionSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStructOrUnionSpecifier(@NotNull CParser.StructOrUnionSpecifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#assignmentOperator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterAssignmentOperator(@NotNull CParser.AssignmentOperatorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#assignmentOperator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitAssignmentOperator(@NotNull CParser.AssignmentOperatorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#compoundStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterCompoundStatement(@NotNull CParser.CompoundStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#compoundStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitCompoundStatement(@NotNull CParser.CompoundStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#declarationSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDeclarationSpecifier(@NotNull CParser.DeclarationSpecifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#declarationSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDeclarationSpecifier(@NotNull CParser.DeclarationSpecifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#declarationList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDeclarationList(@NotNull CParser.DeclarationListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#declarationList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDeclarationList(@NotNull CParser.DeclarationListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#directDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDirectDeclarator(@NotNull CParser.DirectDeclaratorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#directDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDirectDeclarator(@NotNull CParser.DirectDeclaratorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#parameterTypeList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterParameterTypeList(@NotNull CParser.ParameterTypeListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#parameterTypeList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitParameterTypeList(@NotNull CParser.ParameterTypeListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#designatorList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDesignatorList(@NotNull CParser.DesignatorListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#designatorList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDesignatorList(@NotNull CParser.DesignatorListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#functionSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterFunctionSpecifier(@NotNull CParser.FunctionSpecifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#functionSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitFunctionSpecifier(@NotNull CParser.FunctionSpecifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#staticAssertDeclaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStaticAssertDeclaration(@NotNull CParser.StaticAssertDeclarationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#staticAssertDeclaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStaticAssertDeclaration(@NotNull CParser.StaticAssertDeclarationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#castExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterCastExpression(@NotNull CParser.CastExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#castExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitCastExpression(@NotNull CParser.CastExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#initDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterInitDeclarator(@NotNull CParser.InitDeclaratorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#initDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitInitDeclarator(@NotNull CParser.InitDeclaratorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#declarationSpecifiers2}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDeclarationSpecifiers2(@NotNull CParser.DeclarationSpecifiers2Context ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#declarationSpecifiers2}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDeclarationSpecifiers2(@NotNull CParser.DeclarationSpecifiers2Context ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#externalDeclaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterExternalDeclaration(@NotNull CParser.ExternalDeclarationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#externalDeclaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitExternalDeclaration(@NotNull CParser.ExternalDeclarationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#logicalAndExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLogicalAndExpression(@NotNull CParser.LogicalAndExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#logicalAndExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLogicalAndExpression(@NotNull CParser.LogicalAndExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#gccAttributeList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGccAttributeList(@NotNull CParser.GccAttributeListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#gccAttributeList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGccAttributeList(@NotNull CParser.GccAttributeListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#expressionStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterExpressionStatement(@NotNull CParser.ExpressionStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#expressionStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitExpressionStatement(@NotNull CParser.ExpressionStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#unaryExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterUnaryExpression(@NotNull CParser.UnaryExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#unaryExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitUnaryExpression(@NotNull CParser.UnaryExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#typedefName}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypedefName(@NotNull CParser.TypedefNameContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#typedefName}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypedefName(@NotNull CParser.TypedefNameContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#pointer}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterPointer(@NotNull CParser.PointerContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#pointer}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitPointer(@NotNull CParser.PointerContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#identifierList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterIdentifierList(@NotNull CParser.IdentifierListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#identifierList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitIdentifierList(@NotNull CParser.IdentifierListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#shiftExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterShiftExpression(@NotNull CParser.ShiftExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#shiftExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitShiftExpression(@NotNull CParser.ShiftExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#atomicTypeSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterAtomicTypeSpecifier(@NotNull CParser.AtomicTypeSpecifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#atomicTypeSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitAtomicTypeSpecifier(@NotNull CParser.AtomicTypeSpecifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#iterationStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterIterationStatement(@NotNull CParser.IterationStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#iterationStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitIterationStatement(@NotNull CParser.IterationStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#enumerationConstant}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterEnumerationConstant(@NotNull CParser.EnumerationConstantContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#enumerationConstant}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitEnumerationConstant(@NotNull CParser.EnumerationConstantContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#inclusiveOrExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterInclusiveOrExpression(@NotNull CParser.InclusiveOrExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#inclusiveOrExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitInclusiveOrExpression(@NotNull CParser.InclusiveOrExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#assignmentExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterAssignmentExpression(@NotNull CParser.AssignmentExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#assignmentExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitAssignmentExpression(@NotNull CParser.AssignmentExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#directAbstractDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDirectAbstractDeclarator(@NotNull CParser.DirectAbstractDeclaratorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#directAbstractDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDirectAbstractDeclarator(@NotNull CParser.DirectAbstractDeclaratorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#declarationSpecifiers}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDeclarationSpecifiers(@NotNull CParser.DeclarationSpecifiersContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#declarationSpecifiers}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDeclarationSpecifiers(@NotNull CParser.DeclarationSpecifiersContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#alignmentSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterAlignmentSpecifier(@NotNull CParser.AlignmentSpecifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#alignmentSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitAlignmentSpecifier(@NotNull CParser.AlignmentSpecifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#structOrUnion}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStructOrUnion(@NotNull CParser.StructOrUnionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#structOrUnion}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStructOrUnion(@NotNull CParser.StructOrUnionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#translationUnit}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTranslationUnit(@NotNull CParser.TranslationUnitContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#translationUnit}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTranslationUnit(@NotNull CParser.TranslationUnitContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#compilationUnit}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterCompilationUnit(@NotNull CParser.CompilationUnitContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#compilationUnit}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitCompilationUnit(@NotNull CParser.CompilationUnitContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#blockItemList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterBlockItemList(@NotNull CParser.BlockItemListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#blockItemList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitBlockItemList(@NotNull CParser.BlockItemListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#exclusiveOrExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterExclusiveOrExpression(@NotNull CParser.ExclusiveOrExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#exclusiveOrExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitExclusiveOrExpression(@NotNull CParser.ExclusiveOrExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#genericAssocList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGenericAssocList(@NotNull CParser.GenericAssocListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#genericAssocList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGenericAssocList(@NotNull CParser.GenericAssocListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#equalityExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterEqualityExpression(@NotNull CParser.EqualityExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#equalityExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitEqualityExpression(@NotNull CParser.EqualityExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#parameterList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterParameterList(@NotNull CParser.ParameterListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#parameterList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitParameterList(@NotNull CParser.ParameterListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#parameterDeclaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterParameterDeclaration(@NotNull CParser.ParameterDeclarationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#parameterDeclaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitParameterDeclaration(@NotNull CParser.ParameterDeclarationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#designation}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDesignation(@NotNull CParser.DesignationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#designation}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDesignation(@NotNull CParser.DesignationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#blockItem}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterBlockItem(@NotNull CParser.BlockItemContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#blockItem}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitBlockItem(@NotNull CParser.BlockItemContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#initDeclaratorList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterInitDeclaratorList(@NotNull CParser.InitDeclaratorListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#initDeclaratorList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitInitDeclaratorList(@NotNull CParser.InitDeclaratorListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#structDeclaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStructDeclaration(@NotNull CParser.StructDeclarationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#structDeclaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStructDeclaration(@NotNull CParser.StructDeclarationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#structDeclaratorList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStructDeclaratorList(@NotNull CParser.StructDeclaratorListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#structDeclaratorList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStructDeclaratorList(@NotNull CParser.StructDeclaratorListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#additiveExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterAdditiveExpression(@NotNull CParser.AdditiveExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#additiveExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitAdditiveExpression(@NotNull CParser.AdditiveExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#relationalExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterRelationalExpression(@NotNull CParser.RelationalExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#relationalExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitRelationalExpression(@NotNull CParser.RelationalExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#enumeratorList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterEnumeratorList(@NotNull CParser.EnumeratorListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#enumeratorList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitEnumeratorList(@NotNull CParser.EnumeratorListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#typeName}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeName(@NotNull CParser.TypeNameContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#typeName}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeName(@NotNull CParser.TypeNameContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#selectionStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterSelectionStatement(@NotNull CParser.SelectionStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#selectionStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitSelectionStatement(@NotNull CParser.SelectionStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#genericSelection}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGenericSelection(@NotNull CParser.GenericSelectionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#genericSelection}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGenericSelection(@NotNull CParser.GenericSelectionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#storageClassSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStorageClassSpecifier(@NotNull CParser.StorageClassSpecifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#storageClassSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStorageClassSpecifier(@NotNull CParser.StorageClassSpecifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#nestedParenthesesBlock}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterNestedParenthesesBlock(@NotNull CParser.NestedParenthesesBlockContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#nestedParenthesesBlock}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitNestedParenthesesBlock(@NotNull CParser.NestedParenthesesBlockContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#designator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDesignator(@NotNull CParser.DesignatorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#designator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDesignator(@NotNull CParser.DesignatorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#andExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterAndExpression(@NotNull CParser.AndExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#andExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitAndExpression(@NotNull CParser.AndExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#labeledStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLabeledStatement(@NotNull CParser.LabeledStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#labeledStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLabeledStatement(@NotNull CParser.LabeledStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#argumentExpressionList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterArgumentExpressionList(@NotNull CParser.ArgumentExpressionListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#argumentExpressionList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitArgumentExpressionList(@NotNull CParser.ArgumentExpressionListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#gccAttributeSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGccAttributeSpecifier(@NotNull CParser.GccAttributeSpecifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#gccAttributeSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGccAttributeSpecifier(@NotNull CParser.GccAttributeSpecifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#statement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStatement(@NotNull CParser.StatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#statement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStatement(@NotNull CParser.StatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#enumerator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterEnumerator(@NotNull CParser.EnumeratorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#enumerator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitEnumerator(@NotNull CParser.EnumeratorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#abstractDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterAbstractDeclarator(@NotNull CParser.AbstractDeclaratorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#abstractDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitAbstractDeclarator(@NotNull CParser.AbstractDeclaratorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#postfixExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterPostfixExpression(@NotNull CParser.PostfixExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#postfixExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitPostfixExpression(@NotNull CParser.PostfixExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#gccAttribute}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGccAttribute(@NotNull CParser.GccAttributeContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#gccAttribute}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGccAttribute(@NotNull CParser.GccAttributeContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#primaryExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterPrimaryExpression(@NotNull CParser.PrimaryExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#primaryExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitPrimaryExpression(@NotNull CParser.PrimaryExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#typeQualifierList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeQualifierList(@NotNull CParser.TypeQualifierListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#typeQualifierList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeQualifierList(@NotNull CParser.TypeQualifierListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterExpression(@NotNull CParser.ExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#expression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitExpression(@NotNull CParser.ExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#constantExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterConstantExpression(@NotNull CParser.ConstantExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#constantExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitConstantExpression(@NotNull CParser.ConstantExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#conditionalExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterConditionalExpression(@NotNull CParser.ConditionalExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#conditionalExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitConditionalExpression(@NotNull CParser.ConditionalExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#functionDefinition}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterFunctionDefinition(@NotNull CParser.FunctionDefinitionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#functionDefinition}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitFunctionDefinition(@NotNull CParser.FunctionDefinitionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#specifierQualifierList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterSpecifierQualifierList(@NotNull CParser.SpecifierQualifierListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#specifierQualifierList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitSpecifierQualifierList(@NotNull CParser.SpecifierQualifierListContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#gccDeclaratorExtension}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGccDeclaratorExtension(@NotNull CParser.GccDeclaratorExtensionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#gccDeclaratorExtension}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGccDeclaratorExtension(@NotNull CParser.GccDeclaratorExtensionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#typeSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeSpecifier(@NotNull CParser.TypeSpecifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#typeSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeSpecifier(@NotNull CParser.TypeSpecifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#multiplicativeExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterMultiplicativeExpression(@NotNull CParser.MultiplicativeExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#multiplicativeExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitMultiplicativeExpression(@NotNull CParser.MultiplicativeExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#logicalOrExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterLogicalOrExpression(@NotNull CParser.LogicalOrExpressionContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#logicalOrExpression}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitLogicalOrExpression(@NotNull CParser.LogicalOrExpressionContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDeclaration(@NotNull CParser.DeclarationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#declaration}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDeclaration(@NotNull CParser.DeclarationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#declarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterDeclarator(@NotNull CParser.DeclaratorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#declarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitDeclarator(@NotNull CParser.DeclaratorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#initializer}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterInitializer(@NotNull CParser.InitializerContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#initializer}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitInitializer(@NotNull CParser.InitializerContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#genericAssociation}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterGenericAssociation(@NotNull CParser.GenericAssociationContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#genericAssociation}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitGenericAssociation(@NotNull CParser.GenericAssociationContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#structDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterStructDeclarator(@NotNull CParser.StructDeclaratorContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#structDeclarator}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitStructDeclarator(@NotNull CParser.StructDeclaratorContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#enumSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterEnumSpecifier(@NotNull CParser.EnumSpecifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#enumSpecifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitEnumSpecifier(@NotNull CParser.EnumSpecifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#jumpStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterJumpStatement(@NotNull CParser.JumpStatementContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#jumpStatement}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitJumpStatement(@NotNull CParser.JumpStatementContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#typeQualifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterTypeQualifier(@NotNull CParser.TypeQualifierContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#typeQualifier}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitTypeQualifier(@NotNull CParser.TypeQualifierContext ctx);
|
||||
/**
|
||||
* Enter a parse tree produced by {@link CParser#initializerList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void enterInitializerList(@NotNull CParser.InitializerListContext ctx);
|
||||
/**
|
||||
* Exit a parse tree produced by {@link CParser#initializerList}.
|
||||
* @param ctx the parse tree
|
||||
*/
|
||||
void exitInitializerList(@NotNull CParser.InitializerListContext ctx);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,201 @@
|
|||
ABSTRACT=1
|
||||
ASSERT=2
|
||||
BOOLEAN=3
|
||||
BREAK=4
|
||||
BYTE=5
|
||||
CASE=6
|
||||
CATCH=7
|
||||
CHAR=8
|
||||
CLASS=9
|
||||
CONST=10
|
||||
CONTINUE=11
|
||||
DEFAULT=12
|
||||
DO=13
|
||||
DOUBLE=14
|
||||
ELSE=15
|
||||
ENUM=16
|
||||
EXTENDS=17
|
||||
FINAL=18
|
||||
FINALLY=19
|
||||
FLOAT=20
|
||||
FOR=21
|
||||
IF=22
|
||||
GOTO=23
|
||||
IMPLEMENTS=24
|
||||
IMPORT=25
|
||||
INSTANCEOF=26
|
||||
INT=27
|
||||
INTERFACE=28
|
||||
LONG=29
|
||||
NATIVE=30
|
||||
NEW=31
|
||||
PACKAGE=32
|
||||
PRIVATE=33
|
||||
PROTECTED=34
|
||||
PUBLIC=35
|
||||
RETURN=36
|
||||
SHORT=37
|
||||
STATIC=38
|
||||
STRICTFP=39
|
||||
SUPER=40
|
||||
SWITCH=41
|
||||
SYNCHRONIZED=42
|
||||
THIS=43
|
||||
THROW=44
|
||||
THROWS=45
|
||||
TRANSIENT=46
|
||||
TRY=47
|
||||
VOID=48
|
||||
VOLATILE=49
|
||||
WHILE=50
|
||||
IntegerLiteral=51
|
||||
FloatingPointLiteral=52
|
||||
BooleanLiteral=53
|
||||
CharacterLiteral=54
|
||||
StringLiteral=55
|
||||
NullLiteral=56
|
||||
LPAREN=57
|
||||
RPAREN=58
|
||||
LBRACE=59
|
||||
RBRACE=60
|
||||
LBRACK=61
|
||||
RBRACK=62
|
||||
SEMI=63
|
||||
COMMA=64
|
||||
DOT=65
|
||||
ASSIGN=66
|
||||
GT=67
|
||||
LT=68
|
||||
BANG=69
|
||||
TILDE=70
|
||||
QUESTION=71
|
||||
COLON=72
|
||||
EQUAL=73
|
||||
LE=74
|
||||
GE=75
|
||||
NOTEQUAL=76
|
||||
AND=77
|
||||
OR=78
|
||||
INC=79
|
||||
DEC=80
|
||||
ADD=81
|
||||
SUB=82
|
||||
MUL=83
|
||||
DIV=84
|
||||
BITAND=85
|
||||
BITOR=86
|
||||
CARET=87
|
||||
MOD=88
|
||||
ADD_ASSIGN=89
|
||||
SUB_ASSIGN=90
|
||||
MUL_ASSIGN=91
|
||||
DIV_ASSIGN=92
|
||||
AND_ASSIGN=93
|
||||
OR_ASSIGN=94
|
||||
XOR_ASSIGN=95
|
||||
MOD_ASSIGN=96
|
||||
LSHIFT_ASSIGN=97
|
||||
RSHIFT_ASSIGN=98
|
||||
URSHIFT_ASSIGN=99
|
||||
Identifier=100
|
||||
AT=101
|
||||
ELLIPSIS=102
|
||||
WS=103
|
||||
COMMENT=104
|
||||
LINE_COMMENT=105
|
||||
'abstract'=1
|
||||
'assert'=2
|
||||
'boolean'=3
|
||||
'break'=4
|
||||
'byte'=5
|
||||
'case'=6
|
||||
'catch'=7
|
||||
'char'=8
|
||||
'class'=9
|
||||
'const'=10
|
||||
'continue'=11
|
||||
'default'=12
|
||||
'do'=13
|
||||
'double'=14
|
||||
'else'=15
|
||||
'enum'=16
|
||||
'extends'=17
|
||||
'final'=18
|
||||
'finally'=19
|
||||
'float'=20
|
||||
'for'=21
|
||||
'if'=22
|
||||
'goto'=23
|
||||
'implements'=24
|
||||
'import'=25
|
||||
'instanceof'=26
|
||||
'int'=27
|
||||
'interface'=28
|
||||
'long'=29
|
||||
'native'=30
|
||||
'new'=31
|
||||
'package'=32
|
||||
'private'=33
|
||||
'protected'=34
|
||||
'public'=35
|
||||
'return'=36
|
||||
'short'=37
|
||||
'static'=38
|
||||
'strictfp'=39
|
||||
'super'=40
|
||||
'switch'=41
|
||||
'synchronized'=42
|
||||
'this'=43
|
||||
'throw'=44
|
||||
'throws'=45
|
||||
'transient'=46
|
||||
'try'=47
|
||||
'void'=48
|
||||
'volatile'=49
|
||||
'while'=50
|
||||
'null'=56
|
||||
'('=57
|
||||
')'=58
|
||||
'{'=59
|
||||
'}'=60
|
||||
'['=61
|
||||
']'=62
|
||||
';'=63
|
||||
','=64
|
||||
'.'=65
|
||||
'='=66
|
||||
'>'=67
|
||||
'<'=68
|
||||
'!'=69
|
||||
'~'=70
|
||||
'?'=71
|
||||
':'=72
|
||||
'=='=73
|
||||
'<='=74
|
||||
'>='=75
|
||||
'!='=76
|
||||
'&&'=77
|
||||
'||'=78
|
||||
'++'=79
|
||||
'--'=80
|
||||
'+'=81
|
||||
'-'=82
|
||||
'*'=83
|
||||
'/'=84
|
||||
'&'=85
|
||||
'|'=86
|
||||
'^'=87
|
||||
'%'=88
|
||||
'+='=89
|
||||
'-='=90
|
||||
'*='=91
|
||||
'/='=92
|
||||
'&='=93
|
||||
'|='=94
|
||||
'^='=95
|
||||
'%='=96
|
||||
'<<='=97
|
||||
'>>='=98
|
||||
'>>>='=99
|
||||
'@'=101
|
||||
'...'=102
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,545 @@
|
|||
// Generated from Java.g4 by ANTLR 4.7
|
||||
package it.unitn.repoman.core.lang.parsers.java;
|
||||
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
|
||||
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
|
||||
public class JavaLexer extends Lexer {
|
||||
static { RuntimeMetaData.checkVersion("4.7", RuntimeMetaData.VERSION); }
|
||||
|
||||
protected static final DFA[] _decisionToDFA;
|
||||
protected static final PredictionContextCache _sharedContextCache =
|
||||
new PredictionContextCache();
|
||||
public static final int
|
||||
ABSTRACT=1, ASSERT=2, BOOLEAN=3, BREAK=4, BYTE=5, CASE=6, CATCH=7, CHAR=8,
|
||||
CLASS=9, CONST=10, CONTINUE=11, DEFAULT=12, DO=13, DOUBLE=14, ELSE=15,
|
||||
ENUM=16, EXTENDS=17, FINAL=18, FINALLY=19, FLOAT=20, FOR=21, IF=22, GOTO=23,
|
||||
IMPLEMENTS=24, IMPORT=25, INSTANCEOF=26, INT=27, INTERFACE=28, LONG=29,
|
||||
NATIVE=30, NEW=31, PACKAGE=32, PRIVATE=33, PROTECTED=34, PUBLIC=35, RETURN=36,
|
||||
SHORT=37, STATIC=38, STRICTFP=39, SUPER=40, SWITCH=41, SYNCHRONIZED=42,
|
||||
THIS=43, THROW=44, THROWS=45, TRANSIENT=46, TRY=47, VOID=48, VOLATILE=49,
|
||||
WHILE=50, IntegerLiteral=51, FloatingPointLiteral=52, BooleanLiteral=53,
|
||||
CharacterLiteral=54, StringLiteral=55, NullLiteral=56, LPAREN=57, RPAREN=58,
|
||||
LBRACE=59, RBRACE=60, LBRACK=61, RBRACK=62, SEMI=63, COMMA=64, DOT=65,
|
||||
ASSIGN=66, GT=67, LT=68, BANG=69, TILDE=70, QUESTION=71, COLON=72, EQUAL=73,
|
||||
LE=74, GE=75, NOTEQUAL=76, AND=77, OR=78, INC=79, DEC=80, ADD=81, SUB=82,
|
||||
MUL=83, DIV=84, BITAND=85, BITOR=86, CARET=87, MOD=88, ADD_ASSIGN=89,
|
||||
SUB_ASSIGN=90, MUL_ASSIGN=91, DIV_ASSIGN=92, AND_ASSIGN=93, OR_ASSIGN=94,
|
||||
XOR_ASSIGN=95, MOD_ASSIGN=96, LSHIFT_ASSIGN=97, RSHIFT_ASSIGN=98, URSHIFT_ASSIGN=99,
|
||||
Identifier=100, AT=101, ELLIPSIS=102, WS=103, COMMENT=104, LINE_COMMENT=105;
|
||||
public static String[] channelNames = {
|
||||
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
|
||||
};
|
||||
|
||||
public static String[] modeNames = {
|
||||
"DEFAULT_MODE"
|
||||
};
|
||||
|
||||
public static final String[] ruleNames = {
|
||||
"ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH", "CHAR",
|
||||
"CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE", "ENUM",
|
||||
"EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "IF", "GOTO", "IMPLEMENTS",
|
||||
"IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE", "NEW", "PACKAGE",
|
||||
"PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT", "STATIC", "STRICTFP",
|
||||
"SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS", "TRANSIENT",
|
||||
"TRY", "VOID", "VOLATILE", "WHILE", "IntegerLiteral", "DecimalIntegerLiteral",
|
||||
"HexIntegerLiteral", "OctalIntegerLiteral", "BinaryIntegerLiteral", "IntegerTypeSuffix",
|
||||
"DecimalNumeral", "Digits", "Digit", "NonZeroDigit", "DigitOrUnderscore",
|
||||
"Underscores", "HexNumeral", "HexDigits", "HexDigit", "HexDigitOrUnderscore",
|
||||
"OctalNumeral", "OctalDigits", "OctalDigit", "OctalDigitOrUnderscore",
|
||||
"BinaryNumeral", "BinaryDigits", "BinaryDigit", "BinaryDigitOrUnderscore",
|
||||
"FloatingPointLiteral", "DecimalFloatingPointLiteral", "ExponentPart",
|
||||
"ExponentIndicator", "SignedInteger", "Sign", "FloatTypeSuffix", "HexadecimalFloatingPointLiteral",
|
||||
"HexSignificand", "BinaryExponent", "BinaryExponentIndicator", "BooleanLiteral",
|
||||
"CharacterLiteral", "SingleCharacter", "StringLiteral", "StringCharacters",
|
||||
"StringCharacter", "EscapeSequence", "OctalEscape", "UnicodeEscape", "ZeroToThree",
|
||||
"NullLiteral", "LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK",
|
||||
"SEMI", "COMMA", "DOT", "ASSIGN", "GT", "LT", "BANG", "TILDE", "QUESTION",
|
||||
"COLON", "EQUAL", "LE", "GE", "NOTEQUAL", "AND", "OR", "INC", "DEC", "ADD",
|
||||
"SUB", "MUL", "DIV", "BITAND", "BITOR", "CARET", "MOD", "ADD_ASSIGN",
|
||||
"SUB_ASSIGN", "MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN",
|
||||
"MOD_ASSIGN", "LSHIFT_ASSIGN", "RSHIFT_ASSIGN", "URSHIFT_ASSIGN", "Identifier",
|
||||
"JavaLetter", "JavaLetterOrDigit", "AT", "ELLIPSIS", "WS", "COMMENT",
|
||||
"LINE_COMMENT"
|
||||
};
|
||||
|
||||
private static final String[] _LITERAL_NAMES = {
|
||||
null, "'abstract'", "'assert'", "'boolean'", "'break'", "'byte'", "'case'",
|
||||
"'catch'", "'char'", "'class'", "'const'", "'continue'", "'default'",
|
||||
"'do'", "'double'", "'else'", "'enum'", "'extends'", "'final'", "'finally'",
|
||||
"'float'", "'for'", "'if'", "'goto'", "'implements'", "'import'", "'instanceof'",
|
||||
"'int'", "'interface'", "'long'", "'native'", "'new'", "'package'", "'private'",
|
||||
"'protected'", "'public'", "'return'", "'short'", "'static'", "'strictfp'",
|
||||
"'super'", "'switch'", "'synchronized'", "'this'", "'throw'", "'throws'",
|
||||
"'transient'", "'try'", "'void'", "'volatile'", "'while'", null, null,
|
||||
null, null, null, "'null'", "'('", "')'", "'{'", "'}'", "'['", "']'",
|
||||
"';'", "','", "'.'", "'='", "'>'", "'<'", "'!'", "'~'", "'?'", "':'",
|
||||
"'=='", "'<='", "'>='", "'!='", "'&&'", "'||'", "'++'", "'--'", "'+'",
|
||||
"'-'", "'*'", "'/'", "'&'", "'|'", "'^'", "'%'", "'+='", "'-='", "'*='",
|
||||
"'/='", "'&='", "'|='", "'^='", "'%='", "'<<='", "'>>='", "'>>>='", null,
|
||||
"'@'", "'...'"
|
||||
};
|
||||
private static final String[] _SYMBOLIC_NAMES = {
|
||||
null, "ABSTRACT", "ASSERT", "BOOLEAN", "BREAK", "BYTE", "CASE", "CATCH",
|
||||
"CHAR", "CLASS", "CONST", "CONTINUE", "DEFAULT", "DO", "DOUBLE", "ELSE",
|
||||
"ENUM", "EXTENDS", "FINAL", "FINALLY", "FLOAT", "FOR", "IF", "GOTO", "IMPLEMENTS",
|
||||
"IMPORT", "INSTANCEOF", "INT", "INTERFACE", "LONG", "NATIVE", "NEW", "PACKAGE",
|
||||
"PRIVATE", "PROTECTED", "PUBLIC", "RETURN", "SHORT", "STATIC", "STRICTFP",
|
||||
"SUPER", "SWITCH", "SYNCHRONIZED", "THIS", "THROW", "THROWS", "TRANSIENT",
|
||||
"TRY", "VOID", "VOLATILE", "WHILE", "IntegerLiteral", "FloatingPointLiteral",
|
||||
"BooleanLiteral", "CharacterLiteral", "StringLiteral", "NullLiteral",
|
||||
"LPAREN", "RPAREN", "LBRACE", "RBRACE", "LBRACK", "RBRACK", "SEMI", "COMMA",
|
||||
"DOT", "ASSIGN", "GT", "LT", "BANG", "TILDE", "QUESTION", "COLON", "EQUAL",
|
||||
"LE", "GE", "NOTEQUAL", "AND", "OR", "INC", "DEC", "ADD", "SUB", "MUL",
|
||||
"DIV", "BITAND", "BITOR", "CARET", "MOD", "ADD_ASSIGN", "SUB_ASSIGN",
|
||||
"MUL_ASSIGN", "DIV_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN", "MOD_ASSIGN",
|
||||
"LSHIFT_ASSIGN", "RSHIFT_ASSIGN", "URSHIFT_ASSIGN", "Identifier", "AT",
|
||||
"ELLIPSIS", "WS", "COMMENT", "LINE_COMMENT"
|
||||
};
|
||||
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] = "<INVALID>";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String[] getTokenNames() {
|
||||
return tokenNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public Vocabulary getVocabulary() {
|
||||
return VOCABULARY;
|
||||
}
|
||||
|
||||
|
||||
public JavaLexer(CharStream input) {
|
||||
super(input);
|
||||
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGrammarFileName() { return "Java.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 =
|
||||
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2k\u042a\b\1\4\2\t"+
|
||||
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
|
||||
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
|
||||
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
|
||||
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
|
||||
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
|
||||
",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+
|
||||
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
|
||||
"\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+
|
||||
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
|
||||
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+
|
||||
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k\t"+
|
||||
"k\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv\4"+
|
||||
"w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\4~\t~\4\177\t\177\4\u0080\t\u0080"+
|
||||
"\4\u0081\t\u0081\4\u0082\t\u0082\4\u0083\t\u0083\4\u0084\t\u0084\4\u0085"+
|
||||
"\t\u0085\4\u0086\t\u0086\4\u0087\t\u0087\4\u0088\t\u0088\4\u0089\t\u0089"+
|
||||
"\4\u008a\t\u008a\4\u008b\t\u008b\4\u008c\t\u008c\4\u008d\t\u008d\4\u008e"+
|
||||
"\t\u008e\4\u008f\t\u008f\4\u0090\t\u0090\4\u0091\t\u0091\4\u0092\t\u0092"+
|
||||
"\4\u0093\t\u0093\4\u0094\t\u0094\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3\2\3"+
|
||||
"\3\3\3\3\3\3\3\3\3\3\3\3\3\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\4\3\5\3\5\3\5"+
|
||||
"\3\5\3\5\3\5\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3"+
|
||||
"\b\3\b\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\n\3\n\3\n\3\13\3\13\3\13\3\13"+
|
||||
"\3\13\3\13\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r"+
|
||||
"\3\r\3\r\3\16\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3"+
|
||||
"\20\3\20\3\20\3\21\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\22\3\22\3"+
|
||||
"\22\3\22\3\23\3\23\3\23\3\23\3\23\3\23\3\24\3\24\3\24\3\24\3\24\3\24\3"+
|
||||
"\24\3\24\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\27\3\27\3"+
|
||||
"\27\3\30\3\30\3\30\3\30\3\30\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3\31\3"+
|
||||
"\31\3\31\3\31\3\32\3\32\3\32\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3"+
|
||||
"\33\3\33\3\33\3\33\3\33\3\33\3\33\3\34\3\34\3\34\3\34\3\35\3\35\3\35\3"+
|
||||
"\35\3\35\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3"+
|
||||
"\37\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3!\3!\3\"\3\"\3"+
|
||||
"\"\3\"\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3#\3#\3#\3#\3#\3#\3$\3$\3$\3$\3$\3"+
|
||||
"$\3$\3%\3%\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3&\3\'\3\'\3\'\3\'\3\'\3\'\3"+
|
||||
"\'\3(\3(\3(\3(\3(\3(\3(\3(\3(\3)\3)\3)\3)\3)\3)\3*\3*\3*\3*\3*\3*\3*\3"+
|
||||
"+\3+\3+\3+\3+\3+\3+\3+\3+\3+\3+\3+\3+\3,\3,\3,\3,\3,\3-\3-\3-\3-\3-\3"+
|
||||
"-\3.\3.\3.\3.\3.\3.\3.\3/\3/\3/\3/\3/\3/\3/\3/\3/\3/\3\60\3\60\3\60\3"+
|
||||
"\60\3\61\3\61\3\61\3\61\3\61\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3\62\3"+
|
||||
"\62\3\63\3\63\3\63\3\63\3\63\3\63\3\64\3\64\3\64\3\64\5\64\u0281\n\64"+
|
||||
"\3\65\3\65\5\65\u0285\n\65\3\66\3\66\5\66\u0289\n\66\3\67\3\67\5\67\u028d"+
|
||||
"\n\67\38\38\58\u0291\n8\39\39\3:\3:\3:\5:\u0298\n:\3:\3:\3:\5:\u029d\n"+
|
||||
":\5:\u029f\n:\3;\3;\7;\u02a3\n;\f;\16;\u02a6\13;\3;\5;\u02a9\n;\3<\3<"+
|
||||
"\5<\u02ad\n<\3=\3=\3>\3>\5>\u02b3\n>\3?\6?\u02b6\n?\r?\16?\u02b7\3@\3"+
|
||||
"@\3@\3@\3A\3A\7A\u02c0\nA\fA\16A\u02c3\13A\3A\5A\u02c6\nA\3B\3B\3C\3C"+
|
||||
"\5C\u02cc\nC\3D\3D\5D\u02d0\nD\3D\3D\3E\3E\7E\u02d6\nE\fE\16E\u02d9\13"+
|
||||
"E\3E\5E\u02dc\nE\3F\3F\3G\3G\5G\u02e2\nG\3H\3H\3H\3H\3I\3I\7I\u02ea\n"+
|
||||
"I\fI\16I\u02ed\13I\3I\5I\u02f0\nI\3J\3J\3K\3K\5K\u02f6\nK\3L\3L\5L\u02fa"+
|
||||
"\nL\3M\3M\3M\5M\u02ff\nM\3M\5M\u0302\nM\3M\5M\u0305\nM\3M\3M\3M\5M\u030a"+
|
||||
"\nM\3M\5M\u030d\nM\3M\3M\3M\5M\u0312\nM\3M\3M\3M\5M\u0317\nM\3N\3N\3N"+
|
||||
"\3O\3O\3P\5P\u031f\nP\3P\3P\3Q\3Q\3R\3R\3S\3S\3S\5S\u032a\nS\3T\3T\5T"+
|
||||
"\u032e\nT\3T\3T\3T\5T\u0333\nT\3T\3T\5T\u0337\nT\3U\3U\3U\3V\3V\3W\3W"+
|
||||
"\3W\3W\3W\3W\3W\3W\3W\5W\u0347\nW\3X\3X\3X\3X\3X\3X\3X\3X\5X\u0351\nX"+
|
||||
"\3Y\3Y\3Z\3Z\5Z\u0357\nZ\3Z\3Z\3[\6[\u035c\n[\r[\16[\u035d\3\\\3\\\5\\"+
|
||||
"\u0362\n\\\3]\3]\3]\3]\5]\u0368\n]\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\3^\5"+
|
||||
"^\u0375\n^\3_\3_\3_\3_\3_\3_\3_\3`\3`\3a\3a\3a\3a\3a\3b\3b\3c\3c\3d\3"+
|
||||
"d\3e\3e\3f\3f\3g\3g\3h\3h\3i\3i\3j\3j\3k\3k\3l\3l\3m\3m\3n\3n\3o\3o\3"+
|
||||
"p\3p\3q\3q\3r\3r\3r\3s\3s\3s\3t\3t\3t\3u\3u\3u\3v\3v\3v\3w\3w\3w\3x\3"+
|
||||
"x\3x\3y\3y\3y\3z\3z\3{\3{\3|\3|\3}\3}\3~\3~\3\177\3\177\3\u0080\3\u0080"+
|
||||
"\3\u0081\3\u0081\3\u0082\3\u0082\3\u0082\3\u0083\3\u0083\3\u0083\3\u0084"+
|
||||
"\3\u0084\3\u0084\3\u0085\3\u0085\3\u0085\3\u0086\3\u0086\3\u0086\3\u0087"+
|
||||
"\3\u0087\3\u0087\3\u0088\3\u0088\3\u0088\3\u0089\3\u0089\3\u0089\3\u008a"+
|
||||
"\3\u008a\3\u008a\3\u008a\3\u008b\3\u008b\3\u008b\3\u008b\3\u008c\3\u008c"+
|
||||
"\3\u008c\3\u008c\3\u008c\3\u008d\3\u008d\7\u008d\u03f4\n\u008d\f\u008d"+
|
||||
"\16\u008d\u03f7\13\u008d\3\u008e\3\u008e\3\u008e\3\u008e\5\u008e\u03fd"+
|
||||
"\n\u008e\3\u008f\3\u008f\3\u008f\3\u008f\5\u008f\u0403\n\u008f\3\u0090"+
|
||||
"\3\u0090\3\u0091\3\u0091\3\u0091\3\u0091\3\u0092\6\u0092\u040c\n\u0092"+
|
||||
"\r\u0092\16\u0092\u040d\3\u0092\3\u0092\3\u0093\3\u0093\3\u0093\3\u0093"+
|
||||
"\7\u0093\u0416\n\u0093\f\u0093\16\u0093\u0419\13\u0093\3\u0093\3\u0093"+
|
||||
"\3\u0093\3\u0093\3\u0093\3\u0094\3\u0094\3\u0094\3\u0094\7\u0094\u0424"+
|
||||
"\n\u0094\f\u0094\16\u0094\u0427\13\u0094\3\u0094\3\u0094\3\u0417\2\u0095"+
|
||||
"\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27\r\31\16\33\17\35\20"+
|
||||
"\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33\65\34\67\359\36;\37"+
|
||||
"= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63e\64g\65i\2k\2m\2o\2"+
|
||||
"q\2s\2u\2w\2y\2{\2}\2\177\2\u0081\2\u0083\2\u0085\2\u0087\2\u0089\2\u008b"+
|
||||
"\2\u008d\2\u008f\2\u0091\2\u0093\2\u0095\2\u0097\66\u0099\2\u009b\2\u009d"+
|
||||
"\2\u009f\2\u00a1\2\u00a3\2\u00a5\2\u00a7\2\u00a9\2\u00ab\2\u00ad\67\u00af"+
|
||||
"8\u00b1\2\u00b39\u00b5\2\u00b7\2\u00b9\2\u00bb\2\u00bd\2\u00bf\2\u00c1"+
|
||||
":\u00c3;\u00c5<\u00c7=\u00c9>\u00cb?\u00cd@\u00cfA\u00d1B\u00d3C\u00d5"+
|
||||
"D\u00d7E\u00d9F\u00dbG\u00ddH\u00dfI\u00e1J\u00e3K\u00e5L\u00e7M\u00e9"+
|
||||
"N\u00ebO\u00edP\u00efQ\u00f1R\u00f3S\u00f5T\u00f7U\u00f9V\u00fbW\u00fd"+
|
||||
"X\u00ffY\u0101Z\u0103[\u0105\\\u0107]\u0109^\u010b_\u010d`\u010fa\u0111"+
|
||||
"b\u0113c\u0115d\u0117e\u0119f\u011b\2\u011d\2\u011fg\u0121h\u0123i\u0125"+
|
||||
"j\u0127k\3\2\30\4\2NNnn\3\2\63;\4\2ZZzz\5\2\62;CHch\3\2\629\4\2DDdd\3"+
|
||||
"\2\62\63\4\2GGgg\4\2--//\6\2FFHHffhh\4\2RRrr\6\2\f\f\17\17))^^\4\2$$^"+
|
||||
"^\n\2$$))^^ddhhppttvv\3\2\62\65\6\2&&C\\aac|\4\2\2\u0081\ud802\udc01\3"+
|
||||
"\2\ud802\udc01\3\2\udc02\ue001\7\2&&\62;C\\aac|\5\2\13\f\16\17\"\"\4\2"+
|
||||
"\f\f\17\17\2\u0438\2\3\3\2\2\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13"+
|
||||
"\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2"+
|
||||
"\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2"+
|
||||
"!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3"+
|
||||
"\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2"+
|
||||
"\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E"+
|
||||
"\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2"+
|
||||
"\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2"+
|
||||
"\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3\2\2\2\2g\3\2\2\2\2\u0097\3\2\2"+
|
||||
"\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b3\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3"+
|
||||
"\3\2\2\2\2\u00c5\3\2\2\2\2\u00c7\3\2\2\2\2\u00c9\3\2\2\2\2\u00cb\3\2\2"+
|
||||
"\2\2\u00cd\3\2\2\2\2\u00cf\3\2\2\2\2\u00d1\3\2\2\2\2\u00d3\3\2\2\2\2\u00d5"+
|
||||
"\3\2\2\2\2\u00d7\3\2\2\2\2\u00d9\3\2\2\2\2\u00db\3\2\2\2\2\u00dd\3\2\2"+
|
||||
"\2\2\u00df\3\2\2\2\2\u00e1\3\2\2\2\2\u00e3\3\2\2\2\2\u00e5\3\2\2\2\2\u00e7"+
|
||||
"\3\2\2\2\2\u00e9\3\2\2\2\2\u00eb\3\2\2\2\2\u00ed\3\2\2\2\2\u00ef\3\2\2"+
|
||||
"\2\2\u00f1\3\2\2\2\2\u00f3\3\2\2\2\2\u00f5\3\2\2\2\2\u00f7\3\2\2\2\2\u00f9"+
|
||||
"\3\2\2\2\2\u00fb\3\2\2\2\2\u00fd\3\2\2\2\2\u00ff\3\2\2\2\2\u0101\3\2\2"+
|
||||
"\2\2\u0103\3\2\2\2\2\u0105\3\2\2\2\2\u0107\3\2\2\2\2\u0109\3\2\2\2\2\u010b"+
|
||||
"\3\2\2\2\2\u010d\3\2\2\2\2\u010f\3\2\2\2\2\u0111\3\2\2\2\2\u0113\3\2\2"+
|
||||
"\2\2\u0115\3\2\2\2\2\u0117\3\2\2\2\2\u0119\3\2\2\2\2\u011f\3\2\2\2\2\u0121"+
|
||||
"\3\2\2\2\2\u0123\3\2\2\2\2\u0125\3\2\2\2\2\u0127\3\2\2\2\3\u0129\3\2\2"+
|
||||
"\2\5\u0132\3\2\2\2\7\u0139\3\2\2\2\t\u0141\3\2\2\2\13\u0147\3\2\2\2\r"+
|
||||
"\u014c\3\2\2\2\17\u0151\3\2\2\2\21\u0157\3\2\2\2\23\u015c\3\2\2\2\25\u0162"+
|
||||
"\3\2\2\2\27\u0168\3\2\2\2\31\u0171\3\2\2\2\33\u0179\3\2\2\2\35\u017c\3"+
|
||||
"\2\2\2\37\u0183\3\2\2\2!\u0188\3\2\2\2#\u018d\3\2\2\2%\u0195\3\2\2\2\'"+
|
||||
"\u019b\3\2\2\2)\u01a3\3\2\2\2+\u01a9\3\2\2\2-\u01ad\3\2\2\2/\u01b0\3\2"+
|
||||
"\2\2\61\u01b5\3\2\2\2\63\u01c0\3\2\2\2\65\u01c7\3\2\2\2\67\u01d2\3\2\2"+
|
||||
"\29\u01d6\3\2\2\2;\u01e0\3\2\2\2=\u01e5\3\2\2\2?\u01ec\3\2\2\2A\u01f0"+
|
||||
"\3\2\2\2C\u01f8\3\2\2\2E\u0200\3\2\2\2G\u020a\3\2\2\2I\u0211\3\2\2\2K"+
|
||||
"\u0218\3\2\2\2M\u021e\3\2\2\2O\u0225\3\2\2\2Q\u022e\3\2\2\2S\u0234\3\2"+
|
||||
"\2\2U\u023b\3\2\2\2W\u0248\3\2\2\2Y\u024d\3\2\2\2[\u0253\3\2\2\2]\u025a"+
|
||||
"\3\2\2\2_\u0264\3\2\2\2a\u0268\3\2\2\2c\u026d\3\2\2\2e\u0276\3\2\2\2g"+
|
||||
"\u0280\3\2\2\2i\u0282\3\2\2\2k\u0286\3\2\2\2m\u028a\3\2\2\2o\u028e\3\2"+
|
||||
"\2\2q\u0292\3\2\2\2s\u029e\3\2\2\2u\u02a0\3\2\2\2w\u02ac\3\2\2\2y\u02ae"+
|
||||
"\3\2\2\2{\u02b2\3\2\2\2}\u02b5\3\2\2\2\177\u02b9\3\2\2\2\u0081\u02bd\3"+
|
||||
"\2\2\2\u0083\u02c7\3\2\2\2\u0085\u02cb\3\2\2\2\u0087\u02cd\3\2\2\2\u0089"+
|
||||
"\u02d3\3\2\2\2\u008b\u02dd\3\2\2\2\u008d\u02e1\3\2\2\2\u008f\u02e3\3\2"+
|
||||
"\2\2\u0091\u02e7\3\2\2\2\u0093\u02f1\3\2\2\2\u0095\u02f5\3\2\2\2\u0097"+
|
||||
"\u02f9\3\2\2\2\u0099\u0316\3\2\2\2\u009b\u0318\3\2\2\2\u009d\u031b\3\2"+
|
||||
"\2\2\u009f\u031e\3\2\2\2\u00a1\u0322\3\2\2\2\u00a3\u0324\3\2\2\2\u00a5"+
|
||||
"\u0326\3\2\2\2\u00a7\u0336\3\2\2\2\u00a9\u0338\3\2\2\2\u00ab\u033b\3\2"+
|
||||
"\2\2\u00ad\u0346\3\2\2\2\u00af\u0350\3\2\2\2\u00b1\u0352\3\2\2\2\u00b3"+
|
||||
"\u0354\3\2\2\2\u00b5\u035b\3\2\2\2\u00b7\u0361\3\2\2\2\u00b9\u0367\3\2"+
|
||||
"\2\2\u00bb\u0374\3\2\2\2\u00bd\u0376\3\2\2\2\u00bf\u037d\3\2\2\2\u00c1"+
|
||||
"\u037f\3\2\2\2\u00c3\u0384\3\2\2\2\u00c5\u0386\3\2\2\2\u00c7\u0388\3\2"+
|
||||
"\2\2\u00c9\u038a\3\2\2\2\u00cb\u038c\3\2\2\2\u00cd\u038e\3\2\2\2\u00cf"+
|
||||
"\u0390\3\2\2\2\u00d1\u0392\3\2\2\2\u00d3\u0394\3\2\2\2\u00d5\u0396\3\2"+
|
||||
"\2\2\u00d7\u0398\3\2\2\2\u00d9\u039a\3\2\2\2\u00db\u039c\3\2\2\2\u00dd"+
|
||||
"\u039e\3\2\2\2\u00df\u03a0\3\2\2\2\u00e1\u03a2\3\2\2\2\u00e3\u03a4\3\2"+
|
||||
"\2\2\u00e5\u03a7\3\2\2\2\u00e7\u03aa\3\2\2\2\u00e9\u03ad\3\2\2\2\u00eb"+
|
||||
"\u03b0\3\2\2\2\u00ed\u03b3\3\2\2\2\u00ef\u03b6\3\2\2\2\u00f1\u03b9\3\2"+
|
||||
"\2\2\u00f3\u03bc\3\2\2\2\u00f5\u03be\3\2\2\2\u00f7\u03c0\3\2\2\2\u00f9"+
|
||||
"\u03c2\3\2\2\2\u00fb\u03c4\3\2\2\2\u00fd\u03c6\3\2\2\2\u00ff\u03c8\3\2"+
|
||||
"\2\2\u0101\u03ca\3\2\2\2\u0103\u03cc\3\2\2\2\u0105\u03cf\3\2\2\2\u0107"+
|
||||
"\u03d2\3\2\2\2\u0109\u03d5\3\2\2\2\u010b\u03d8\3\2\2\2\u010d\u03db\3\2"+
|
||||
"\2\2\u010f\u03de\3\2\2\2\u0111\u03e1\3\2\2\2\u0113\u03e4\3\2\2\2\u0115"+
|
||||
"\u03e8\3\2\2\2\u0117\u03ec\3\2\2\2\u0119\u03f1\3\2\2\2\u011b\u03fc\3\2"+
|
||||
"\2\2\u011d\u0402\3\2\2\2\u011f\u0404\3\2\2\2\u0121\u0406\3\2\2\2\u0123"+
|
||||
"\u040b\3\2\2\2\u0125\u0411\3\2\2\2\u0127\u041f\3\2\2\2\u0129\u012a\7c"+
|
||||
"\2\2\u012a\u012b\7d\2\2\u012b\u012c\7u\2\2\u012c\u012d\7v\2\2\u012d\u012e"+
|
||||
"\7t\2\2\u012e\u012f\7c\2\2\u012f\u0130\7e\2\2\u0130\u0131\7v\2\2\u0131"+
|
||||
"\4\3\2\2\2\u0132\u0133\7c\2\2\u0133\u0134\7u\2\2\u0134\u0135\7u\2\2\u0135"+
|
||||
"\u0136\7g\2\2\u0136\u0137\7t\2\2\u0137\u0138\7v\2\2\u0138\6\3\2\2\2\u0139"+
|
||||
"\u013a\7d\2\2\u013a\u013b\7q\2\2\u013b\u013c\7q\2\2\u013c\u013d\7n\2\2"+
|
||||
"\u013d\u013e\7g\2\2\u013e\u013f\7c\2\2\u013f\u0140\7p\2\2\u0140\b\3\2"+
|
||||
"\2\2\u0141\u0142\7d\2\2\u0142\u0143\7t\2\2\u0143\u0144\7g\2\2\u0144\u0145"+
|
||||
"\7c\2\2\u0145\u0146\7m\2\2\u0146\n\3\2\2\2\u0147\u0148\7d\2\2\u0148\u0149"+
|
||||
"\7{\2\2\u0149\u014a\7v\2\2\u014a\u014b\7g\2\2\u014b\f\3\2\2\2\u014c\u014d"+
|
||||
"\7e\2\2\u014d\u014e\7c\2\2\u014e\u014f\7u\2\2\u014f\u0150\7g\2\2\u0150"+
|
||||
"\16\3\2\2\2\u0151\u0152\7e\2\2\u0152\u0153\7c\2\2\u0153\u0154\7v\2\2\u0154"+
|
||||
"\u0155\7e\2\2\u0155\u0156\7j\2\2\u0156\20\3\2\2\2\u0157\u0158\7e\2\2\u0158"+
|
||||
"\u0159\7j\2\2\u0159\u015a\7c\2\2\u015a\u015b\7t\2\2\u015b\22\3\2\2\2\u015c"+
|
||||
"\u015d\7e\2\2\u015d\u015e\7n\2\2\u015e\u015f\7c\2\2\u015f\u0160\7u\2\2"+
|
||||
"\u0160\u0161\7u\2\2\u0161\24\3\2\2\2\u0162\u0163\7e\2\2\u0163\u0164\7"+
|
||||
"q\2\2\u0164\u0165\7p\2\2\u0165\u0166\7u\2\2\u0166\u0167\7v\2\2\u0167\26"+
|
||||
"\3\2\2\2\u0168\u0169\7e\2\2\u0169\u016a\7q\2\2\u016a\u016b\7p\2\2\u016b"+
|
||||
"\u016c\7v\2\2\u016c\u016d\7k\2\2\u016d\u016e\7p\2\2\u016e\u016f\7w\2\2"+
|
||||
"\u016f\u0170\7g\2\2\u0170\30\3\2\2\2\u0171\u0172\7f\2\2\u0172\u0173\7"+
|
||||
"g\2\2\u0173\u0174\7h\2\2\u0174\u0175\7c\2\2\u0175\u0176\7w\2\2\u0176\u0177"+
|
||||
"\7n\2\2\u0177\u0178\7v\2\2\u0178\32\3\2\2\2\u0179\u017a\7f\2\2\u017a\u017b"+
|
||||
"\7q\2\2\u017b\34\3\2\2\2\u017c\u017d\7f\2\2\u017d\u017e\7q\2\2\u017e\u017f"+
|
||||
"\7w\2\2\u017f\u0180\7d\2\2\u0180\u0181\7n\2\2\u0181\u0182\7g\2\2\u0182"+
|
||||
"\36\3\2\2\2\u0183\u0184\7g\2\2\u0184\u0185\7n\2\2\u0185\u0186\7u\2\2\u0186"+
|
||||
"\u0187\7g\2\2\u0187 \3\2\2\2\u0188\u0189\7g\2\2\u0189\u018a\7p\2\2\u018a"+
|
||||
"\u018b\7w\2\2\u018b\u018c\7o\2\2\u018c\"\3\2\2\2\u018d\u018e\7g\2\2\u018e"+
|
||||
"\u018f\7z\2\2\u018f\u0190\7v\2\2\u0190\u0191\7g\2\2\u0191\u0192\7p\2\2"+
|
||||
"\u0192\u0193\7f\2\2\u0193\u0194\7u\2\2\u0194$\3\2\2\2\u0195\u0196\7h\2"+
|
||||
"\2\u0196\u0197\7k\2\2\u0197\u0198\7p\2\2\u0198\u0199\7c\2\2\u0199\u019a"+
|
||||
"\7n\2\2\u019a&\3\2\2\2\u019b\u019c\7h\2\2\u019c\u019d\7k\2\2\u019d\u019e"+
|
||||
"\7p\2\2\u019e\u019f\7c\2\2\u019f\u01a0\7n\2\2\u01a0\u01a1\7n\2\2\u01a1"+
|
||||
"\u01a2\7{\2\2\u01a2(\3\2\2\2\u01a3\u01a4\7h\2\2\u01a4\u01a5\7n\2\2\u01a5"+
|
||||
"\u01a6\7q\2\2\u01a6\u01a7\7c\2\2\u01a7\u01a8\7v\2\2\u01a8*\3\2\2\2\u01a9"+
|
||||
"\u01aa\7h\2\2\u01aa\u01ab\7q\2\2\u01ab\u01ac\7t\2\2\u01ac,\3\2\2\2\u01ad"+
|
||||
"\u01ae\7k\2\2\u01ae\u01af\7h\2\2\u01af.\3\2\2\2\u01b0\u01b1\7i\2\2\u01b1"+
|
||||
"\u01b2\7q\2\2\u01b2\u01b3\7v\2\2\u01b3\u01b4\7q\2\2\u01b4\60\3\2\2\2\u01b5"+
|
||||
"\u01b6\7k\2\2\u01b6\u01b7\7o\2\2\u01b7\u01b8\7r\2\2\u01b8\u01b9\7n\2\2"+
|
||||
"\u01b9\u01ba\7g\2\2\u01ba\u01bb\7o\2\2\u01bb\u01bc\7g\2\2\u01bc\u01bd"+
|
||||
"\7p\2\2\u01bd\u01be\7v\2\2\u01be\u01bf\7u\2\2\u01bf\62\3\2\2\2\u01c0\u01c1"+
|
||||
"\7k\2\2\u01c1\u01c2\7o\2\2\u01c2\u01c3\7r\2\2\u01c3\u01c4\7q\2\2\u01c4"+
|
||||
"\u01c5\7t\2\2\u01c5\u01c6\7v\2\2\u01c6\64\3\2\2\2\u01c7\u01c8\7k\2\2\u01c8"+
|
||||
"\u01c9\7p\2\2\u01c9\u01ca\7u\2\2\u01ca\u01cb\7v\2\2\u01cb\u01cc\7c\2\2"+
|
||||
"\u01cc\u01cd\7p\2\2\u01cd\u01ce\7e\2\2\u01ce\u01cf\7g\2\2\u01cf\u01d0"+
|
||||
"\7q\2\2\u01d0\u01d1\7h\2\2\u01d1\66\3\2\2\2\u01d2\u01d3\7k\2\2\u01d3\u01d4"+
|
||||
"\7p\2\2\u01d4\u01d5\7v\2\2\u01d58\3\2\2\2\u01d6\u01d7\7k\2\2\u01d7\u01d8"+
|
||||
"\7p\2\2\u01d8\u01d9\7v\2\2\u01d9\u01da\7g\2\2\u01da\u01db\7t\2\2\u01db"+
|
||||
"\u01dc\7h\2\2\u01dc\u01dd\7c\2\2\u01dd\u01de\7e\2\2\u01de\u01df\7g\2\2"+
|
||||
"\u01df:\3\2\2\2\u01e0\u01e1\7n\2\2\u01e1\u01e2\7q\2\2\u01e2\u01e3\7p\2"+
|
||||
"\2\u01e3\u01e4\7i\2\2\u01e4<\3\2\2\2\u01e5\u01e6\7p\2\2\u01e6\u01e7\7"+
|
||||
"c\2\2\u01e7\u01e8\7v\2\2\u01e8\u01e9\7k\2\2\u01e9\u01ea\7x\2\2\u01ea\u01eb"+
|
||||
"\7g\2\2\u01eb>\3\2\2\2\u01ec\u01ed\7p\2\2\u01ed\u01ee\7g\2\2\u01ee\u01ef"+
|
||||
"\7y\2\2\u01ef@\3\2\2\2\u01f0\u01f1\7r\2\2\u01f1\u01f2\7c\2\2\u01f2\u01f3"+
|
||||
"\7e\2\2\u01f3\u01f4\7m\2\2\u01f4\u01f5\7c\2\2\u01f5\u01f6\7i\2\2\u01f6"+
|
||||
"\u01f7\7g\2\2\u01f7B\3\2\2\2\u01f8\u01f9\7r\2\2\u01f9\u01fa\7t\2\2\u01fa"+
|
||||
"\u01fb\7k\2\2\u01fb\u01fc\7x\2\2\u01fc\u01fd\7c\2\2\u01fd\u01fe\7v\2\2"+
|
||||
"\u01fe\u01ff\7g\2\2\u01ffD\3\2\2\2\u0200\u0201\7r\2\2\u0201\u0202\7t\2"+
|
||||
"\2\u0202\u0203\7q\2\2\u0203\u0204\7v\2\2\u0204\u0205\7g\2\2\u0205\u0206"+
|
||||
"\7e\2\2\u0206\u0207\7v\2\2\u0207\u0208\7g\2\2\u0208\u0209\7f\2\2\u0209"+
|
||||
"F\3\2\2\2\u020a\u020b\7r\2\2\u020b\u020c\7w\2\2\u020c\u020d\7d\2\2\u020d"+
|
||||
"\u020e\7n\2\2\u020e\u020f\7k\2\2\u020f\u0210\7e\2\2\u0210H\3\2\2\2\u0211"+
|
||||
"\u0212\7t\2\2\u0212\u0213\7g\2\2\u0213\u0214\7v\2\2\u0214\u0215\7w\2\2"+
|
||||
"\u0215\u0216\7t\2\2\u0216\u0217\7p\2\2\u0217J\3\2\2\2\u0218\u0219\7u\2"+
|
||||
"\2\u0219\u021a\7j\2\2\u021a\u021b\7q\2\2\u021b\u021c\7t\2\2\u021c\u021d"+
|
||||
"\7v\2\2\u021dL\3\2\2\2\u021e\u021f\7u\2\2\u021f\u0220\7v\2\2\u0220\u0221"+
|
||||
"\7c\2\2\u0221\u0222\7v\2\2\u0222\u0223\7k\2\2\u0223\u0224\7e\2\2\u0224"+
|
||||
"N\3\2\2\2\u0225\u0226\7u\2\2\u0226\u0227\7v\2\2\u0227\u0228\7t\2\2\u0228"+
|
||||
"\u0229\7k\2\2\u0229\u022a\7e\2\2\u022a\u022b\7v\2\2\u022b\u022c\7h\2\2"+
|
||||
"\u022c\u022d\7r\2\2\u022dP\3\2\2\2\u022e\u022f\7u\2\2\u022f\u0230\7w\2"+
|
||||
"\2\u0230\u0231\7r\2\2\u0231\u0232\7g\2\2\u0232\u0233\7t\2\2\u0233R\3\2"+
|
||||
"\2\2\u0234\u0235\7u\2\2\u0235\u0236\7y\2\2\u0236\u0237\7k\2\2\u0237\u0238"+
|
||||
"\7v\2\2\u0238\u0239\7e\2\2\u0239\u023a\7j\2\2\u023aT\3\2\2\2\u023b\u023c"+
|
||||
"\7u\2\2\u023c\u023d\7{\2\2\u023d\u023e\7p\2\2\u023e\u023f\7e\2\2\u023f"+
|
||||
"\u0240\7j\2\2\u0240\u0241\7t\2\2\u0241\u0242\7q\2\2\u0242\u0243\7p\2\2"+
|
||||
"\u0243\u0244\7k\2\2\u0244\u0245\7|\2\2\u0245\u0246\7g\2\2\u0246\u0247"+
|
||||
"\7f\2\2\u0247V\3\2\2\2\u0248\u0249\7v\2\2\u0249\u024a\7j\2\2\u024a\u024b"+
|
||||
"\7k\2\2\u024b\u024c\7u\2\2\u024cX\3\2\2\2\u024d\u024e\7v\2\2\u024e\u024f"+
|
||||
"\7j\2\2\u024f\u0250\7t\2\2\u0250\u0251\7q\2\2\u0251\u0252\7y\2\2\u0252"+
|
||||
"Z\3\2\2\2\u0253\u0254\7v\2\2\u0254\u0255\7j\2\2\u0255\u0256\7t\2\2\u0256"+
|
||||
"\u0257\7q\2\2\u0257\u0258\7y\2\2\u0258\u0259\7u\2\2\u0259\\\3\2\2\2\u025a"+
|
||||
"\u025b\7v\2\2\u025b\u025c\7t\2\2\u025c\u025d\7c\2\2\u025d\u025e\7p\2\2"+
|
||||
"\u025e\u025f\7u\2\2\u025f\u0260\7k\2\2\u0260\u0261\7g\2\2\u0261\u0262"+
|
||||
"\7p\2\2\u0262\u0263\7v\2\2\u0263^\3\2\2\2\u0264\u0265\7v\2\2\u0265\u0266"+
|
||||
"\7t\2\2\u0266\u0267\7{\2\2\u0267`\3\2\2\2\u0268\u0269\7x\2\2\u0269\u026a"+
|
||||
"\7q\2\2\u026a\u026b\7k\2\2\u026b\u026c\7f\2\2\u026cb\3\2\2\2\u026d\u026e"+
|
||||
"\7x\2\2\u026e\u026f\7q\2\2\u026f\u0270\7n\2\2\u0270\u0271\7c\2\2\u0271"+
|
||||
"\u0272\7v\2\2\u0272\u0273\7k\2\2\u0273\u0274\7n\2\2\u0274\u0275\7g\2\2"+
|
||||
"\u0275d\3\2\2\2\u0276\u0277\7y\2\2\u0277\u0278\7j\2\2\u0278\u0279\7k\2"+
|
||||
"\2\u0279\u027a\7n\2\2\u027a\u027b\7g\2\2\u027bf\3\2\2\2\u027c\u0281\5"+
|
||||
"i\65\2\u027d\u0281\5k\66\2\u027e\u0281\5m\67\2\u027f\u0281\5o8\2\u0280"+
|
||||
"\u027c\3\2\2\2\u0280\u027d\3\2\2\2\u0280\u027e\3\2\2\2\u0280\u027f\3\2"+
|
||||
"\2\2\u0281h\3\2\2\2\u0282\u0284\5s:\2\u0283\u0285\5q9\2\u0284\u0283\3"+
|
||||
"\2\2\2\u0284\u0285\3\2\2\2\u0285j\3\2\2\2\u0286\u0288\5\177@\2\u0287\u0289"+
|
||||
"\5q9\2\u0288\u0287\3\2\2\2\u0288\u0289\3\2\2\2\u0289l\3\2\2\2\u028a\u028c"+
|
||||
"\5\u0087D\2\u028b\u028d\5q9\2\u028c\u028b\3\2\2\2\u028c\u028d\3\2\2\2"+
|
||||
"\u028dn\3\2\2\2\u028e\u0290\5\u008fH\2\u028f\u0291\5q9\2\u0290\u028f\3"+
|
||||
"\2\2\2\u0290\u0291\3\2\2\2\u0291p\3\2\2\2\u0292\u0293\t\2\2\2\u0293r\3"+
|
||||
"\2\2\2\u0294\u029f\7\62\2\2\u0295\u029c\5y=\2\u0296\u0298\5u;\2\u0297"+
|
||||
"\u0296\3\2\2\2\u0297\u0298\3\2\2\2\u0298\u029d\3\2\2\2\u0299\u029a\5}"+
|
||||
"?\2\u029a\u029b\5u;\2\u029b\u029d\3\2\2\2\u029c\u0297\3\2\2\2\u029c\u0299"+
|
||||
"\3\2\2\2\u029d\u029f\3\2\2\2\u029e\u0294\3\2\2\2\u029e\u0295\3\2\2\2\u029f"+
|
||||
"t\3\2\2\2\u02a0\u02a8\5w<\2\u02a1\u02a3\5{>\2\u02a2\u02a1\3\2\2\2\u02a3"+
|
||||
"\u02a6\3\2\2\2\u02a4\u02a2\3\2\2\2\u02a4\u02a5\3\2\2\2\u02a5\u02a7\3\2"+
|
||||
"\2\2\u02a6\u02a4\3\2\2\2\u02a7\u02a9\5w<\2\u02a8\u02a4\3\2\2\2\u02a8\u02a9"+
|
||||
"\3\2\2\2\u02a9v\3\2\2\2\u02aa\u02ad\7\62\2\2\u02ab\u02ad\5y=\2\u02ac\u02aa"+
|
||||
"\3\2\2\2\u02ac\u02ab\3\2\2\2\u02adx\3\2\2\2\u02ae\u02af\t\3\2\2\u02af"+
|
||||
"z\3\2\2\2\u02b0\u02b3\5w<\2\u02b1\u02b3\7a\2\2\u02b2\u02b0\3\2\2\2\u02b2"+
|
||||
"\u02b1\3\2\2\2\u02b3|\3\2\2\2\u02b4\u02b6\7a\2\2\u02b5\u02b4\3\2\2\2\u02b6"+
|
||||
"\u02b7\3\2\2\2\u02b7\u02b5\3\2\2\2\u02b7\u02b8\3\2\2\2\u02b8~\3\2\2\2"+
|
||||
"\u02b9\u02ba\7\62\2\2\u02ba\u02bb\t\4\2\2\u02bb\u02bc\5\u0081A\2\u02bc"+
|
||||
"\u0080\3\2\2\2\u02bd\u02c5\5\u0083B\2\u02be\u02c0\5\u0085C\2\u02bf\u02be"+
|
||||
"\3\2\2\2\u02c0\u02c3\3\2\2\2\u02c1\u02bf\3\2\2\2\u02c1\u02c2\3\2\2\2\u02c2"+
|
||||
"\u02c4\3\2\2\2\u02c3\u02c1\3\2\2\2\u02c4\u02c6\5\u0083B\2\u02c5\u02c1"+
|
||||
"\3\2\2\2\u02c5\u02c6\3\2\2\2\u02c6\u0082\3\2\2\2\u02c7\u02c8\t\5\2\2\u02c8"+
|
||||
"\u0084\3\2\2\2\u02c9\u02cc\5\u0083B\2\u02ca\u02cc\7a\2\2\u02cb\u02c9\3"+
|
||||
"\2\2\2\u02cb\u02ca\3\2\2\2\u02cc\u0086\3\2\2\2\u02cd\u02cf\7\62\2\2\u02ce"+
|
||||
"\u02d0\5}?\2\u02cf\u02ce\3\2\2\2\u02cf\u02d0\3\2\2\2\u02d0\u02d1\3\2\2"+
|
||||
"\2\u02d1\u02d2\5\u0089E\2\u02d2\u0088\3\2\2\2\u02d3\u02db\5\u008bF\2\u02d4"+
|
||||
"\u02d6\5\u008dG\2\u02d5\u02d4\3\2\2\2\u02d6\u02d9\3\2\2\2\u02d7\u02d5"+
|
||||
"\3\2\2\2\u02d7\u02d8\3\2\2\2\u02d8\u02da\3\2\2\2\u02d9\u02d7\3\2\2\2\u02da"+
|
||||
"\u02dc\5\u008bF\2\u02db\u02d7\3\2\2\2\u02db\u02dc\3\2\2\2\u02dc\u008a"+
|
||||
"\3\2\2\2\u02dd\u02de\t\6\2\2\u02de\u008c\3\2\2\2\u02df\u02e2\5\u008bF"+
|
||||
"\2\u02e0\u02e2\7a\2\2\u02e1\u02df\3\2\2\2\u02e1\u02e0\3\2\2\2\u02e2\u008e"+
|
||||
"\3\2\2\2\u02e3\u02e4\7\62\2\2\u02e4\u02e5\t\7\2\2\u02e5\u02e6\5\u0091"+
|
||||
"I\2\u02e6\u0090\3\2\2\2\u02e7\u02ef\5\u0093J\2\u02e8\u02ea\5\u0095K\2"+
|
||||
"\u02e9\u02e8\3\2\2\2\u02ea\u02ed\3\2\2\2\u02eb\u02e9\3\2\2\2\u02eb\u02ec"+
|
||||
"\3\2\2\2\u02ec\u02ee\3\2\2\2\u02ed\u02eb\3\2\2\2\u02ee\u02f0\5\u0093J"+
|
||||
"\2\u02ef\u02eb\3\2\2\2\u02ef\u02f0\3\2\2\2\u02f0\u0092\3\2\2\2\u02f1\u02f2"+
|
||||
"\t\b\2\2\u02f2\u0094\3\2\2\2\u02f3\u02f6\5\u0093J\2\u02f4\u02f6\7a\2\2"+
|
||||
"\u02f5\u02f3\3\2\2\2\u02f5\u02f4\3\2\2\2\u02f6\u0096\3\2\2\2\u02f7\u02fa"+
|
||||
"\5\u0099M\2\u02f8\u02fa\5\u00a5S\2\u02f9\u02f7\3\2\2\2\u02f9\u02f8\3\2"+
|
||||
"\2\2\u02fa\u0098\3\2\2\2\u02fb\u02fc\5u;\2\u02fc\u02fe\7\60\2\2\u02fd"+
|
||||
"\u02ff\5u;\2\u02fe\u02fd\3\2\2\2\u02fe\u02ff\3\2\2\2\u02ff\u0301\3\2\2"+
|
||||
"\2\u0300\u0302\5\u009bN\2\u0301\u0300\3\2\2\2\u0301\u0302\3\2\2\2\u0302"+
|
||||
"\u0304\3\2\2\2\u0303\u0305\5\u00a3R\2\u0304\u0303\3\2\2\2\u0304\u0305"+
|
||||
"\3\2\2\2\u0305\u0317\3\2\2\2\u0306\u0307\7\60\2\2\u0307\u0309\5u;\2\u0308"+
|
||||
"\u030a\5\u009bN\2\u0309\u0308\3\2\2\2\u0309\u030a\3\2\2\2\u030a\u030c"+
|
||||
"\3\2\2\2\u030b\u030d\5\u00a3R\2\u030c\u030b\3\2\2\2\u030c\u030d\3\2\2"+
|
||||
"\2\u030d\u0317\3\2\2\2\u030e\u030f\5u;\2\u030f\u0311\5\u009bN\2\u0310"+
|
||||
"\u0312\5\u00a3R\2\u0311\u0310\3\2\2\2\u0311\u0312\3\2\2\2\u0312\u0317"+
|
||||
"\3\2\2\2\u0313\u0314\5u;\2\u0314\u0315\5\u00a3R\2\u0315\u0317\3\2\2\2"+
|
||||
"\u0316\u02fb\3\2\2\2\u0316\u0306\3\2\2\2\u0316\u030e\3\2\2\2\u0316\u0313"+
|
||||
"\3\2\2\2\u0317\u009a\3\2\2\2\u0318\u0319\5\u009dO\2\u0319\u031a\5\u009f"+
|
||||
"P\2\u031a\u009c\3\2\2\2\u031b\u031c\t\t\2\2\u031c\u009e\3\2\2\2\u031d"+
|
||||
"\u031f\5\u00a1Q\2\u031e\u031d\3\2\2\2\u031e\u031f\3\2\2\2\u031f\u0320"+
|
||||
"\3\2\2\2\u0320\u0321\5u;\2\u0321\u00a0\3\2\2\2\u0322\u0323\t\n\2\2\u0323"+
|
||||
"\u00a2\3\2\2\2\u0324\u0325\t\13\2\2\u0325\u00a4\3\2\2\2\u0326\u0327\5"+
|
||||
"\u00a7T\2\u0327\u0329\5\u00a9U\2\u0328\u032a\5\u00a3R\2\u0329\u0328\3"+
|
||||
"\2\2\2\u0329\u032a\3\2\2\2\u032a\u00a6\3\2\2\2\u032b\u032d\5\177@\2\u032c"+
|
||||
"\u032e\7\60\2\2\u032d\u032c\3\2\2\2\u032d\u032e\3\2\2\2\u032e\u0337\3"+
|
||||
"\2\2\2\u032f\u0330\7\62\2\2\u0330\u0332\t\4\2\2\u0331\u0333\5\u0081A\2"+
|
||||
"\u0332\u0331\3\2\2\2\u0332\u0333\3\2\2\2\u0333\u0334\3\2\2\2\u0334\u0335"+
|
||||
"\7\60\2\2\u0335\u0337\5\u0081A\2\u0336\u032b\3\2\2\2\u0336\u032f\3\2\2"+
|
||||
"\2\u0337\u00a8\3\2\2\2\u0338\u0339\5\u00abV\2\u0339\u033a\5\u009fP\2\u033a"+
|
||||
"\u00aa\3\2\2\2\u033b\u033c\t\f\2\2\u033c\u00ac\3\2\2\2\u033d\u033e\7v"+
|
||||
"\2\2\u033e\u033f\7t\2\2\u033f\u0340\7w\2\2\u0340\u0347\7g\2\2\u0341\u0342"+
|
||||
"\7h\2\2\u0342\u0343\7c\2\2\u0343\u0344\7n\2\2\u0344\u0345\7u\2\2\u0345"+
|
||||
"\u0347\7g\2\2\u0346\u033d\3\2\2\2\u0346\u0341\3\2\2\2\u0347\u00ae\3\2"+
|
||||
"\2\2\u0348\u0349\7)\2\2\u0349\u034a\5\u00b1Y\2\u034a\u034b\7)\2\2\u034b"+
|
||||
"\u0351\3\2\2\2\u034c\u034d\7)\2\2\u034d\u034e\5\u00b9]\2\u034e\u034f\7"+
|
||||
")\2\2\u034f\u0351\3\2\2\2\u0350\u0348\3\2\2\2\u0350\u034c\3\2\2\2\u0351"+
|
||||
"\u00b0\3\2\2\2\u0352\u0353\n\r\2\2\u0353\u00b2\3\2\2\2\u0354\u0356\7$"+
|
||||
"\2\2\u0355\u0357\5\u00b5[\2\u0356\u0355\3\2\2\2\u0356\u0357\3\2\2\2\u0357"+
|
||||
"\u0358\3\2\2\2\u0358\u0359\7$\2\2\u0359\u00b4\3\2\2\2\u035a\u035c\5\u00b7"+
|
||||
"\\\2\u035b\u035a\3\2\2\2\u035c\u035d\3\2\2\2\u035d\u035b\3\2\2\2\u035d"+
|
||||
"\u035e\3\2\2\2\u035e\u00b6\3\2\2\2\u035f\u0362\n\16\2\2\u0360\u0362\5"+
|
||||
"\u00b9]\2\u0361\u035f\3\2\2\2\u0361\u0360\3\2\2\2\u0362\u00b8\3\2\2\2"+
|
||||
"\u0363\u0364\7^\2\2\u0364\u0368\t\17\2\2\u0365\u0368\5\u00bb^\2\u0366"+
|
||||
"\u0368\5\u00bd_\2\u0367\u0363\3\2\2\2\u0367\u0365\3\2\2\2\u0367\u0366"+
|
||||
"\3\2\2\2\u0368\u00ba\3\2\2\2\u0369\u036a\7^\2\2\u036a\u0375\5\u008bF\2"+
|
||||
"\u036b\u036c\7^\2\2\u036c\u036d\5\u008bF\2\u036d\u036e\5\u008bF\2\u036e"+
|
||||
"\u0375\3\2\2\2\u036f\u0370\7^\2\2\u0370\u0371\5\u00bf`\2\u0371\u0372\5"+
|
||||
"\u008bF\2\u0372\u0373\5\u008bF\2\u0373\u0375\3\2\2\2\u0374\u0369\3\2\2"+
|
||||
"\2\u0374\u036b\3\2\2\2\u0374\u036f\3\2\2\2\u0375\u00bc\3\2\2\2\u0376\u0377"+
|
||||
"\7^\2\2\u0377\u0378\7w\2\2\u0378\u0379\5\u0083B\2\u0379\u037a\5\u0083"+
|
||||
"B\2\u037a\u037b\5\u0083B\2\u037b\u037c\5\u0083B\2\u037c\u00be\3\2\2\2"+
|
||||
"\u037d\u037e\t\20\2\2\u037e\u00c0\3\2\2\2\u037f\u0380\7p\2\2\u0380\u0381"+
|
||||
"\7w\2\2\u0381\u0382\7n\2\2\u0382\u0383\7n\2\2\u0383\u00c2\3\2\2\2\u0384"+
|
||||
"\u0385\7*\2\2\u0385\u00c4\3\2\2\2\u0386\u0387\7+\2\2\u0387\u00c6\3\2\2"+
|
||||
"\2\u0388\u0389\7}\2\2\u0389\u00c8\3\2\2\2\u038a\u038b\7\177\2\2\u038b"+
|
||||
"\u00ca\3\2\2\2\u038c\u038d\7]\2\2\u038d\u00cc\3\2\2\2\u038e\u038f\7_\2"+
|
||||
"\2\u038f\u00ce\3\2\2\2\u0390\u0391\7=\2\2\u0391\u00d0\3\2\2\2\u0392\u0393"+
|
||||
"\7.\2\2\u0393\u00d2\3\2\2\2\u0394\u0395\7\60\2\2\u0395\u00d4\3\2\2\2\u0396"+
|
||||
"\u0397\7?\2\2\u0397\u00d6\3\2\2\2\u0398\u0399\7@\2\2\u0399\u00d8\3\2\2"+
|
||||
"\2\u039a\u039b\7>\2\2\u039b\u00da\3\2\2\2\u039c\u039d\7#\2\2\u039d\u00dc"+
|
||||
"\3\2\2\2\u039e\u039f\7\u0080\2\2\u039f\u00de\3\2\2\2\u03a0\u03a1\7A\2"+
|
||||
"\2\u03a1\u00e0\3\2\2\2\u03a2\u03a3\7<\2\2\u03a3\u00e2\3\2\2\2\u03a4\u03a5"+
|
||||
"\7?\2\2\u03a5\u03a6\7?\2\2\u03a6\u00e4\3\2\2\2\u03a7\u03a8\7>\2\2\u03a8"+
|
||||
"\u03a9\7?\2\2\u03a9\u00e6\3\2\2\2\u03aa\u03ab\7@\2\2\u03ab\u03ac\7?\2"+
|
||||
"\2\u03ac\u00e8\3\2\2\2\u03ad\u03ae\7#\2\2\u03ae\u03af\7?\2\2\u03af\u00ea"+
|
||||
"\3\2\2\2\u03b0\u03b1\7(\2\2\u03b1\u03b2\7(\2\2\u03b2\u00ec\3\2\2\2\u03b3"+
|
||||
"\u03b4\7~\2\2\u03b4\u03b5\7~\2\2\u03b5\u00ee\3\2\2\2\u03b6\u03b7\7-\2"+
|
||||
"\2\u03b7\u03b8\7-\2\2\u03b8\u00f0\3\2\2\2\u03b9\u03ba\7/\2\2\u03ba\u03bb"+
|
||||
"\7/\2\2\u03bb\u00f2\3\2\2\2\u03bc\u03bd\7-\2\2\u03bd\u00f4\3\2\2\2\u03be"+
|
||||
"\u03bf\7/\2\2\u03bf\u00f6\3\2\2\2\u03c0\u03c1\7,\2\2\u03c1\u00f8\3\2\2"+
|
||||
"\2\u03c2\u03c3\7\61\2\2\u03c3\u00fa\3\2\2\2\u03c4\u03c5\7(\2\2\u03c5\u00fc"+
|
||||
"\3\2\2\2\u03c6\u03c7\7~\2\2\u03c7\u00fe\3\2\2\2\u03c8\u03c9\7`\2\2\u03c9"+
|
||||
"\u0100\3\2\2\2\u03ca\u03cb\7\'\2\2\u03cb\u0102\3\2\2\2\u03cc\u03cd\7-"+
|
||||
"\2\2\u03cd\u03ce\7?\2\2\u03ce\u0104\3\2\2\2\u03cf\u03d0\7/\2\2\u03d0\u03d1"+
|
||||
"\7?\2\2\u03d1\u0106\3\2\2\2\u03d2\u03d3\7,\2\2\u03d3\u03d4\7?\2\2\u03d4"+
|
||||
"\u0108\3\2\2\2\u03d5\u03d6\7\61\2\2\u03d6\u03d7\7?\2\2\u03d7\u010a\3\2"+
|
||||
"\2\2\u03d8\u03d9\7(\2\2\u03d9\u03da\7?\2\2\u03da\u010c\3\2\2\2\u03db\u03dc"+
|
||||
"\7~\2\2\u03dc\u03dd\7?\2\2\u03dd\u010e\3\2\2\2\u03de\u03df\7`\2\2\u03df"+
|
||||
"\u03e0\7?\2\2\u03e0\u0110\3\2\2\2\u03e1\u03e2\7\'\2\2\u03e2\u03e3\7?\2"+
|
||||
"\2\u03e3\u0112\3\2\2\2\u03e4\u03e5\7>\2\2\u03e5\u03e6\7>\2\2\u03e6\u03e7"+
|
||||
"\7?\2\2\u03e7\u0114\3\2\2\2\u03e8\u03e9\7@\2\2\u03e9\u03ea\7@\2\2\u03ea"+
|
||||
"\u03eb\7?\2\2\u03eb\u0116\3\2\2\2\u03ec\u03ed\7@\2\2\u03ed\u03ee\7@\2"+
|
||||
"\2\u03ee\u03ef\7@\2\2\u03ef\u03f0\7?\2\2\u03f0\u0118\3\2\2\2\u03f1\u03f5"+
|
||||
"\5\u011b\u008e\2\u03f2\u03f4\5\u011d\u008f\2\u03f3\u03f2\3\2\2\2\u03f4"+
|
||||
"\u03f7\3\2\2\2\u03f5\u03f3\3\2\2\2\u03f5\u03f6\3\2\2\2\u03f6\u011a\3\2"+
|
||||
"\2\2\u03f7\u03f5\3\2\2\2\u03f8\u03fd\t\21\2\2\u03f9\u03fd\n\22\2\2\u03fa"+
|
||||
"\u03fb\t\23\2\2\u03fb\u03fd\t\24\2\2\u03fc\u03f8\3\2\2\2\u03fc\u03f9\3"+
|
||||
"\2\2\2\u03fc\u03fa\3\2\2\2\u03fd\u011c\3\2\2\2\u03fe\u0403\t\25\2\2\u03ff"+
|
||||
"\u0403\n\22\2\2\u0400\u0401\t\23\2\2\u0401\u0403\t\24\2\2\u0402\u03fe"+
|
||||
"\3\2\2\2\u0402\u03ff\3\2\2\2\u0402\u0400\3\2\2\2\u0403\u011e\3\2\2\2\u0404"+
|
||||
"\u0405\7B\2\2\u0405\u0120\3\2\2\2\u0406\u0407\7\60\2\2\u0407\u0408\7\60"+
|
||||
"\2\2\u0408\u0409\7\60\2\2\u0409\u0122\3\2\2\2\u040a\u040c\t\26\2\2\u040b"+
|
||||
"\u040a\3\2\2\2\u040c\u040d\3\2\2\2\u040d\u040b\3\2\2\2\u040d\u040e\3\2"+
|
||||
"\2\2\u040e\u040f\3\2\2\2\u040f\u0410\b\u0092\2\2\u0410\u0124\3\2\2\2\u0411"+
|
||||
"\u0412\7\61\2\2\u0412\u0413\7,\2\2\u0413\u0417\3\2\2\2\u0414\u0416\13"+
|
||||
"\2\2\2\u0415\u0414\3\2\2\2\u0416\u0419\3\2\2\2\u0417\u0418\3\2\2\2\u0417"+
|
||||
"\u0415\3\2\2\2\u0418\u041a\3\2\2\2\u0419\u0417\3\2\2\2\u041a\u041b\7,"+
|
||||
"\2\2\u041b\u041c\7\61\2\2\u041c\u041d\3\2\2\2\u041d\u041e\b\u0093\3\2"+
|
||||
"\u041e\u0126\3\2\2\2\u041f\u0420\7\61\2\2\u0420\u0421\7\61\2\2\u0421\u0425"+
|
||||
"\3\2\2\2\u0422\u0424\n\27\2\2\u0423\u0422\3\2\2\2\u0424\u0427\3\2\2\2"+
|
||||
"\u0425\u0423\3\2\2\2\u0425\u0426\3\2\2\2\u0426\u0428\3\2\2\2\u0427\u0425"+
|
||||
"\3\2\2\2\u0428\u0429\b\u0094\3\2\u0429\u0128\3\2\2\2\64\2\u0280\u0284"+
|
||||
"\u0288\u028c\u0290\u0297\u029c\u029e\u02a4\u02a8\u02ac\u02b2\u02b7\u02c1"+
|
||||
"\u02c5\u02cb\u02cf\u02d7\u02db\u02e1\u02eb\u02ef\u02f5\u02f9\u02fe\u0301"+
|
||||
"\u0304\u0309\u030c\u0311\u0316\u031e\u0329\u032d\u0332\u0336\u0346\u0350"+
|
||||
"\u0356\u035d\u0361\u0367\u0374\u03f5\u03fc\u0402\u040d\u0417\u0425\4\b"+
|
||||
"\2\2\2\3\2";
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,201 @@
|
|||
ABSTRACT=1
|
||||
ASSERT=2
|
||||
BOOLEAN=3
|
||||
BREAK=4
|
||||
BYTE=5
|
||||
CASE=6
|
||||
CATCH=7
|
||||
CHAR=8
|
||||
CLASS=9
|
||||
CONST=10
|
||||
CONTINUE=11
|
||||
DEFAULT=12
|
||||
DO=13
|
||||
DOUBLE=14
|
||||
ELSE=15
|
||||
ENUM=16
|
||||
EXTENDS=17
|
||||
FINAL=18
|
||||
FINALLY=19
|
||||
FLOAT=20
|
||||
FOR=21
|
||||
IF=22
|
||||
GOTO=23
|
||||
IMPLEMENTS=24
|
||||
IMPORT=25
|
||||
INSTANCEOF=26
|
||||
INT=27
|
||||
INTERFACE=28
|
||||
LONG=29
|
||||
NATIVE=30
|
||||
NEW=31
|
||||
PACKAGE=32
|
||||
PRIVATE=33
|
||||
PROTECTED=34
|
||||
PUBLIC=35
|
||||
RETURN=36
|
||||
SHORT=37
|
||||
STATIC=38
|
||||
STRICTFP=39
|
||||
SUPER=40
|
||||
SWITCH=41
|
||||
SYNCHRONIZED=42
|
||||
THIS=43
|
||||
THROW=44
|
||||
THROWS=45
|
||||
TRANSIENT=46
|
||||
TRY=47
|
||||
VOID=48
|
||||
VOLATILE=49
|
||||
WHILE=50
|
||||
IntegerLiteral=51
|
||||
FloatingPointLiteral=52
|
||||
BooleanLiteral=53
|
||||
CharacterLiteral=54
|
||||
StringLiteral=55
|
||||
NullLiteral=56
|
||||
LPAREN=57
|
||||
RPAREN=58
|
||||
LBRACE=59
|
||||
RBRACE=60
|
||||
LBRACK=61
|
||||
RBRACK=62
|
||||
SEMI=63
|
||||
COMMA=64
|
||||
DOT=65
|
||||
ASSIGN=66
|
||||
GT=67
|
||||
LT=68
|
||||
BANG=69
|
||||
TILDE=70
|
||||
QUESTION=71
|
||||
COLON=72
|
||||
EQUAL=73
|
||||
LE=74
|
||||
GE=75
|
||||
NOTEQUAL=76
|
||||
AND=77
|
||||
OR=78
|
||||
INC=79
|
||||
DEC=80
|
||||
ADD=81
|
||||
SUB=82
|
||||
MUL=83
|
||||
DIV=84
|
||||
BITAND=85
|
||||
BITOR=86
|
||||
CARET=87
|
||||
MOD=88
|
||||
ADD_ASSIGN=89
|
||||
SUB_ASSIGN=90
|
||||
MUL_ASSIGN=91
|
||||
DIV_ASSIGN=92
|
||||
AND_ASSIGN=93
|
||||
OR_ASSIGN=94
|
||||
XOR_ASSIGN=95
|
||||
MOD_ASSIGN=96
|
||||
LSHIFT_ASSIGN=97
|
||||
RSHIFT_ASSIGN=98
|
||||
URSHIFT_ASSIGN=99
|
||||
Identifier=100
|
||||
AT=101
|
||||
ELLIPSIS=102
|
||||
WS=103
|
||||
COMMENT=104
|
||||
LINE_COMMENT=105
|
||||
'abstract'=1
|
||||
'assert'=2
|
||||
'boolean'=3
|
||||
'break'=4
|
||||
'byte'=5
|
||||
'case'=6
|
||||
'catch'=7
|
||||
'char'=8
|
||||
'class'=9
|
||||
'const'=10
|
||||
'continue'=11
|
||||
'default'=12
|
||||
'do'=13
|
||||
'double'=14
|
||||
'else'=15
|
||||
'enum'=16
|
||||
'extends'=17
|
||||
'final'=18
|
||||
'finally'=19
|
||||
'float'=20
|
||||
'for'=21
|
||||
'if'=22
|
||||
'goto'=23
|
||||
'implements'=24
|
||||
'import'=25
|
||||
'instanceof'=26
|
||||
'int'=27
|
||||
'interface'=28
|
||||
'long'=29
|
||||
'native'=30
|
||||
'new'=31
|
||||
'package'=32
|
||||
'private'=33
|
||||
'protected'=34
|
||||
'public'=35
|
||||
'return'=36
|
||||
'short'=37
|
||||
'static'=38
|
||||
'strictfp'=39
|
||||
'super'=40
|
||||
'switch'=41
|
||||
'synchronized'=42
|
||||
'this'=43
|
||||
'throw'=44
|
||||
'throws'=45
|
||||
'transient'=46
|
||||
'try'=47
|
||||
'void'=48
|
||||
'volatile'=49
|
||||
'while'=50
|
||||
'null'=56
|
||||
'('=57
|
||||
')'=58
|
||||
'{'=59
|
||||
'}'=60
|
||||
'['=61
|
||||
']'=62
|
||||
';'=63
|
||||
','=64
|
||||
'.'=65
|
||||
'='=66
|
||||
'>'=67
|
||||
'<'=68
|
||||
'!'=69
|
||||
'~'=70
|
||||
'?'=71
|
||||
':'=72
|
||||
'=='=73
|
||||
'<='=74
|
||||
'>='=75
|
||||
'!='=76
|
||||
'&&'=77
|
||||
'||'=78
|
||||
'++'=79
|
||||
'--'=80
|
||||
'+'=81
|
||||
'-'=82
|
||||
'*'=83
|
||||
'/'=84
|
||||
'&'=85
|
||||
'|'=86
|
||||
'^'=87
|
||||
'%'=88
|
||||
'+='=89
|
||||
'-='=90
|
||||
'*='=91
|
||||
'/='=92
|
||||
'&='=93
|
||||
'|='=94
|
||||
'^='=95
|
||||
'%='=96
|
||||
'<<='=97
|
||||
'>>='=98
|
||||
'>>>='=99
|
||||
'@'=101
|
||||
'...'=102
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,110 @@
|
|||
package it.unitn.repoman.core.lang.traversals.c;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.DFSTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import it.unitn.repoman.core.lang.parsers.c.CParser;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.TerminalNode;
|
||||
|
||||
public class CMethodCallTraversal extends MethodCallTraversal {
|
||||
|
||||
public CMethodCallTraversal(ParseTree node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
private class ParamsTraversal extends DFSTraversal {
|
||||
private Set<ParseTree> params = new HashSet<>();
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (node instanceof CParser.PrimaryExpressionContext) {
|
||||
params.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
skip--;
|
||||
if (node.getParent() instanceof CParser.InitDeclaratorListContext) {
|
||||
if (node.getChildCount() == 1) {
|
||||
try {
|
||||
this.methodContext = node.getParent().getParent();
|
||||
this.callNameNode = methodContext.getChild(0);
|
||||
ParseTree declarator = node.getChild(0).getChild(0);
|
||||
ParseTree lbrace = declarator.getChild(0);
|
||||
this.paramsNode = declarator.getChild(1);
|
||||
ParseTree rbrace = declarator.getChild(2);
|
||||
if (lbrace.getText().equals("(")) {
|
||||
if (paramsNode.getText().equals(")")) {
|
||||
this.isMethodCall = true;
|
||||
paramsNode = null;
|
||||
}
|
||||
else if (rbrace.getText().equals(")")) {
|
||||
this.isMethodCall = true;
|
||||
}
|
||||
|
||||
}
|
||||
if (paramsNode != null) {
|
||||
this.params.add(paramsNode.getChild(0));
|
||||
}
|
||||
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
this.isMethodCall = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
skip = 5;
|
||||
}
|
||||
}
|
||||
else if (node.getParent() instanceof CParser.ExpressionStatementContext
|
||||
&& !(node instanceof TerminalNode)) {
|
||||
if (node.getChild(0).getChildCount() != 1) {
|
||||
skip = 7;
|
||||
}
|
||||
else {
|
||||
skip = 1;
|
||||
}
|
||||
}
|
||||
if (skip == 0) {
|
||||
if (node instanceof CParser.PostfixExpressionContext) {
|
||||
if (node.getChild(0) instanceof CParser.PrimaryExpressionContext) {
|
||||
skip = -1;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
this.methodContext = node;
|
||||
this.callNameNode = node.getChild(0);
|
||||
ParseTree lbrace = node.getChild(1);
|
||||
this.paramsNode = node.getChild(2);
|
||||
ParseTree rbrace = node.getChild(3);
|
||||
if (lbrace.getText().equals("(")) {
|
||||
if (paramsNode.getText().equals(")")) {
|
||||
this.isMethodCall = true;
|
||||
paramsNode = null;
|
||||
}
|
||||
else if (rbrace.getText().equals(")")) {
|
||||
this.isMethodCall = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
this.isMethodCall = false;
|
||||
}
|
||||
if (this.paramsNode != null) {
|
||||
ParamsTraversal pt = new ParamsTraversal();
|
||||
pt.traverse(paramsNode);
|
||||
this.params.addAll(pt.params);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
skip++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class AssignmentSymbolExtractTraversal extends DFSTraversal {
|
||||
private ParserRuleContext stmt = null;
|
||||
private boolean isNextLeft = false;
|
||||
private ParseTree lhs = null;
|
||||
private List<ParseTree> rhs = new LinkedList<>();
|
||||
|
||||
public AssignmentSymbolExtractTraversal(ParserRuleContext ctx) {
|
||||
this.stmt = ctx;
|
||||
traverse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void traverse() {
|
||||
this.traverse(this.stmt);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (isWithinContext(node)) {
|
||||
isNextLeft = true;
|
||||
}
|
||||
if (isNextLeft) {
|
||||
if (wrapper.isTerminal(node) && wrapper.isToken(node)) {
|
||||
isNextLeft = false;
|
||||
lhs = node;
|
||||
}
|
||||
}
|
||||
else {
|
||||
SymbolExtractTraversal t = new SymbolExtractTraversal(stmt);
|
||||
rhs.addAll(t.getSymbols());
|
||||
rhs.remove(lhs);
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isWithinContext(ParseTree node) {
|
||||
return wrapper.isStatement(node.getParent()) ||
|
||||
wrapper.isFieldDeclaration(node.getParent());
|
||||
}
|
||||
|
||||
public ParseTree getLhs() {
|
||||
return lhs;
|
||||
}
|
||||
|
||||
public List<ParseTree> getRhsList() {
|
||||
return rhs;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class ConditionTraversal extends DFSTraversal {
|
||||
private Set<ParserRuleContext> innerStmts = new HashSet<>();
|
||||
|
||||
public ConditionTraversal(ParserRuleContext cnd) {
|
||||
traverse(cnd.getParent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (wrapper.isStatement(node)) {
|
||||
innerStmts.add((ParserRuleContext)node);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<ParserRuleContext> getInnerStatements() {
|
||||
return this.innerStmts;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import it.unitn.repoman.core.lang.LanguageFactory;
|
||||
import it.unitn.repoman.core.lang.wrappers.generic.Wrapper;
|
||||
import java.lang.UnsupportedOperationException;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class DFSTraversal implements Traversal {
|
||||
protected boolean isTerminated = false;
|
||||
protected ParseTree lastNode = null;
|
||||
protected Wrapper wrapper = LanguageFactory.getWrapper();
|
||||
|
||||
@Override
|
||||
public void traverse(ParseTree root) {
|
||||
if (root == null) {
|
||||
return;
|
||||
}
|
||||
for (int i=0; i < root.getChildCount(); i++) {
|
||||
if (isTerminated) {
|
||||
onTerminate();
|
||||
break;
|
||||
}
|
||||
lastNode = root.getChild(i);
|
||||
onEnterNode(lastNode);
|
||||
traverse(lastNode);
|
||||
onExitNode(lastNode);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void traverse() {
|
||||
throw new UnsupportedOperationException("ERROR: This method is not implemented!");
|
||||
}
|
||||
|
||||
protected boolean isWithinContext(ParseTree node) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onExitNode(ParseTree node) {
|
||||
}
|
||||
|
||||
protected void onTerminate() {
|
||||
}
|
||||
|
||||
protected void terminate() {
|
||||
this.isTerminated = true;
|
||||
}
|
||||
|
||||
public ParseTree getLastNode() {
|
||||
return this.lastNode;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class DotSymbolTraversal extends DFSTraversal{
|
||||
|
||||
private ParseTree rightmostNode = null;
|
||||
private List<ParseTree> nodes = new LinkedList<>();
|
||||
|
||||
public DotSymbolTraversal(ParseTree root) {
|
||||
traverse(root);
|
||||
rightmostNode = nodes.get(nodes.size()-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (wrapper.isTerminal(node)) {
|
||||
if (!node.getText().equals(".")) {
|
||||
nodes.add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ParseTree getRightmostNode() {
|
||||
return rightmostNode;
|
||||
}
|
||||
|
||||
public String getRightmostNodeName() {
|
||||
return (rightmostNode != null) ? rightmostNode.getText() : "";
|
||||
}
|
||||
|
||||
public List<ParseTree> getLeftNodes() {
|
||||
List<ParseTree> leftNodes = new LinkedList<>();
|
||||
leftNodes.addAll(nodes);
|
||||
if (rightmostNode != null) {
|
||||
leftNodes.remove(rightmostNode);
|
||||
}
|
||||
return leftNodes;
|
||||
}
|
||||
|
||||
public List<String> getLeftNodesNames() {
|
||||
List<String> leftNodesNames = new LinkedList<>();
|
||||
for (ParseTree node : getLeftNodes()) {
|
||||
leftNodesNames.add(node.getText());
|
||||
}
|
||||
return leftNodesNames;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import it.unitn.repoman.core.lang.parsers.java.JavaParser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class FormalParameterTraversal extends DFSTraversal {
|
||||
|
||||
private ParseTree type;
|
||||
private ParseTree variable;
|
||||
|
||||
public FormalParameterTraversal(ParserRuleContext ctx) {
|
||||
if (wrapper.isFormalParameter(ctx)) {
|
||||
traverse(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (node.getClass().equals(JavaParser.TypeTypeContext.class)) {
|
||||
type = node;
|
||||
}
|
||||
else if (node.getClass().equals(JavaParser.VariableDeclaratorIdContext.class)) {
|
||||
variable = node;
|
||||
}
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return type.getText();
|
||||
}
|
||||
|
||||
public String getVariableName() {
|
||||
return variable.getText();
|
||||
}
|
||||
|
||||
public ParseTree getTypeTerminalNode() {
|
||||
return type.getChild(0);
|
||||
}
|
||||
|
||||
public ParseTree getTypeNode() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public ParseTree getVariableTerminalNode() {
|
||||
return variable.getChild(0);
|
||||
}
|
||||
|
||||
public ParseTree getVariableNode() {
|
||||
return variable;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
|
||||
public abstract class MethodCallTraversal extends DFSTraversal {
|
||||
protected boolean isMethodCall = false;
|
||||
protected ParseTree callNameNode = null;
|
||||
protected ParseTree paramsNode = null;
|
||||
protected final List<ParseTree> params = new LinkedList<>();
|
||||
protected final List<String> paramNames = new LinkedList<>();
|
||||
protected final int numberOfParams;
|
||||
protected int skip = -1;
|
||||
protected ParseTree methodContext = null;
|
||||
|
||||
|
||||
public MethodCallTraversal(ParseTree node) {
|
||||
traverse(node);
|
||||
for (ParseTree t : params) {
|
||||
if (wrapper.isToken(t)) {
|
||||
paramNames.add(t.getText());
|
||||
}
|
||||
}
|
||||
numberOfParams = params.size();
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return (callNameNode != null) ? callNameNode.getText() : "";
|
||||
}
|
||||
|
||||
public int getParamsNumber() {
|
||||
return numberOfParams;
|
||||
}
|
||||
|
||||
public ParseTree getCallNameNode() {
|
||||
return this.callNameNode;
|
||||
}
|
||||
|
||||
public List<ParseTree> getParams() {
|
||||
return this.params;
|
||||
}
|
||||
|
||||
public List<String> getParamNames() {
|
||||
return paramNames;
|
||||
}
|
||||
|
||||
public ParseTree getParamsNode() {
|
||||
return this.paramsNode;
|
||||
}
|
||||
|
||||
public boolean isMethodCall() {
|
||||
return this.isMethodCall;
|
||||
}
|
||||
|
||||
public ParseTree getMethodContextNode() {
|
||||
return this.methodContext;
|
||||
}
|
||||
|
||||
public String getParamName(int pos) {
|
||||
return getParamNames().get(pos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
public class MethodDeclarationTraversal extends DFSTraversal {
|
||||
|
||||
private ParseTree methodName = null;
|
||||
private ParseTree returnType = null;
|
||||
private List<String> paramNames = new LinkedList<>();
|
||||
private List<ParseTree> paramNodes = new LinkedList<>();
|
||||
private final List<ParserRuleContext> parameters = new LinkedList<>();
|
||||
|
||||
public MethodDeclarationTraversal(ParserRuleContext ctx) {
|
||||
if (wrapper.isMethodDeclaration(ctx)) {
|
||||
traverse(ctx);
|
||||
} // or else throw an exception?
|
||||
for (ParserRuleContext param : parameters) {
|
||||
FormalParameterTraversal t = new FormalParameterTraversal(param);
|
||||
paramNames.add(t.getVariableName());
|
||||
paramNodes.add(t.getVariableTerminalNode());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (returnType == null && wrapper.isTerminal(node)) {
|
||||
returnType = node;
|
||||
}
|
||||
else if (methodName == null && wrapper.isTerminal(node)) {
|
||||
methodName = node;
|
||||
}
|
||||
else if (methodName != null && returnType != null){
|
||||
if (wrapper.isFormalParameter(node)) {
|
||||
parameters.add((ParserRuleContext) node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getMethodName() {
|
||||
return methodName.getText();
|
||||
}
|
||||
|
||||
public String getReturnType() {
|
||||
return returnType.getText();
|
||||
}
|
||||
|
||||
public List<String> getParamNames() {
|
||||
return paramNames;
|
||||
}
|
||||
|
||||
public int getParamsNumber() {
|
||||
return parameters.size();
|
||||
}
|
||||
|
||||
public String getParamName(int pos) {
|
||||
return paramNames.get(pos);
|
||||
}
|
||||
|
||||
public ParseTree getParamNode(int pos) {
|
||||
return paramNodes.get(pos);
|
||||
}
|
||||
|
||||
public ParseTree getParam(int pos) {
|
||||
return parameters.get(pos);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class NodeContainmentTraversal extends DFSTraversal {
|
||||
|
||||
private boolean isFound = false;
|
||||
private final ParseTree soughtNode;
|
||||
|
||||
public NodeContainmentTraversal(ParserRuleContext root, ParseTree node) {
|
||||
soughtNode = node;
|
||||
traverse(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (node.equals(soughtNode)) {
|
||||
isFound = true;
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isFound() {
|
||||
return isFound;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class ScopesTraversal extends DFSTraversal {
|
||||
private Set<ParserRuleContext> fields = new HashSet<>();
|
||||
private Set<ParserRuleContext> methods = new HashSet<>();
|
||||
private int currentLine = 0;
|
||||
private int totalLines = 0;
|
||||
private final Set<Integer> collectableLines = new HashSet<>();
|
||||
|
||||
public ScopesTraversal(ParserRuleContext root) {
|
||||
traverse(root);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
//collect all "collectable" lines
|
||||
if (wrapper.isCollectable(node)) {
|
||||
int line = ((ParserRuleContext)node).getStart().getLine();
|
||||
this.collectableLines.add(line);
|
||||
}
|
||||
if (wrapper.isRuleContext(node)) {
|
||||
int lookupLine = ((ParserRuleContext)node).getStart().getLine();
|
||||
if (currentLine != lookupLine) {
|
||||
currentLine = lookupLine;
|
||||
this.totalLines++;
|
||||
}
|
||||
}
|
||||
if (wrapper.isFieldDeclaration(node)) {
|
||||
fields.add((ParserRuleContext)node);
|
||||
}
|
||||
if (wrapper.isMethodDeclaration(node)) {
|
||||
methods.add((ParserRuleContext)node);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<ParserRuleContext> getScopes() {
|
||||
return this.methods;
|
||||
}
|
||||
|
||||
public Set<ParserRuleContext> getFields() {
|
||||
return this.fields;
|
||||
}
|
||||
|
||||
public int getTotalLinesCount() {
|
||||
return this.totalLines;
|
||||
}
|
||||
|
||||
public Set<Integer> getCollectableLines() {
|
||||
return this.collectableLines;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import it.unitn.repoman.core.exceptions.InvalidLineException;
|
||||
|
||||
public final class SeedTraversal extends DFSTraversal {
|
||||
private ParserRuleContext seedScope = null;
|
||||
private ParserRuleContext seedStmt = null;
|
||||
private int seedLine;
|
||||
|
||||
public SeedTraversal(int line) {
|
||||
this.seedLine = line;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (wrapper.isMethodDeclaration(node)) {
|
||||
this.seedScope = (ParserRuleContext)node;
|
||||
}
|
||||
if (wrapper.isCollectable(node)) {
|
||||
ParserRuleContext nodeCtx = (ParserRuleContext)node;
|
||||
if (this.seedStmt == null && nodeCtx.getStart().getLine() == this.seedLine) {
|
||||
this.seedStmt = (ParserRuleContext)node;
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ParserRuleContext getSeedScope() throws InvalidLineException {
|
||||
return this.seedScope;
|
||||
}
|
||||
|
||||
public ParserRuleContext getSeedStmt() throws InvalidLineException {
|
||||
return this.seedStmt;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class StatementMappingTraversal extends DFSTraversal {
|
||||
|
||||
private final Set<ParserRuleContext> methodDeclarations = new LinkedHashSet<>();
|
||||
private final Set<ParserRuleContext> statements = new LinkedHashSet<>();
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (wrapper.isCollectable(node)) {
|
||||
this.statements.add((ParserRuleContext) node);
|
||||
}
|
||||
else if (wrapper.isMethodDeclaration(node)) {
|
||||
this.methodDeclarations.add((ParserRuleContext) node);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<ParserRuleContext> getStatements() {
|
||||
return this.statements;
|
||||
}
|
||||
|
||||
public Set<ParserRuleContext> getMethodDeclarations() {
|
||||
return this.methodDeclarations;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class SymbolExtractTraversal extends DFSTraversal {
|
||||
|
||||
private Set<ParseTree> symbols = new LinkedHashSet<>();
|
||||
|
||||
public SymbolExtractTraversal(ParserRuleContext ctx) {
|
||||
MethodCallTraversal t = wrapper.getMethodCallTraversal(ctx);
|
||||
if (!t.isMethodCall()) {
|
||||
traverse(ctx);
|
||||
}
|
||||
else {
|
||||
this.symbols.addAll(t.getParams());
|
||||
DotSymbolTraversal dott = new DotSymbolTraversal(t.getCallNameNode());
|
||||
symbols.addAll(dott.getLeftNodes());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (isWithinContext(node) && wrapper.isToken(node) && wrapper.isToken(node)) {
|
||||
symbols.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isWithinContext(ParseTree node) {
|
||||
return wrapper.isTerminal(node);
|
||||
}
|
||||
|
||||
public Set<ParseTree> getSymbols() {
|
||||
return this.symbols;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package it.unitn.repoman.core.lang.traversals.generic;
|
||||
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public interface Traversal {
|
||||
void traverse(ParseTree startNode);
|
||||
void onEnterNode(ParseTree node);
|
||||
void onExitNode(ParseTree node);
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package it.unitn.repoman.core.lang.traversals.java;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import it.unitn.repoman.core.lang.traversals.generic.DFSTraversal;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import it.unitn.repoman.core.lang.parsers.java.JavaParser;
|
||||
|
||||
public class JavaAPISignatureTraversal extends DFSTraversal {
|
||||
protected final Set<String> signatures = new HashSet<>();
|
||||
|
||||
public JavaAPISignatureTraversal(ParseTree node) {
|
||||
traverse(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (wrapper.isMethodDeclaration(node)) {
|
||||
ParserRuleContext method = (ParserRuleContext) node;
|
||||
this.signatures.add(getMethodSignature(method));
|
||||
}
|
||||
}
|
||||
|
||||
public String getMethodSignature(ParserRuleContext method) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
if (wrapper.isMethodDeclaration(method)) {
|
||||
ParserRuleContext declRoot = method.getParent().getParent();
|
||||
for (int i=0; i<declRoot.getChildCount(); i++) {
|
||||
ParseTree node = declRoot.getChild(i);
|
||||
if (node.getClass().equals(JavaParser.ModifierContext.class)) {
|
||||
builder.append(node.getText());
|
||||
}
|
||||
}
|
||||
for (int i=0; i<method.getChildCount(); i++) {
|
||||
ParseTree node = method.getChild(i);
|
||||
if (wrapper.isTerminal(node) || node.getClass().equals(JavaParser.TypeTypeContext.class)
|
||||
|| node.getClass().equals(JavaParser.FormalParametersContext.class)) {
|
||||
builder.append(node.getText());
|
||||
}
|
||||
}
|
||||
return refineSignature(builder.toString());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean methodSignatureExists(String signature) {
|
||||
signature = refineSignature(signature);
|
||||
for (String s : signatures) {
|
||||
if (s.equals(signature)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
public boolean isPublicMethod(String signature) {
|
||||
signature = refineSignature(signature);
|
||||
return signature.startsWith("public");
|
||||
}
|
||||
|
||||
public boolean isProtectedMethod(String signature) {
|
||||
signature = refineSignature(signature);
|
||||
return signature.startsWith("protected");
|
||||
}
|
||||
|
||||
public boolean isPrivateMethod(String signature) {
|
||||
signature = refineSignature(signature);
|
||||
return signature.startsWith("private");
|
||||
}
|
||||
|
||||
protected String refineSignature(String signature) {
|
||||
int closingBracketPosition = signature.indexOf(")");
|
||||
if (closingBracketPosition != -1) {
|
||||
return signature.replace(signature.substring(signature.indexOf(")")), ")").replace("@Override", "");
|
||||
}
|
||||
return signature;
|
||||
}
|
||||
|
||||
public int getSignaturesCount() {
|
||||
return this.signatures.size();
|
||||
}
|
||||
|
||||
public Set<String> getPublicSignatures() {
|
||||
Set<String> s = new HashSet<>();
|
||||
for (String signature : this.signatures) {
|
||||
if (this.isPublicMethod(signature)) {
|
||||
s.add(signature);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public Set<String> getProtectedSignatures() {
|
||||
Set<String> s = new HashSet<>();
|
||||
for (String signature : this.signatures) {
|
||||
if (this.isProtectedMethod(signature)) {
|
||||
s.add(signature);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public Set<String> getPrivateSignatures() {
|
||||
Set<String> s = new HashSet<>();
|
||||
for (String signature : this.signatures) {
|
||||
if (this.isPrivateMethod(signature)) {
|
||||
s.add(signature);
|
||||
}
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
public Set<String> getSignatures() {
|
||||
return this.signatures;
|
||||
}
|
||||
|
||||
|
||||
public int getPublicSignaturesCount() {
|
||||
return this.getPublicSignatures().size();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package it.unitn.repoman.core.lang.traversals.java;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import it.unitn.repoman.core.lang.traversals.generic.DotSymbolTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.DFSTraversal;
|
||||
import it.unitn.repoman.core.lang.parsers.java.JavaParser;
|
||||
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class JavaMethodCallTraversal extends MethodCallTraversal {
|
||||
|
||||
public JavaMethodCallTraversal(ParseTree node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
private class ParamsTraversal extends DFSTraversal {
|
||||
private List<ParseTree> params = new LinkedList<>();
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (node.getClass().equals(JavaParser.ExpressionContext.class) &&
|
||||
node.getParent().getClass().equals(JavaParser.ExpressionListContext.class)) {
|
||||
SingleParamTraversal t = new SingleParamTraversal();
|
||||
t.traverse(node);
|
||||
if (t.paramName != null) {
|
||||
params.add(t.paramName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private class SingleParamTraversal extends DFSTraversal {
|
||||
private ParseTree paramName = null;
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
if (wrapper.isTerminal(node) && wrapper.isToken(node)) {
|
||||
paramName = node;
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnterNode(ParseTree node) {
|
||||
skip--;
|
||||
if (node.getClass().equals(JavaParser.LocalVariableDeclarationContext.class)) {
|
||||
skip = 10;
|
||||
}
|
||||
if (node.getClass().equals(JavaParser.StatementExpressionContext.class)) {
|
||||
if (node.getChild(0).getChild(1).getText().equals("(")) {
|
||||
skip = 1;
|
||||
}
|
||||
else {
|
||||
skip = 6;
|
||||
}
|
||||
}
|
||||
else if (node.getClass().equals(JavaParser.ExpressionContext.class)) {
|
||||
if (node.getChild(1) != null && node.getChild(1).getText().equals("(")) {
|
||||
skip = 0;
|
||||
}
|
||||
else {
|
||||
skip = 5;
|
||||
}
|
||||
}
|
||||
|
||||
if (skip == 0) {
|
||||
try {
|
||||
this.methodContext = node;
|
||||
this.callNameNode = node.getChild(0);
|
||||
ParseTree lbrace = node.getChild(1);
|
||||
this.paramsNode = node.getChild(2);
|
||||
ParseTree rbrace = node.getChild(3);
|
||||
|
||||
if (lbrace.getText().equals("(")) {
|
||||
if (paramsNode.getText().equals(")")) {
|
||||
this.isMethodCall = true;
|
||||
paramsNode = null;
|
||||
} else if (rbrace.getText().equals(")")) {
|
||||
this.isMethodCall = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (paramsNode != null) {
|
||||
ParamsTraversal pt = new ParamsTraversal();
|
||||
pt.traverse(paramsNode);
|
||||
for (ParseTree param : pt.params) {
|
||||
if (wrapper.isToken(param)) {
|
||||
this.params.add(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NullPointerException e) {
|
||||
this.isMethodCall = false;
|
||||
}
|
||||
finally {
|
||||
terminate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodName() {
|
||||
if (callNameNode != null) {
|
||||
DotSymbolTraversal t = new DotSymbolTraversal(callNameNode);
|
||||
return t.getRightmostNodeName();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,103 @@
|
|||
package it.unitn.repoman.core.lang.wrappers.c;
|
||||
|
||||
import it.unitn.repoman.core.lang.traversals.c.CMethodCallTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import it.unitn.repoman.core.lang.wrappers.generic.Wrapper;
|
||||
import it.unitn.repoman.core.lang.parsers.c.CParser;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.TerminalNodeImpl;
|
||||
|
||||
|
||||
public class CWrapper extends Wrapper {
|
||||
|
||||
public CWrapper() {
|
||||
this.restrictedKeywords = new String[]{ "return", "true", "false"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatement(ParseTree node) {
|
||||
return node instanceof CParser.DeclarationContext ||
|
||||
node instanceof CParser.ExpressionStatementContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReturnStatement(ParseTree node) {
|
||||
return (node instanceof CParser.JumpStatementContext && node.getChild(0).getText().equals("return"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConditionalExpression(ParseTree node) {
|
||||
return (node instanceof CParser.ExpressionContext &&
|
||||
node.getParent() instanceof CParser.SelectionStatementContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMethodDeclaration(ParseTree node) {
|
||||
return node instanceof CParser.FunctionDefinitionContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFieldDeclaration(ParseTree node) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToken(ParseTree node) {
|
||||
Pattern pattern = Pattern.compile(this.validVarNameRegex);
|
||||
Matcher matcher = pattern.matcher(node.getText());
|
||||
return (!isRestrictedKeyword(node) && matcher.matches() &&
|
||||
node instanceof TerminalNodeImpl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormalParameter(ParseTree node) {
|
||||
return node instanceof CParser.DeclaratorContext &&
|
||||
node.getParent() instanceof CParser.ParameterDeclarationContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMethodDeclarationName(ParseTree node) {
|
||||
return node.getChild(1).getChild(0).getChild(0).getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ParseTree getMethodDeclarationParams(ParseTree node) {
|
||||
return node.getChild(1).getChild(0).getChild(2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodCallTraversal getMethodCallTraversal(ParseTree node) {
|
||||
return new CMethodCallTraversal(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTerminal(ParseTree node) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocalVariableDeclaration(ParseTree node) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignmentExpression(ParseTree node) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: implement the method
|
||||
@Override
|
||||
public boolean isPartOfExpression(ParseTree node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
package it.unitn.repoman.core.lang.wrappers.generic;
|
||||
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.SymbolExtractTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.AssignmentSymbolExtractTraversal;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public abstract class Wrapper {
|
||||
|
||||
protected String validVarNameRegex = "[A-Za-z_][A-Za-z_0-9]*$";
|
||||
|
||||
protected String[] restrictedKeywords = {""};
|
||||
|
||||
public abstract boolean isTerminal(ParseTree node);
|
||||
|
||||
public abstract boolean isStatement(ParseTree node);
|
||||
|
||||
public abstract boolean isLocalVariableDeclaration(ParseTree node);
|
||||
|
||||
public abstract boolean isAssignmentExpression(ParseTree node);
|
||||
|
||||
public abstract boolean isPartOfExpression(ParseTree node);
|
||||
|
||||
public abstract boolean isReturnStatement(ParseTree node);
|
||||
|
||||
public abstract boolean isConditionalExpression(ParseTree node);
|
||||
|
||||
public abstract boolean isMethodDeclaration(ParseTree node);
|
||||
|
||||
public abstract boolean isFieldDeclaration(ParseTree node);
|
||||
|
||||
public abstract boolean isToken(ParseTree node);
|
||||
|
||||
public abstract boolean isFormalParameter(ParseTree node);
|
||||
|
||||
|
||||
protected abstract String getMethodDeclarationName(ParseTree node);
|
||||
|
||||
protected abstract ParseTree getMethodDeclarationParams(ParseTree node);
|
||||
|
||||
public boolean isClassDeclaration(ParseTree node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isTypeDeclaration(ParseTree node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isCollectable(ParseTree node) {
|
||||
if (!(node instanceof ParserRuleContext)) {
|
||||
return false;
|
||||
}
|
||||
return (this.isStatement(node) ||
|
||||
this.isConditionalExpression(node) ||
|
||||
this.isReturnStatement(node) ||
|
||||
this.isFieldDeclaration(node));
|
||||
}
|
||||
|
||||
public boolean isRuleContext(ParseTree node) {
|
||||
return node instanceof ParserRuleContext;
|
||||
}
|
||||
|
||||
protected boolean isRestrictedKeyword(ParseTree node) {
|
||||
for (int i = 0; i < this.restrictedKeywords.length; i++) {
|
||||
if (this.restrictedKeywords[i].equals(node.getText())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public ParseTree getDefinedVar(ParserRuleContext stmt) {
|
||||
ParseTree defVar = null;
|
||||
if (this.isLocalVariableDeclaration(stmt) || this.isAssignmentExpression(stmt) ||
|
||||
this.isFieldDeclaration(stmt)) {
|
||||
AssignmentSymbolExtractTraversal traversal = new AssignmentSymbolExtractTraversal(stmt);
|
||||
defVar = traversal.getLhs();
|
||||
}
|
||||
return defVar;
|
||||
}
|
||||
|
||||
public Set<ParseTree> getReferencedVars(ParserRuleContext stmt) {
|
||||
Set<ParseTree> refVars = new LinkedHashSet<>();
|
||||
if (isLocalVariableDeclaration(stmt) || isAssignmentExpression(stmt) || isFieldDeclaration(stmt)) {
|
||||
AssignmentSymbolExtractTraversal traversal = new AssignmentSymbolExtractTraversal(stmt);
|
||||
for (ParseTree var : traversal.getRhsList()) {
|
||||
refVars.add(var);
|
||||
}
|
||||
}
|
||||
else if (isConditionalExpression(stmt) || isMethodCall(stmt) || isReturnStatement(stmt)) {
|
||||
SymbolExtractTraversal traversal = new SymbolExtractTraversal(stmt);
|
||||
for (ParseTree var : traversal.getSymbols()) {
|
||||
refVars.add(var);
|
||||
}
|
||||
}
|
||||
return refVars;
|
||||
}
|
||||
|
||||
public ParserRuleContext getContainer(ParseTree ctx) {
|
||||
ParseTree c = ctx.getParent();
|
||||
while (!isTypeDeclaration(c)) {
|
||||
if (isMethodDeclaration(c)) {
|
||||
return (ParserRuleContext)c;
|
||||
}
|
||||
c = c.getParent();
|
||||
}
|
||||
return (ParserRuleContext)c;
|
||||
}
|
||||
|
||||
public boolean precedes(ParserRuleContext stmt1, ParserRuleContext stmt2) {
|
||||
if (stmt1 == null || stmt2 == null) {
|
||||
return false;
|
||||
}
|
||||
return (stmt1.getStart().getLine() < stmt2.getStart().getLine());
|
||||
}
|
||||
|
||||
|
||||
public Collection<? extends ParseTree> getExternalSeeds(ParseTree method, ParseTree decl) {
|
||||
// TODO Auto-generated method stub
|
||||
final Set<ParseTree> seeds = new HashSet<>();
|
||||
return seeds;
|
||||
}
|
||||
|
||||
public abstract MethodCallTraversal getMethodCallTraversal(ParseTree node);
|
||||
|
||||
public boolean isMethodCall(ParseTree stmt) {
|
||||
MethodCallTraversal traversal = this.getMethodCallTraversal(stmt);
|
||||
return traversal.isMethodCall();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
package it.unitn.repoman.core.lang.wrappers.java;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import it.unitn.repoman.core.lang.wrappers.generic.Wrapper;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import org.antlr.v4.runtime.tree.TerminalNodeImpl;
|
||||
|
||||
import it.unitn.repoman.core.lang.traversals.java.JavaMethodCallTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import it.unitn.repoman.core.lang.parsers.java.JavaParser;
|
||||
|
||||
public class JavaWrapper extends Wrapper {
|
||||
|
||||
public JavaWrapper() {
|
||||
this.restrictedKeywords = new String[]{"true", "false", "return", "null", "new", "this"};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatement(ParseTree node) {
|
||||
return node.getClass().equals(JavaParser.StatementExpressionContext.class) ||
|
||||
node.getClass().equals(JavaParser.LocalVariableDeclarationContext.class) ||
|
||||
node.getClass().equals(JavaParser.FieldDeclarationContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReturnStatement(ParseTree node) {
|
||||
return (node.getClass().equals(JavaParser.StatementContext.class) && node.getChild(0).getText().equals("return"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isConditionalExpression(ParseTree node) {
|
||||
return node.getClass().equals(JavaParser.ParExpressionContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMethodDeclaration(ParseTree node) {
|
||||
return node.getClass().equals(JavaParser.MethodDeclarationContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isClassDeclaration(ParseTree node) {
|
||||
return node.getClass().equals(JavaParser.ClassDeclarationContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTypeDeclaration(ParseTree node) {
|
||||
return node.getClass().equals(JavaParser.TypeDeclarationContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFieldDeclaration(ParseTree node) {
|
||||
return node.getClass().equals(JavaParser.FieldDeclarationContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isToken(ParseTree node) {
|
||||
Pattern pattern = Pattern.compile(this.validVarNameRegex);
|
||||
Matcher matcher = pattern.matcher(node.getText());
|
||||
return (!isRestrictedKeyword(node) && matcher.matches() &&
|
||||
!(node.getParent().getClass().equals(JavaParser.ClassOrInterfaceTypeContext.class)) &&
|
||||
!(node.getParent().getClass().equals(JavaParser.PrimitiveTypeContext.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isFormalParameter(ParseTree node) {
|
||||
return node.getClass().equals(JavaParser.FormalParameterContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getMethodDeclarationName(ParseTree node) {
|
||||
return node.getChild(1).getText();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ParseTree getMethodDeclarationParams(ParseTree node) {
|
||||
return node.getChild(2).getChild(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodCallTraversal getMethodCallTraversal(ParseTree node) {
|
||||
return new JavaMethodCallTraversal(node.getParent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isTerminal(ParseTree node) {
|
||||
return node.getClass().equals(TerminalNodeImpl.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLocalVariableDeclaration(ParseTree node) {
|
||||
return node.getClass().equals(JavaParser.LocalVariableDeclarationContext.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAssignmentExpression(ParseTree node) {
|
||||
if (node.getClass().equals(JavaParser.StatementExpressionContext.class)) {
|
||||
ParseTree child = node.getChild(0);
|
||||
if (child.getChildCount() > 1) {
|
||||
child = child.getChild(1);
|
||||
if (child.getText().equals("=")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPartOfExpression(ParseTree node) {
|
||||
return node.getClass().equals(JavaParser.ExpressionContext.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
package it.unitn.repoman.core.slicers;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import it.unitn.repoman.core.lang.LanguageFactory;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodDeclarationTraversal;
|
||||
import it.unitn.repoman.core.slicers.tainters.BackwardTainter;
|
||||
import it.unitn.repoman.core.slicers.tainters.ForwardTainter;
|
||||
import it.unitn.repoman.core.slicers.tainters.TaintedVariableSet;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.StatementMappingTraversal;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class LightweightSlice {
|
||||
|
||||
protected final ParserRuleContext root;
|
||||
protected final Set<Integer> selectedLines = new LinkedHashSet<>();
|
||||
protected final Set<ParserRuleContext> collectables;
|
||||
protected final Set<ParserRuleContext> methodDeclarations;
|
||||
|
||||
public LightweightSlice(ParserRuleContext root, Set<Integer> lines) throws Exception {
|
||||
this.root = root;
|
||||
StatementMappingTraversal statementGetter = new StatementMappingTraversal();
|
||||
statementGetter.traverse(this.root);
|
||||
|
||||
collectables = statementGetter.getStatements();
|
||||
methodDeclarations = statementGetter.getMethodDeclarations();
|
||||
|
||||
Set<Integer> toAdd = new LinkedHashSet<>();
|
||||
toAdd.addAll(makePass(lines));
|
||||
|
||||
selectedLines.addAll(toAdd);
|
||||
}
|
||||
|
||||
protected Set<Integer> makePass(Set<Integer> lines) {
|
||||
Set<Integer> matchedLines = new LinkedHashSet<>();
|
||||
Set<ParserRuleContext> statements = new LinkedHashSet<>();
|
||||
for (ParserRuleContext stmt : collectables) {
|
||||
if (lines.contains(stmt.getStart().getLine())) {
|
||||
statements.add(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
ForwardTainter forwardTainter = new ForwardTainter(collectables, statements);
|
||||
matchedLines.addAll(forwardTainter.getCollectedLines());
|
||||
|
||||
BackwardTainter backwardTainter = new BackwardTainter(collectables, statements);
|
||||
matchedLines.addAll(backwardTainter.getCollectedLines());
|
||||
|
||||
/* TODO: Experimental
|
||||
Set<Integer> inter = propagrateForwardTaint(collectables, methodDeclarations, forwardTainter);
|
||||
matchedLines.addAll(inter);
|
||||
*/
|
||||
return matchedLines;
|
||||
}
|
||||
|
||||
// TODO: Experimental
|
||||
protected Set<Integer> propagrateForwardTaint(Set<ParserRuleContext> collectables, Set<ParserRuleContext> methodDeclarations, ForwardTainter forwardTainter) {
|
||||
|
||||
Set<Integer> collected = new LinkedHashSet<>();
|
||||
|
||||
// get intra-procedural tainted variables
|
||||
TaintedVariableSet taintedVars = forwardTainter.getTaintedVars();
|
||||
|
||||
// get intra-procedural tainted method calls
|
||||
Set<ParserRuleContext> taintedMethodCalls = forwardTainter.getTaintedMethodCalls();
|
||||
|
||||
// match a tainted method call to the corresponding method declaration
|
||||
for (ParserRuleContext tmc : taintedMethodCalls) {
|
||||
MethodCallTraversal t1 = LanguageFactory.getWrapper().getMethodCallTraversal(tmc);
|
||||
String methodCallName = t1.getMethodName();
|
||||
for (ParserRuleContext md : methodDeclarations) {
|
||||
MethodDeclarationTraversal t2 = new MethodDeclarationTraversal(md);
|
||||
String methodDeclName = t2.getMethodName();
|
||||
if (methodCallName.equals(methodDeclName) && t1.getParamsNumber() == t2.getParamsNumber()) {
|
||||
// ---------------- inter-procedural "expansion" goes here ----------------------------------------
|
||||
// get tainted variables for the method call statement
|
||||
List<ParseTree> vars = forwardTainter.getTaintedVars().getStatementVariables((ParserRuleContext) t1.getMethodContextNode());
|
||||
// keep only tainted parameters
|
||||
List<String> taintedParams = new LinkedList<>();
|
||||
List<String> params = t1.getParamNames();
|
||||
for (int i=0; i<t1.getParamsNumber(); i++) {
|
||||
String param = t1.getParamName(i);
|
||||
boolean match = false;
|
||||
for (ParseTree var : vars) {
|
||||
if (param.equals(var.getText())) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (match) {
|
||||
taintedParams.add(param);
|
||||
}
|
||||
else {
|
||||
taintedParams.add("NOT_TAINTED");
|
||||
}
|
||||
}
|
||||
|
||||
// match tainted parameters to aliases in the method declaration
|
||||
List<ParseTree> matchedTaintedParams = new LinkedList<>();
|
||||
for (int i=0; i<taintedParams.size(); i++) {
|
||||
String callParam = taintedParams.get(i);
|
||||
String declParam = t2.getParamNames().get(i);
|
||||
if (!callParam.equals("NOT_TAINTED")) {
|
||||
matchedTaintedParams.add(t2.getParamNode(i));
|
||||
}
|
||||
}
|
||||
|
||||
// taint relevant stuff within the method declaration...
|
||||
ForwardTainter expandedFt = new ForwardTainter(collectables, matchedTaintedParams);
|
||||
collected.addAll(expandedFt.getCollectedLines());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return collected;
|
||||
}
|
||||
|
||||
public Set<Integer> getSelectedLines() {
|
||||
return this.selectedLines;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package it.unitn.repoman.core.slicers;
|
||||
|
||||
import it.unitn.repoman.core.slicers.tainters.BackwardTainterPessimist;
|
||||
import it.unitn.repoman.core.slicers.tainters.ForwardTainterPessimist;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class LightweightSlicePessimist extends LightweightSlice {
|
||||
|
||||
public LightweightSlicePessimist(ParserRuleContext root, Set<Integer> lines) throws Exception {
|
||||
super(root, lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<Integer> makePass(Set<Integer> lines) {
|
||||
Set<Integer> matchedLines = new LinkedHashSet<>();
|
||||
Set<ParserRuleContext> statements = new LinkedHashSet<>();
|
||||
for (ParserRuleContext stmt : collectables) {
|
||||
if (lines.contains(stmt.getStart().getLine())) {
|
||||
statements.add(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
ForwardTainterPessimist forwardTainter = new ForwardTainterPessimist(collectables, statements);
|
||||
matchedLines.addAll(forwardTainter.getCollectedLines());
|
||||
|
||||
BackwardTainterPessimist backwardTainter = new BackwardTainterPessimist(collectables, statements);
|
||||
matchedLines.addAll(backwardTainter.getCollectedLines());
|
||||
|
||||
return matchedLines;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package it.unitn.repoman.core.slicers.tainters;
|
||||
|
||||
import it.unitn.repoman.core.lang.LanguageFactory;
|
||||
import it.unitn.repoman.core.lang.wrappers.generic.Wrapper;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public abstract class AbstractTainter {
|
||||
|
||||
protected final Wrapper wrapper = LanguageFactory.getWrapper();
|
||||
protected final Set<ParserRuleContext> collectables;
|
||||
protected final TaintedVariableSet taints = new TaintedVariableSet();
|
||||
protected final Set<ParserRuleContext> taintedStatements = new LinkedHashSet<>();
|
||||
|
||||
public AbstractTainter(Set<ParserRuleContext> collectables, List<ParseTree> taintedVars) {
|
||||
this.collectables = collectables;
|
||||
Set<ParserRuleContext> seeds = new LinkedHashSet<>();
|
||||
|
||||
for (ParseTree taintedVar : taintedVars) {
|
||||
ParserRuleContext taintedVarScope = wrapper.getContainer(taintedVar);
|
||||
taints.addTaintedVariable(taintedVarScope, taintedVar);
|
||||
|
||||
for (ParserRuleContext collectable : collectables) {
|
||||
ParserRuleContext collectableScope = wrapper.getContainer(collectable);
|
||||
if (taintedVarScope.equals(collectableScope)) {
|
||||
Set<ParseTree> referencedVars = wrapper.getReferencedVars(collectable);
|
||||
for (ParseTree refVar : referencedVars) {
|
||||
if (refVar.getText().equals(taintedVar.getText())) {
|
||||
seeds.add(collectable);
|
||||
taints.addTaintedVariable(collectableScope, refVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
initSeeds(seeds);
|
||||
expand();
|
||||
}
|
||||
|
||||
public AbstractTainter(Set<ParserRuleContext> collectables, Set<ParserRuleContext> seeds) {
|
||||
this.collectables = collectables;
|
||||
initSeeds(seeds);
|
||||
expand();
|
||||
}
|
||||
|
||||
protected void expand() {
|
||||
Queue<ParserRuleContext> q = new LinkedList<>();
|
||||
q.addAll(taintedStatements);
|
||||
while (!q.isEmpty()) {
|
||||
ParserRuleContext stmt = q.poll();
|
||||
Set<ParserRuleContext> growths = iterate(stmt);
|
||||
taintedStatements.add(stmt);
|
||||
q.addAll(growths);
|
||||
}
|
||||
}
|
||||
|
||||
public Set<Integer> getCollectedLines() {
|
||||
Set<Integer> lineNumbers = new LinkedHashSet<>();
|
||||
for (ParserRuleContext stmt : this.taintedStatements) {
|
||||
lineNumbers.add(stmt.getStart().getLine());
|
||||
}
|
||||
return lineNumbers;
|
||||
}
|
||||
|
||||
public TaintedVariableSet getTaintedVars() {
|
||||
return this.taints;
|
||||
}
|
||||
|
||||
protected abstract void initSeeds(Set<ParserRuleContext> seeds);
|
||||
public abstract Set<ParserRuleContext> iterate(ParserRuleContext taintedStmt);
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
package it.unitn.repoman.core.slicers.tainters;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.ConditionTraversal;
|
||||
|
||||
public class BackwardTainter extends ForwardTainter {
|
||||
|
||||
public BackwardTainter(Set<ParserRuleContext> collectables, Set<ParserRuleContext> seeds) {
|
||||
super(collectables, seeds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initSeed(ParserRuleContext stmt) {
|
||||
this.taintedStatements.add(stmt);
|
||||
ParserRuleContext scope = wrapper.getContainer(stmt);
|
||||
Set<ParseTree> refVars = wrapper.getReferencedVars(stmt);
|
||||
for (ParseTree refVar : refVars) {
|
||||
this.taints.addTaintedVariable(scope, refVar);
|
||||
}
|
||||
ParseTree defVar = wrapper.getDefinedVar(stmt);
|
||||
if (defVar != null) {
|
||||
this.taints.addTaintedVariable(scope, defVar);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ParserRuleContext> iterate(ParserRuleContext taintedStmt) {
|
||||
Set<ParserRuleContext> elementsToAdd = new LinkedHashSet<>();
|
||||
ParserRuleContext taintedScope = wrapper.getContainer(taintedStmt);
|
||||
|
||||
LinkedList<ParserRuleContext> list = new LinkedList<>(this.collectables);
|
||||
Iterator<ParserRuleContext> backwardIter = list.descendingIterator();
|
||||
while (backwardIter.hasNext()) {
|
||||
ParserRuleContext collectable = backwardIter.next();
|
||||
if (taintedStatements.contains(collectable)) {
|
||||
continue;
|
||||
}
|
||||
ParserRuleContext collectableScope = wrapper.getContainer(collectable);
|
||||
if (collectableScope.equals(taintedScope) && wrapper.precedes(collectable, taintedStmt)) {
|
||||
Set<String> taintedVars = this.taints.getVariableNames(collectableScope);
|
||||
// if the seed is an inner statement of a conditional statement, take the conditional statement-----
|
||||
if (wrapper.isConditionalExpression(collectable)) {
|
||||
ConditionTraversal t = new ConditionTraversal(collectable);
|
||||
for (ParserRuleContext innerStmt : t.getInnerStatements()) {
|
||||
if (this.taintedStatements.contains(innerStmt) || elementsToAdd.contains(innerStmt)) {
|
||||
elementsToAdd.add(collectable);
|
||||
Set<ParseTree> referencedVars = wrapper.getReferencedVars(collectable);
|
||||
for (ParseTree referencedVar : referencedVars) {
|
||||
taints.addTaintedVariable(collectableScope, referencedVar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ParseTree definedVar = wrapper.getDefinedVar(collectable);
|
||||
if (definedVar != null) {
|
||||
if (taintedVars.contains(definedVar.getText())) {
|
||||
elementsToAdd.add(collectable);
|
||||
Set<ParseTree> referencedVars = wrapper.getReferencedVars(collectable);
|
||||
for (ParseTree referencedVar : referencedVars) {
|
||||
taints.addTaintedVariable(collectableScope, referencedVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return elementsToAdd;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package it.unitn.repoman.core.slicers.tainters;
|
||||
|
||||
import it.unitn.repoman.core.lang.traversals.generic.ConditionTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class BackwardTainterPessimist extends BackwardTainter {
|
||||
|
||||
public BackwardTainterPessimist(Set<ParserRuleContext> collectables, Set<ParserRuleContext> seeds) {
|
||||
super(collectables, seeds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initSeed(ParserRuleContext stmt) {
|
||||
this.taintedStatements.add(stmt);
|
||||
ParserRuleContext scope = wrapper.getContainer(stmt);
|
||||
Set<ParseTree> refVars = wrapper.getReferencedVars(stmt);
|
||||
for (ParseTree refVar : refVars) {
|
||||
this.taints.addTaintedVariable(scope, refVar);
|
||||
}
|
||||
ParseTree defVar = wrapper.getDefinedVar(stmt);
|
||||
if (defVar != null) {
|
||||
this.taints.addTaintedVariable(scope, defVar);
|
||||
}
|
||||
/*
|
||||
* THIS SHOULD NOT HAPPEN IN AN "EFFECT-FREE" SLICE!
|
||||
* taint ref. variables in a method call as well */
|
||||
if (wrapper.isMethodCall(stmt)) {
|
||||
for (ParseTree var : wrapper.getReferencedVars(stmt)) {
|
||||
this.taints.addTaintedVariable(scope, var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Set<ParserRuleContext> iterate(ParserRuleContext taintedStmt) {
|
||||
Set<ParserRuleContext> elementsToAdd = new LinkedHashSet<>();
|
||||
ParserRuleContext taintedScope = wrapper.getContainer(taintedStmt);
|
||||
|
||||
LinkedList<ParserRuleContext> list = new LinkedList<>(this.collectables);
|
||||
Iterator<ParserRuleContext> backwardIter = list.descendingIterator();
|
||||
while (backwardIter.hasNext()) {
|
||||
ParserRuleContext collectable = backwardIter.next();
|
||||
if (taintedStatements.contains(collectable)) {
|
||||
continue;
|
||||
}
|
||||
ParserRuleContext collectableScope = wrapper.getContainer(collectable);
|
||||
if (collectableScope.equals(taintedScope) && wrapper.precedes(collectable, taintedStmt)) {
|
||||
Set<String> taintedVars = this.taints.getVariableNames(collectableScope);
|
||||
// if the seed is an inner statement of a conditional statement, take the conditional statement-----
|
||||
if (wrapper.isConditionalExpression(collectable)) {
|
||||
ConditionTraversal t = new ConditionTraversal(collectable);
|
||||
for (ParserRuleContext innerStmt : t.getInnerStatements()) {
|
||||
if (this.taintedStatements.contains(innerStmt) || elementsToAdd.contains(innerStmt)) {
|
||||
elementsToAdd.add(collectable);
|
||||
Set<ParseTree> referencedVars = wrapper.getReferencedVars(collectable);
|
||||
for (ParseTree referencedVar : referencedVars) {
|
||||
taints.addTaintedVariable(collectableScope, referencedVar);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ParseTree definedVar = wrapper.getDefinedVar(collectable);
|
||||
if (definedVar != null) {
|
||||
if (taintedVars.contains(definedVar.getText())) {
|
||||
elementsToAdd.add(collectable);
|
||||
Set<ParseTree> referencedVars = wrapper.getReferencedVars(collectable);
|
||||
for (ParseTree referencedVar : referencedVars) {
|
||||
taints.addTaintedVariable(collectableScope, referencedVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (wrapper.isMethodCall(collectable)) {
|
||||
MethodCallTraversal t = wrapper.getMethodCallTraversal(collectable);
|
||||
List<ParseTree> vars = t.getParams();
|
||||
boolean tainted = false;
|
||||
for (ParseTree var : vars) {
|
||||
if (taintedVars.contains(var.getText())) {
|
||||
tainted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tainted) {
|
||||
for (ParseTree var : vars) {
|
||||
taints.addTaintedVariable(collectableScope, var);
|
||||
}
|
||||
taintedStatements.add(collectable);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return elementsToAdd;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,140 @@
|
|||
package it.unitn.repoman.core.slicers.tainters;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.ConditionTraversal;
|
||||
|
||||
public class ForwardTainter extends AbstractTainter {
|
||||
|
||||
protected final Set<ParserRuleContext> taintedMethodCalls = new LinkedHashSet<>();
|
||||
|
||||
public ForwardTainter(Set<ParserRuleContext> collectables, Set<ParserRuleContext> seeds) {
|
||||
super(collectables, seeds);
|
||||
}
|
||||
|
||||
public ForwardTainter(Set<ParserRuleContext> collectables, List<ParseTree> taintedVars) {
|
||||
super(collectables, taintedVars);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initSeeds(Set<ParserRuleContext> seeds) {
|
||||
for (ParserRuleContext seed : seeds) {
|
||||
this.initSeed(seed);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ParserRuleContext> iterate(ParserRuleContext taintedStmt) {
|
||||
Set<ParserRuleContext> elementsToAdd = new LinkedHashSet<>();
|
||||
ParserRuleContext taintedScope = wrapper.getContainer(taintedStmt);
|
||||
|
||||
for (ParserRuleContext collectable: this.collectables) {
|
||||
// do nothing if a statement is already collected
|
||||
if (taintedStatements.contains(collectable)) {
|
||||
continue;
|
||||
}
|
||||
ParserRuleContext collectableScope = wrapper.getContainer(collectable);
|
||||
if (collectableScope.equals(taintedScope) && wrapper.precedes(taintedStmt, collectable)) {
|
||||
Set<String> taintedVars = this.taints.getVariableNames(collectableScope);
|
||||
Set<ParseTree> referencedVars = wrapper.getReferencedVars(collectable);
|
||||
MethodCallTraversal t = wrapper.getMethodCallTraversal(collectable);
|
||||
if (t.isMethodCall()) {
|
||||
List<ParseTree> vars = t.getParams();
|
||||
for (ParseTree var : vars) {
|
||||
if (taintedVars.contains(var.getText())) {
|
||||
taints.addTaintedVariable(collectableScope, var);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ParseTree referencedVar : referencedVars) {
|
||||
if (taintedVars.contains(referencedVar.getText())) {
|
||||
elementsToAdd.add(collectable);
|
||||
ParseTree definedVar = wrapper.getDefinedVar(collectable);
|
||||
if (definedVar != null) {
|
||||
taints.addTaintedVariable(collectableScope, definedVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<ParserRuleContext> taintedInnerStatements = new HashSet<>();
|
||||
for (ParserRuleContext ctx : elementsToAdd) {
|
||||
if (wrapper.isConditionalExpression(ctx)) {
|
||||
taintedInnerStatements.addAll(taintInnerStatements(ctx));
|
||||
}
|
||||
}
|
||||
elementsToAdd.addAll(taintedInnerStatements);
|
||||
return elementsToAdd;
|
||||
}
|
||||
|
||||
protected void initSeed(ParserRuleContext stmt) {
|
||||
this.taintedStatements.add(stmt);
|
||||
ParserRuleContext scope = wrapper.getContainer(stmt);
|
||||
ParseTree defVar = wrapper.getDefinedVar(stmt);
|
||||
if (defVar != null) {
|
||||
this.taints.addTaintedVariable(scope, defVar);
|
||||
}
|
||||
/*
|
||||
* THIS SHOULD NOT HAPPEN IN AN "EFFECT-FREE" SLICE!
|
||||
* taint ref. variables in a method call as well
|
||||
if (wrapper.isMethodCall(stmt)) {
|
||||
for (ParseTree var : wrapper.getReferencedVars(stmt)) {
|
||||
this.taints.addTaintedVariable(scope, var);
|
||||
}
|
||||
}
|
||||
*/
|
||||
// if the seed is a conditional statement or a return statement, take all inner statements
|
||||
else if (wrapper.isConditionalExpression(stmt)) {
|
||||
this.taintedStatements.addAll(taintConditionalExpression(stmt));
|
||||
// and taint all variables within the condition
|
||||
Set<ParseTree> vars = wrapper.getReferencedVars(stmt);
|
||||
for (ParseTree var : vars) {
|
||||
taints.addTaintedVariable(scope, var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Set<ParserRuleContext> taintInnerStatements(ParserRuleContext cnd) {
|
||||
Set<ParserRuleContext> addedStmts = new HashSet<>();
|
||||
ConditionTraversal t = new ConditionTraversal(cnd);
|
||||
for (ParserRuleContext innerStmt : t.getInnerStatements()) {
|
||||
ParseTree defVar = wrapper.getDefinedVar(innerStmt);
|
||||
if (defVar != null) {
|
||||
taints.addTaintedVariable(wrapper.getContainer(innerStmt), defVar);
|
||||
}
|
||||
addedStmts.add(innerStmt);
|
||||
}
|
||||
return addedStmts;
|
||||
}
|
||||
|
||||
protected Set<ParserRuleContext> taintConditionalExpression(ParserRuleContext cnd) {
|
||||
ConditionTraversal t = new ConditionTraversal(cnd);
|
||||
Set<ParserRuleContext> addedStmts = new LinkedHashSet<>();
|
||||
addedStmts.add(cnd);
|
||||
for (ParserRuleContext innerStmt : t.getInnerStatements()) {
|
||||
ParseTree innerStmtDefVar = wrapper.getDefinedVar(innerStmt);
|
||||
if (innerStmtDefVar != null) {
|
||||
taints.addTaintedVariable(wrapper.getContainer(innerStmt), innerStmtDefVar);
|
||||
}
|
||||
addedStmts.add(innerStmt);
|
||||
}
|
||||
return addedStmts;
|
||||
}
|
||||
|
||||
public Set<ParserRuleContext> getTaintedMethodCalls() {
|
||||
if (taintedMethodCalls.size() == 0) {
|
||||
for (ParserRuleContext ctx : this.collectables) {
|
||||
if (getCollectedLines().contains(ctx.getStart().getLine())) {
|
||||
MethodCallTraversal t = wrapper.getMethodCallTraversal(ctx);
|
||||
if (t.isMethodCall()) {
|
||||
taintedMethodCalls.add(ctx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return taintedMethodCalls;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package it.unitn.repoman.core.slicers.tainters;
|
||||
|
||||
import it.unitn.repoman.core.lang.traversals.generic.ConditionTraversal;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ForwardTainterPessimist extends ForwardTainter {
|
||||
|
||||
public ForwardTainterPessimist(Set<ParserRuleContext> collectables, Set<ParserRuleContext> seeds) {
|
||||
super(collectables, seeds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initSeed(ParserRuleContext stmt) {
|
||||
this.taintedStatements.add(stmt);
|
||||
ParserRuleContext scope = wrapper.getContainer(stmt);
|
||||
ParseTree defVar = wrapper.getDefinedVar(stmt);
|
||||
if (defVar != null) {
|
||||
this.taints.addTaintedVariable(scope, defVar);
|
||||
}
|
||||
/*
|
||||
* THIS SHOULD NOT HAPPEN IN AN "EFFECT-FREE" SLICE!
|
||||
* taint ref. variables in a method call as well */
|
||||
if (wrapper.isMethodCall(stmt)) {
|
||||
for (ParseTree var : wrapper.getReferencedVars(stmt)) {
|
||||
this.taints.addTaintedVariable(scope, var);
|
||||
}
|
||||
}
|
||||
// if the seed is a conditional statement or a return statement, take all inner statements
|
||||
else if (wrapper.isConditionalExpression(stmt)) {
|
||||
this.taintedStatements.addAll(taintConditionalExpression(stmt));
|
||||
// and taint all variables within the condition
|
||||
Set<ParseTree> vars = wrapper.getReferencedVars(stmt);
|
||||
for (ParseTree var : vars) {
|
||||
taints.addTaintedVariable(scope, var);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ParserRuleContext> iterate(ParserRuleContext taintedStmt) {
|
||||
Set<ParserRuleContext> elementsToAdd = new LinkedHashSet<>();
|
||||
ParserRuleContext taintedScope = wrapper.getContainer(taintedStmt);
|
||||
|
||||
for (ParserRuleContext collectable: this.collectables) {
|
||||
ParserRuleContext collectableScope = wrapper.getContainer(collectable);
|
||||
// do nothing if a statement is already collected
|
||||
if (taintedStatements.contains(collectable)) {
|
||||
if (wrapper.isMethodCall(collectable)) {
|
||||
for (ParseTree var : wrapper.getReferencedVars(collectable)) {
|
||||
this.taints.addTaintedVariable(collectableScope, var);
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (collectableScope.equals(taintedScope) && wrapper.precedes(taintedStmt, collectable)) {
|
||||
Set<String> taintedVars = this.taints.getVariableNames(collectableScope);
|
||||
Set<ParseTree> referencedVars = wrapper.getReferencedVars(collectable);
|
||||
MethodCallTraversal t = wrapper.getMethodCallTraversal(collectable);
|
||||
if (t.isMethodCall()) {
|
||||
List<ParseTree> vars = t.getParams();
|
||||
boolean tainted = false;
|
||||
for (ParseTree var : vars) {
|
||||
if (taintedVars.contains(var.getText())) {
|
||||
tainted = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (tainted) {
|
||||
for (ParseTree var : vars) {
|
||||
taints.addTaintedVariable(collectableScope, var);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (ParseTree referencedVar : referencedVars) {
|
||||
if (taintedVars.contains(referencedVar.getText())) {
|
||||
elementsToAdd.add(collectable);
|
||||
ParseTree definedVar = wrapper.getDefinedVar(collectable);
|
||||
if (definedVar != null) {
|
||||
taints.addTaintedVariable(collectableScope, definedVar);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Set<ParserRuleContext> taintedInnerStatements = new HashSet<>();
|
||||
for (ParserRuleContext ctx : elementsToAdd) {
|
||||
if (wrapper.isConditionalExpression(ctx)) {
|
||||
taintedInnerStatements.addAll(taintInnerStatements(ctx));
|
||||
}
|
||||
}
|
||||
elementsToAdd.addAll(taintedInnerStatements);
|
||||
return elementsToAdd;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<ParserRuleContext> taintInnerStatements(ParserRuleContext cnd) {
|
||||
Set<ParserRuleContext> addedStmts = new HashSet<>();
|
||||
ConditionTraversal t = new ConditionTraversal(cnd);
|
||||
for (ParserRuleContext innerStmt : t.getInnerStatements()) {
|
||||
ParseTree defVar = wrapper.getDefinedVar(innerStmt);
|
||||
if (defVar != null) {
|
||||
taints.addTaintedVariable(wrapper.getContainer(innerStmt), defVar);
|
||||
}
|
||||
addedStmts.add(innerStmt);
|
||||
}
|
||||
return addedStmts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package it.unitn.repoman.core.slicers.tainters;
|
||||
|
||||
import it.unitn.repoman.core.lang.traversals.generic.MethodCallTraversal;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class MethodCallTainter extends AbstractTainter {
|
||||
|
||||
public MethodCallTainter(Set<ParserRuleContext> collectables, Set<ParserRuleContext> seeds) {
|
||||
super(collectables, seeds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initSeeds(Set<ParserRuleContext> seeds) {
|
||||
this.taintedStatements.addAll(seeds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<ParserRuleContext> iterate(ParserRuleContext taintedStmt) {
|
||||
Set<ParserRuleContext> elementsToAdd = new LinkedHashSet<>();
|
||||
ParserRuleContext taintedScope = wrapper.getContainer(taintedStmt);
|
||||
|
||||
for (ParserRuleContext collectable : collectables) {
|
||||
if (!taintedStatements.contains(collectable)) {
|
||||
if (wrapper.getContainer(collectable).equals(taintedScope)) {
|
||||
MethodCallTraversal t = wrapper.getMethodCallTraversal(collectable);
|
||||
MethodCallTraversal tt = wrapper.getMethodCallTraversal(taintedStmt);
|
||||
if (t.getMethodName().equals(tt.getMethodName()) && t.getParamsNumber() == tt.getParamsNumber()) {
|
||||
elementsToAdd.add(collectable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return elementsToAdd;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package it.unitn.repoman.core.slicers.tainters;
|
||||
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class TaintedVariable {
|
||||
private final ParseTree variable;
|
||||
private final ParserRuleContext scope;
|
||||
|
||||
public TaintedVariable(ParserRuleContext scope, ParseTree variable) {
|
||||
this.scope = scope;
|
||||
this.variable = variable;
|
||||
}
|
||||
|
||||
public ParserRuleContext getScope() {
|
||||
return this.scope;
|
||||
}
|
||||
|
||||
public ParseTree getVariable() {
|
||||
return this.variable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("[" + this.scope.getStart().getLine() + "] -> " + this.variable.getText() + "\n");
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package it.unitn.repoman.core.slicers.tainters;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import it.unitn.repoman.core.lang.LanguageFactory;
|
||||
import it.unitn.repoman.core.lang.traversals.generic.NodeContainmentTraversal;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.tree.ParseTree;
|
||||
|
||||
public class TaintedVariableSet {
|
||||
|
||||
private final Set<TaintedVariable> taintedVars = new LinkedHashSet<>();
|
||||
|
||||
public void addTaintedVariable(TaintedVariable newVariable) {
|
||||
// for (TaintedVariable var : this.taintedVars) {
|
||||
// if (var.getScope().equals(newVariable.getScope())
|
||||
// && var.getVariable().getText().equals(newVariable.getVariable().getText())) {
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
for (TaintedVariable var : this.taintedVars) {
|
||||
if (var.getVariable().equals(newVariable.getVariable())) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
taintedVars.add(newVariable);
|
||||
}
|
||||
|
||||
public void addTaintedVariable(ParserRuleContext scope, ParseTree variable) {
|
||||
this.addTaintedVariable((new TaintedVariable(scope, variable)));
|
||||
}
|
||||
|
||||
public Set<String> getVariableNames(ParserRuleContext scope) {
|
||||
Set<String> vars = new LinkedHashSet<>();
|
||||
for (TaintedVariable var : this.taintedVars) {
|
||||
if (var.getScope().equals(scope)) {
|
||||
vars.add(var.getVariable().getText());
|
||||
}
|
||||
}
|
||||
return vars;
|
||||
}
|
||||
|
||||
public Set<ParseTree> getVariables(ParserRuleContext scope) {
|
||||
Set<ParseTree> vars = new LinkedHashSet<>();
|
||||
for (TaintedVariable var : this.taintedVars) {
|
||||
if (var.getScope().equals(scope)) {
|
||||
vars.add(var.getVariable());
|
||||
}
|
||||
}
|
||||
return vars;
|
||||
}
|
||||
|
||||
public List<ParseTree> getStatementVariables(ParserRuleContext statement) {
|
||||
List<ParseTree> vars = new LinkedList<>();
|
||||
ParserRuleContext scope = LanguageFactory.getWrapper().getContainer(statement);
|
||||
for (TaintedVariable var : this.taintedVars) {
|
||||
if (var.getScope().equals(scope)) {
|
||||
NodeContainmentTraversal t = new NodeContainmentTraversal(statement, var.getVariable());
|
||||
if (t.isFound()) {
|
||||
vars.add(var.getVariable());
|
||||
}
|
||||
}
|
||||
}
|
||||
return vars;
|
||||
}
|
||||
|
||||
// public void removeVariable(ParserRuleContext scope, ParseTree variable) {
|
||||
// Iterator<TaintedVariable> it = this.taintedVars.iterator();
|
||||
// while (it.hasNext()) {
|
||||
// TaintedVariable var = it.next();
|
||||
// if (var.getScope().equals(scope) &&
|
||||
// var.getVariable().getText().equals(variable.getText())) {
|
||||
// it.remove();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
public boolean isVariableTainted(ParserRuleContext scope, ParseTree variable) {
|
||||
for (TaintedVariable var : this.taintedVars) {
|
||||
if (var.getScope().equals(scope) && var.getVariable().getText().equals(variable.getText())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (TaintedVariable var : this.taintedVars) {
|
||||
builder.append(var.toString());
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package it.unitn.repoman.core.utils.printers;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
|
||||
import it.unitn.repoman.core.lang.LanguageFactory;
|
||||
import it.unitn.repoman.core.slicers.LightweightSlice;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.misc.Utils;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
||||
public class ConsolePrinterListener implements ParseTreeListener {
|
||||
private final Set<Integer> selectedLines;
|
||||
private final Parser parser;
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
private int indent = 0;
|
||||
private boolean marked = false;
|
||||
private String MARK_START = "\u001B[31m";
|
||||
private String MARK_END = "\u001B[0m";
|
||||
|
||||
public ConsolePrinterListener(Parser parser, LightweightSlice slice) {
|
||||
this.parser = parser;
|
||||
this.selectedLines = slice.getSelectedLines();
|
||||
builder.append("Selected lines: " + slice.getSelectedLines() + "\n");
|
||||
builder.append("#Selected lines: " + slice.getSelectedLines().size() + "\n");
|
||||
builder.append("\n\n");
|
||||
ParseTreeWalker.DEFAULT.walk(this, LanguageFactory.getRoot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTerminal(TerminalNode node) {
|
||||
if (marked) {
|
||||
mark(builder);
|
||||
}
|
||||
|
||||
if (builder.length() > 0)
|
||||
builder.append(' ');
|
||||
|
||||
String text = Trees.getNodeText(node, this.parser);
|
||||
if (text.equals("{")) {
|
||||
indent++;
|
||||
builder.append(Utils.escapeWhitespace(text, false));
|
||||
unmark(builder);
|
||||
appendNewline();
|
||||
}
|
||||
else if (text.equals(";")) {
|
||||
builder.append(Utils.escapeWhitespace(text, false));
|
||||
unmark(builder);
|
||||
appendNewline();
|
||||
}
|
||||
else if (text.equals("}")) {
|
||||
indent--;
|
||||
appendNewline();
|
||||
builder.append(" " + Utils.escapeWhitespace(text, false));
|
||||
unmark(builder);
|
||||
appendNewline();
|
||||
}
|
||||
else {
|
||||
if (!text.contains("<EOF>")) {
|
||||
builder.append(Utils.escapeWhitespace(text, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitErrorNode(ErrorNode node) {
|
||||
builder.append(Utils.escapeWhitespace(Trees.getNodeText(node, this.parser), false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterEveryRule(ParserRuleContext ctx) {
|
||||
marked = this.selectedLines.contains(ctx.getStart().getLine());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitEveryRule(ParserRuleContext ctx) {
|
||||
}
|
||||
|
||||
private void appendNewline() {
|
||||
builder.append("\n");
|
||||
for (int i=0; i<indent; i++) {
|
||||
builder.append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
private void unmark(StringBuilder builder) {
|
||||
builder.append(MARK_END);
|
||||
marked = false;
|
||||
}
|
||||
|
||||
private void mark(StringBuilder builder) {
|
||||
builder.append(MARK_START);
|
||||
marked = true;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package it.unitn.repoman.core.utils.printers;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class HTMLPrinter {
|
||||
|
||||
protected final StringBuilder builder = new StringBuilder();
|
||||
|
||||
public HTMLPrinter(String fileContents, Set<Integer> selectedLines) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
package it.unitn.repoman.core.utils.printers;
|
||||
|
||||
import it.unitn.repoman.core.lang.LanguageFactory;
|
||||
import it.unitn.repoman.core.slicers.LightweightSlice;
|
||||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.misc.Utils;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
public class TextPrinterListener implements ParseTreeListener {
|
||||
private final Set<Integer> selectedLines;
|
||||
private final Parser parser;
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
private boolean marked = false;
|
||||
private int currentLineNumber = -1;
|
||||
|
||||
public TextPrinterListener(Parser parser, LightweightSlice slice) {
|
||||
this.parser = parser;
|
||||
this.selectedLines = slice.getSelectedLines();
|
||||
builder.append("Selected lines: " + slice.getSelectedLines() + "\n");
|
||||
builder.append("#Selected lines: " + slice.getSelectedLines().size() + "\n");
|
||||
ParseTreeWalker.DEFAULT.walk(this, LanguageFactory.getRoot());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterEveryRule(ParserRuleContext ctx) {
|
||||
int lineNumber = ctx.getStart().getLine();
|
||||
marked = (selectedLines.contains(lineNumber));
|
||||
if (lineNumber != currentLineNumber && marked) {
|
||||
builder.append("\n");
|
||||
currentLineNumber = lineNumber;
|
||||
builder.append(lineNumber);
|
||||
builder.append(": ");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTerminal(TerminalNode node) {
|
||||
if (marked) {
|
||||
if (builder.length() > 0) {
|
||||
builder.append(' ');
|
||||
}
|
||||
String text = Trees.getNodeText(node, this.parser);
|
||||
if (text.equals("{")) {
|
||||
builder.append(Utils.escapeWhitespace(text, false));
|
||||
} else if (text.equals(";")) {
|
||||
builder.append(Utils.escapeWhitespace(text, false));
|
||||
} else if (text.equals("}")) {
|
||||
builder.append(" " + Utils.escapeWhitespace(text, false));
|
||||
} else {
|
||||
if (!text.contains("<EOF>")) {
|
||||
builder.append(Utils.escapeWhitespace(text, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitErrorNode(ErrorNode node) {
|
||||
builder.append(Utils.escapeWhitespace(Trees.getNodeText(node, this.parser), false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitEveryRule(ParserRuleContext ctx) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue