libcmo21/CodeGen/EnumsMigration/CommonHelper.java

250 lines
6.7 KiB
Java
Raw Normal View History

2023-08-18 15:55:31 +08:00
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
2023-08-20 12:13:40 +08:00
import java.util.stream.Collectors;
import java.util.stream.Stream;
2023-08-18 15:55:31 +08:00
import org.antlr.v4.runtime.*;
2023-08-20 12:13:40 +08:00
public class CommonHelper {
// =========== Token Finder & Comments Processing ===========
2023-08-18 15:55:31 +08:00
public static Token getPreChannelToken(BufferedTokenStream stream, Token token, int channel) {
List<Token> tokens = stream.getHiddenTokensToLeft(token.getTokenIndex(), channel);
if (tokens == null)
return null;
return tokens.get(0);
}
public static Token getPostChannelToken(BufferedTokenStream stream, Token token, int channel) {
List<Token> tokens = stream.getHiddenTokensToRight(token.getTokenIndex(), channel);
if (tokens == null)
return null;
return tokens.get(0);
}
2023-08-20 12:13:40 +08:00
public static List<Token> getPreChannelTokens(BufferedTokenStream stream, Token token, int channel) {
return stream.getHiddenTokensToLeft(token.getTokenIndex(), channel);
}
2023-08-18 15:55:31 +08:00
2023-08-20 12:13:40 +08:00
public static List<Token> getPostChannelTokens(BufferedTokenStream stream, Token token, int channel) {
return stream.getHiddenTokensToRight(token.getTokenIndex(), channel);
}
/**
* Cut the head and tail of comment
*
* @param comment The comment need to be cut.
* @return The cut comment.
*/
2023-08-18 15:55:31 +08:00
public static String cutComment(Token comment) {
if (comment == null)
return null;
switch (comment.getType()) {
case CKGeneralLexer.CKGENERAL_LINE_COMMENT: {
2023-09-15 13:21:49 +08:00
return removeStars(comment.getText().substring(2));
2023-08-18 15:55:31 +08:00
}
case CKGeneralLexer.CKGENERAL_BLOCK_COMMENT: {
String cache = comment.getText();
2023-09-15 13:21:49 +08:00
return removeStars(cache.substring(2, cache.length() - 4));
2023-08-18 15:55:31 +08:00
}
default:
return comment.getText();
}
}
2023-08-20 12:13:40 +08:00
/**
* Cut multiple comments.
* <p>
* Each comment will be cut the head and tail first. And strip all whitespace.
2023-08-20 12:13:40 +08:00
* Then join together.
*
* @param tokens Multiple comments.
* @return The joined comment.
*/
public static String cutComments(List<Token> tokens) {
if (tokens == null)
return null;
return tokens.stream().map(value -> {
String text = cutComment(value).strip();
return text + " ";
}).collect(Collectors.joining(""));
}
2023-08-20 12:13:40 +08:00
// =========== Number Operations ===========
/**
* Check whether Antlr captured CKGENERAL_NUM is a negative number.
*
* @param numstr The captured number.
* @return true if it is negative number.
*/
public static boolean isNegativeNumber(String numstr) {
2023-08-18 15:55:31 +08:00
return numstr.startsWith("-");
}
2023-08-20 12:13:40 +08:00
/**
* Check whether Altlr captured CKGENERAL_NUM is a hex number.
*
2023-08-20 12:13:40 +08:00
* @param numstr The captured number.
* @return true if it is hex number.
*/
public static boolean isHexNumber(String numstr) {
return numstr.startsWith("0x") || numstr.startsWith("0X");
}
/**
* Convert accepted string into Python cupported format.
*
* It actually just remove trail "UL".
*
* @param numstr The captured number.
* @return The Python style number string.
*/
public static String convertToPythonNumber(String numstr) {
return numstr.replaceFirst("[ulUL]+$", "");
}
2023-08-20 12:13:40 +08:00
/**
* Get underlying type of enum.
*
* @param canUnsigned The parameter stored in Enum_t that indiccate whether this
* enum can use unsigned int as its underlying type.
* @return The string form of its underlying type.
*/
public static String getEnumUnderlyingType(boolean canUnsigned) {
2023-09-16 18:31:25 +08:00
return canUnsigned ? "CKDWORD" : "CKINT";
2023-08-20 12:13:40 +08:00
}
// =========== Parts ===========
2023-08-18 15:55:31 +08:00
enum CKParts {
CK2, VxMath
}
2023-10-10 10:39:27 +08:00
enum LangType {
CPP, Python
}
2023-08-18 15:55:31 +08:00
public static String getCKPartsNamespace(CKParts parts) {
switch (parts) {
case CK2:
return "CK2";
case VxMath:
return "VxMath";
default:
throw new IllegalArgumentException("Unexpected value: " + parts);
}
}
2023-08-19 00:03:00 +08:00
// =========== File Operations ===========
2023-08-20 12:13:40 +08:00
2023-08-19 00:03:00 +08:00
public static class InputFilePair {
public CharStream mAntlrStream;
public FileInputStream mUnderlyingStream;
}
2023-08-20 12:13:40 +08:00
2023-08-19 00:03:00 +08:00
public static InputFilePair openInputFile(String filename) throws Exception {
InputFilePair pair = new InputFilePair();
pair.mUnderlyingStream = new FileInputStream(filename);
pair.mAntlrStream = CharStreams.fromStream(pair.mUnderlyingStream, StandardCharsets.UTF_8);
return pair;
}
2023-08-20 12:13:40 +08:00
2023-08-19 00:03:00 +08:00
/**
* Get output file for writing.
2023-08-20 12:13:40 +08:00
*
2023-08-19 00:03:00 +08:00
* @param filename The name of file opening.
* @return An OutputStreamWriter.
* @throws Exception
*/
2023-08-18 15:55:31 +08:00
public static OutputStreamWriter openOutputFile(String filename) throws Exception {
FileOutputStream fs = new FileOutputStream(filename);
return new OutputStreamWriter(fs, StandardCharsets.UTF_8);
}
2023-08-19 00:03:00 +08:00
// =========== String Process ===========
/**
* Escape String
*
* Escape all characters which are invalid in string quote.
*
* @param strl The string need to be escaped.
* @return The escaped string.
* @see removeEol
*/
2023-08-18 15:55:31 +08:00
public static String escapeString(String strl) {
2023-08-19 00:03:00 +08:00
return strl.replace("\\", "\\\\").replace("\t", "\\t").replace("\b", "\\b").replace("\n", "\\n")
.replace("\r", "\\r").replace("\f", "\\f").replace("\"", "\\\"");
2023-08-18 15:55:31 +08:00
}
2023-08-19 00:03:00 +08:00
/**
* Remove all EOL (End of Line) characters.
*
* @param strl The string need to be processed.
* @return The string eliminated all EOL.
* @see escapeString
*/
public static String removeEol(String strl) {
return strl.replace("\n", "").replace("\r", "");
}
2023-09-15 13:21:49 +08:00
/**
* Remove redundent star '*' (at least 5 continuous star chars)
*
2023-09-15 13:21:49 +08:00
* @param cmt The string provided.
* @return The string processed.
*/
public static String removeStars(String cmt) {
// only remove at least 5 continuous star chars.
return cmt.replaceAll("\\*{5,}", "");
}
/**
* Get indent char by style
*
* @param use_tab Whether indent use Tab, not Space.
* @return The indent chars
*/
public static String getIndentString(boolean use_tab) {
if (use_tab)
return "\t";
else
return " ";
}
/**
* Re-indent a block of string
*
* This function will first split block string by line. Then remove all indent
* (strip Tab and Space). At last, re-indent and join each line
*
* @param block_str The string provided.
* @param use_tab Use Tab, not Space as indent chars.
* @param indent_level The level of indent, started by 0.
* @return The re-indent string
*/
public static String reindentBlockString(String block_str, boolean use_tab, int indent_level) {
// pre-create indent string
String indentChars = getIndentString(use_tab);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < indent_level; ++i) {
sb.append(indentChars);
}
String indents = sb.toString();
// split line
return block_str.lines().map((String line) -> {
// strip space and tab, then re-indent it.
return indents + line.trim();
}).collect(Collectors.joining(System.lineSeparator())); // then join with new line breaker and return.
}
2023-08-18 15:55:31 +08:00
}