blob: d510395c5bfebd2455914281e07a2571be5cff9c [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2020 Bart Jacobs and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
*/
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import org.eclipse.jdt.internal.compiler.parser.Parser;
public class GenerateParserScript {
private static void assertTrue(boolean b) { if (!b) throw new AssertionError(); }
public static void main(String[] args) throws IOException, InterruptedException {
File grammarDir = new File("../grammar");
File parserDir = new File("../src/org/eclipse/jdt/internal/compiler/parser");
String jikespg = System.getProperty("JIKESPG");
assertTrue(jikespg != null);
if (!jikespg.equals("JIKESPG_EXTERNAL")) {
// Run JikesPG
Process process = Runtime.getRuntime().exec(new String[] {jikespg, "java.g"}, null, grammarDir);
boolean ok = false;
try (BufferedReader jikespgOutput = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
for (;;) {
String line = jikespgOutput.readLine();
if (line == null)
break;
System.out.println(line);
if (line.equals("This grammar is LALR(1)."))
ok = true;
}
}
int exitCode = process.waitFor();
assertTrue(exitCode == 0);
if (!ok)
System.exit(1);
}
// Update parserNN.rsc and readableNames.props
File javadclFile = new File(grammarDir, "javadcl.java");
File javahdrFile = new File(grammarDir, "javahdr.java");
Parser.buildFilesFromLPG(javadclFile.toString(), javahdrFile.toString());
for (int i = 1; i <= 24; i++) {
String filename = "parser"+i+".rsc";
Files.move(new File(filename).toPath(), new File(parserDir, filename).toPath(), StandardCopyOption.REPLACE_EXISTING);
}
{
String filename = "readableNames.props";
Files.move(new File(filename).toPath(), new File(parserDir, filename).toPath(), StandardCopyOption.REPLACE_EXISTING);
}
// Update TerminalTokens.java
File javasymFile = new File(grammarDir, "javasym.java");
File terminalTokensFile = new File(parserDir, "TerminalTokens.java");
String javasymText = new String(Files.readAllBytes(javasymFile.toPath())).replace("\r\n", "\n");
String terminalTokensText = new String(Files.readAllBytes(terminalTokensFile.toPath()));
{
String startTag = "// BEGIN_AUTOGENERATED_REGION\n";
int start = terminalTokensText.indexOf(startTag);
assertTrue(start >= 0);
start += startTag.length();
String terminalTokensProlog = terminalTokensText.substring(0, start);
String javasymProlog =
"interface javasym\n" +
"{\n" +
" public final static int\n" +
" ";
assertTrue(javasymText.startsWith(javasymProlog));
javasymText = javasymText.substring(javasymProlog.length());
javasymText = javasymText.replace(",\n ", ",\n\t\t\t\t\t\t\t");
javasymText = javasymText.replace("TokenName$eof", "TokenNameEOF");
javasymText = javasymText.replace("TokenName$error", "TokenNameERROR");
javasymText = javasymText.replace("TokenNamenon-sealed", "TokenNamenon_sealed");
Files.write(terminalTokensFile.toPath(), (terminalTokensProlog + "\tint " + javasymText).getBytes());
}
// Update ParserBasicInformation.java
File javadefFile = new File(grammarDir, "javadef.java");
File parserBasicInformationFile = new File(parserDir, "ParserBasicInformation.java");
String javadefText = new String(Files.readAllBytes(javadefFile.toPath())).replace("\r\n", "\n");
String parserBasicInformationText = new String(Files.readAllBytes(parserBasicInformationFile.toPath()));
{
String startTag = "// BEGIN_AUTOGENERATED_REGION";
int start = parserBasicInformationText.indexOf(startTag);
assertTrue(start >= 0);
start += startTag.length();
String parserBasicInformationProlog = parserBasicInformationText.substring(0, start);
String javadefProlog =
"interface javadef\n" +
"{\n" +
" public final static int";
assertTrue(javadefText.startsWith(javadefProlog));
javadefText = javadefText.substring(javadefProlog.length());
javadefText = javadefText.replace("\n ", "\n\t\t\t\t\t");
javadefText = javadefText.replaceAll(" +", " ");
javadefText = javadefText.replace("};\n\n", "}\n");
Files.write(parserBasicInformationFile.toPath(), (parserBasicInformationProlog + javadefText).getBytes());
}
// Update method consumeRule in Parser.java
File parserFile = new File(parserDir, "Parser.java");
String parserText = new String(Files.readAllBytes(parserFile.toPath()));
File javaActionFile = new File(grammarDir, "JavaAction.java");
String javaActionText = new String(Files.readAllBytes(javaActionFile.toPath()))
.replace("\r\n", "\n").replace(" \n", "\n").replace(" \n", "\n");
{
String startTag = "// BEGIN_AUTOGENERATED_REGION_CONSUME_RULE\n";
String endTag = "// END_AUTOGENERATED_REGION_CONSUME_RULE\n";
int start = parserText.indexOf(startTag);
assertTrue(start >= 0);
start += startTag.length();
int end = parserText.indexOf(endTag, start);
assertTrue(end >= 0);
String newParserText = parserText.substring(0, start) + javaActionText + parserText.substring(end);
Files.write(parserFile.toPath(), newParserText.getBytes());
}
// Clean up JikesPG output files
Files.delete(javadclFile.toPath());
Files.delete(javahdrFile.toPath());
Files.delete(javaActionFile.toPath());
Files.delete(javasymFile.toPath());
Files.delete(javadefFile.toPath());
Files.delete(new File(grammarDir, "javaprs.java").toPath());
Files.delete(new File(grammarDir, "java.l").toPath());
}
}