write shit
This commit is contained in:
parent
c1aac0beda
commit
77d8bbf3ba
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -13,6 +13,8 @@ temp/
|
|||
## Special Treat of CodeGen
|
||||
CodeGen.old/
|
||||
CodeGen/dest/*.txt
|
||||
CodeGen/.*
|
||||
CodeGen/*.class
|
||||
|
||||
CodeGen/CKGeneralLexer*.*
|
||||
CodeGen/CKEnumParser*.*
|
||||
|
|
76
CodeGen/CKCommonHelper.java
Normal file
76
CodeGen/CKCommonHelper.java
Normal file
|
@ -0,0 +1,76 @@
|
|||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
public class CKCommonHelper {
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
public static String cutComment(Token comment) {
|
||||
if (comment == null)
|
||||
return null;
|
||||
|
||||
switch (comment.getType()) {
|
||||
case CKGeneralLexer.CKGENERAL_LINE_COMMENT: {
|
||||
return comment.getText().substring(2);
|
||||
}
|
||||
case CKGeneralLexer.CKGENERAL_BLOCK_COMMENT: {
|
||||
String cache = comment.getText();
|
||||
return cache.substring(2, cache.length() - 4);
|
||||
}
|
||||
default:
|
||||
return comment.getText();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isNegtiveNumber(String numstr) {
|
||||
return numstr.startsWith("-");
|
||||
}
|
||||
|
||||
enum CKParts {
|
||||
CK2, VxMath
|
||||
}
|
||||
|
||||
public static String getCKPartsNamespace(CKParts parts) {
|
||||
switch (parts) {
|
||||
case CK2:
|
||||
return "CK2";
|
||||
case VxMath:
|
||||
return "VxMath";
|
||||
default:
|
||||
throw new IllegalArgumentException("Unexpected value: " + parts);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getEnumUnderlayingType(boolean canUnsigned) {
|
||||
return canUnsigned ? "uint32_t" : "int32_t";
|
||||
}
|
||||
|
||||
public static OutputStreamWriter openOutputFile(String filename) throws Exception {
|
||||
FileOutputStream fs = new FileOutputStream(filename);
|
||||
return new OutputStreamWriter(fs, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static String escapeString(String strl) {
|
||||
|
||||
}
|
||||
|
||||
}
|
51
CodeGen/CKEnumCommentsHelper.java
Normal file
51
CodeGen/CKEnumCommentsHelper.java
Normal file
|
@ -0,0 +1,51 @@
|
|||
import org.antlr.v4.runtime.*;
|
||||
|
||||
public class CKEnumCommentsHelper {
|
||||
|
||||
enum CommentsPosition {
|
||||
Unknown, Precomment, Postcomment
|
||||
}
|
||||
|
||||
public CKEnumCommentsHelper(BufferedTokenStream tokenStream) {
|
||||
mTokenStream = tokenStream;
|
||||
mCommentsPos = CommentsPosition.Unknown;
|
||||
}
|
||||
|
||||
private BufferedTokenStream mTokenStream;
|
||||
private CommentsPosition mCommentsPos;
|
||||
|
||||
public String getComment(Token preToken, Token postToken) {
|
||||
switch (mCommentsPos) {
|
||||
case Unknown: {
|
||||
// if we don't know where is our token,
|
||||
// we should assume it is from precomment to postcomment
|
||||
// and check it.
|
||||
Token precomment = CKCommonHelper.getPreChannelToken(mTokenStream, preToken, CKGeneralLexer.COMMENTS);
|
||||
if (precomment != null) {
|
||||
mCommentsPos = CommentsPosition.Precomment;
|
||||
return CKCommonHelper.cutComment(precomment);
|
||||
}
|
||||
|
||||
Token postcomment = CKCommonHelper.getPostChannelToken(mTokenStream, postToken, CKGeneralLexer.COMMENTS);
|
||||
if (postcomment != null) {
|
||||
mCommentsPos = CommentsPosition.Postcomment;
|
||||
return CKCommonHelper.cutComment(postcomment);
|
||||
}
|
||||
|
||||
// really do not have comment, return empty and keep comment pos
|
||||
return null;
|
||||
}
|
||||
case Precomment: {
|
||||
Token comment = CKCommonHelper.getPreChannelToken(mTokenStream, preToken, CKGeneralLexer.COMMENTS);
|
||||
return CKCommonHelper.cutComment(comment);
|
||||
}
|
||||
case Postcomment: {
|
||||
Token comment = CKCommonHelper.getPostChannelToken(mTokenStream, postToken, CKGeneralLexer.COMMENTS);
|
||||
return CKCommonHelper.cutComment(comment);
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -4,11 +4,11 @@ options { tokenVocab = CKGeneralLexer; }
|
|||
prog: enumBody+ ;
|
||||
|
||||
enumBody: CKGENERAL_TYPEDEF? CKGENERAL_ENUM CKGENERAL_ID CKGENERAL_LBRACKET
|
||||
entryPair (CKGENERAL_COMMA entryPair)*
|
||||
entryPair+
|
||||
CKGENERAL_RBRACKET CKGENERAL_ID? CKGENERAL_SEMICOLON ;
|
||||
|
||||
entryPair: CKGENERAL_ID (CKGENERAL_EQUAL entryValue)? ;
|
||||
entryPair: CKGENERAL_ID (CKGENERAL_EQUAL entryValue)? CKGENERAL_COMMA? ;
|
||||
|
||||
entryValue: CKGENERAL_NUM (CKGENERAL_LSHIFT CKGENERAL_NUM)* # entryDirectValue
|
||||
entryValue: CKGENERAL_NUM (CKGENERAL_LSHIFT CKGENERAL_NUM)? # entryDirectValue
|
||||
| CKGENERAL_ID (CKGENERAL_OR CKGENERAL_ID)* # entryRelativeValue
|
||||
;
|
192
CodeGen/CKEnumRunner.java
Normal file
192
CodeGen/CKEnumRunner.java
Normal file
|
@ -0,0 +1,192 @@
|
|||
import java.io.OutputStreamWriter;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
||||
public class CKEnumRunner {
|
||||
public static class EnumEntry_t {
|
||||
public EnumEntry_t() {
|
||||
mEntryName = null;
|
||||
mEntryValue = null;
|
||||
mEntryComment = null;
|
||||
}
|
||||
|
||||
public String mEntryName;
|
||||
public String mEntryValue; // setting to null mean this entry do not have specified value.
|
||||
public String mEntryComment;
|
||||
}
|
||||
|
||||
public static class Enum_t {
|
||||
public Enum_t() {
|
||||
mEnumName = null;
|
||||
mEnumComment = null;
|
||||
mCanUnsigned = true;
|
||||
mEntries = new Vector<EnumEntry_t>();
|
||||
}
|
||||
|
||||
public String mEnumName;
|
||||
public String mEnumComment;
|
||||
public boolean mCanUnsigned;
|
||||
public Vector<EnumEntry_t> mEntries;
|
||||
}
|
||||
|
||||
public static class EnumWalker extends CKEnumParserBaseListener {
|
||||
public EnumWalker(BufferedTokenStream tokenStream) {
|
||||
mTokenStream = tokenStream;
|
||||
mCommentsHelper = new CKEnumCommentsHelper(tokenStream);
|
||||
mResult = null;
|
||||
|
||||
mCurrentProg = null;
|
||||
mCurrentEnum = null;
|
||||
mCurrentEntry = null;
|
||||
}
|
||||
|
||||
public List<Enum_t> getResult() {
|
||||
return mResult;
|
||||
}
|
||||
|
||||
private BufferedTokenStream mTokenStream;
|
||||
private CKEnumCommentsHelper mCommentsHelper;
|
||||
private Vector<Enum_t> mResult;
|
||||
|
||||
private Vector<Enum_t> mCurrentProg;
|
||||
private Enum_t mCurrentEnum;
|
||||
private EnumEntry_t mCurrentEntry;
|
||||
|
||||
@Override
|
||||
public void enterProg(CKEnumParser.ProgContext ctx) {
|
||||
mCurrentProg = new Vector<Enum_t>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitProg(CKEnumParser.ProgContext ctx) {
|
||||
mResult = mCurrentProg;
|
||||
mCurrentProg = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterEnumBody(CKEnumParser.EnumBodyContext ctx) {
|
||||
mCurrentEnum = new Enum_t();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitEnumBody(CKEnumParser.EnumBodyContext ctx) {
|
||||
// get enum comment
|
||||
mCurrentEnum.mEnumComment = CKCommonHelper.cutComment(
|
||||
CKCommonHelper.getPreChannelToken(mTokenStream, ctx.getStart(), CKGeneralLexer.COMMENTS));
|
||||
// get the last name (for typedef case)
|
||||
List<TerminalNode> allNames = ctx.CKGENERAL_ID();
|
||||
mCurrentEnum.mEnumName = allNames.get(allNames.size() - 1).getText();
|
||||
|
||||
mCurrentProg.add(mCurrentEnum);
|
||||
mCurrentEnum = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enterEntryPair(CKEnumParser.EntryPairContext ctx) {
|
||||
mCurrentEntry = new EnumEntry_t();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitEntryPair(CKEnumParser.EntryPairContext ctx) {
|
||||
// get entry comment
|
||||
mCurrentEntry.mEntryComment = mCommentsHelper.getComment(ctx.getStart(), ctx.getStop());
|
||||
// get entry name
|
||||
mCurrentEntry.mEntryName = ctx.CKGENERAL_ID().getText();
|
||||
|
||||
mCurrentEnum.mEntries.add(mCurrentEntry);
|
||||
mCurrentEntry = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitEntryDirectValue(CKEnumParser.EntryDirectValueContext ctx) {
|
||||
// get all numbers
|
||||
List<TerminalNode> nums = ctx.CKGENERAL_NUM();
|
||||
|
||||
switch (nums.size()) {
|
||||
case 1: {
|
||||
TerminalNode node = nums.get(0);
|
||||
// check whether target is minus number
|
||||
if (CKCommonHelper.isNegtiveNumber(node.getText())) {
|
||||
mCurrentEnum.mCanUnsigned = false;
|
||||
}
|
||||
// set value
|
||||
mCurrentEntry.mEntryValue = node.getText();
|
||||
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
TerminalNode num = nums.get(0), offset = nums.get(1);
|
||||
// set value
|
||||
mCurrentEntry.mEntryValue = String.format("{} << {}", num.getText(), offset.getText());
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new IllegalArgumentException("Unexpected value: " + nums.size());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exitEntryRelativeValue(CKEnumParser.EntryRelativeValueContext ctx) {
|
||||
// get all identifiers and join them
|
||||
mCurrentEntry.mEntryValue = String.join(" | ",
|
||||
ctx.CKGENERAL_ID().stream().map(value -> value.getText()).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class EnumProgWriter {
|
||||
public static void writeEnums(OutputStreamWriter writer, CKCommonHelper.CKParts parts, List<Enum_t> prog)
|
||||
throws Exception {
|
||||
CKIndentHelper indent = new CKIndentHelper(writer);
|
||||
indent.puts("#pragma once");
|
||||
indent.puts("#include <cstdint>");
|
||||
indent.printf("namespace LibCmo::{} {{", CKCommonHelper.getCKPartsNamespace(parts));
|
||||
indent.inc();
|
||||
|
||||
// write enums
|
||||
for (Enum_t enum_t : prog) {
|
||||
// write enum comment
|
||||
indent.briefComment(enum_t.mEnumComment);
|
||||
|
||||
// write enum start
|
||||
indent.printf("enum class {} : {} {{", enum_t.mEnumName,
|
||||
CKCommonHelper.getEnumUnderlayingType(enum_t.mCanUnsigned));
|
||||
indent.inc();
|
||||
|
||||
// write enum entries
|
||||
for (EnumEntry_t enumEntry_t : enum_t.mEntries) {
|
||||
// write entry self
|
||||
if (enumEntry_t.mEntryValue == null) {
|
||||
indent.printf("{},", enumEntry_t.mEntryName);
|
||||
} else {
|
||||
indent.printf("{} = {},", enumEntry_t.mEntryName, enumEntry_t.mEntryValue);
|
||||
}
|
||||
|
||||
// write entry comment after member
|
||||
indent.afterMemberComment(enumEntry_t.mEntryComment);
|
||||
}
|
||||
|
||||
// write enum tail
|
||||
indent.dec();
|
||||
indent.puts("}");
|
||||
}
|
||||
|
||||
indent.dec();
|
||||
indent.puts("}");
|
||||
}
|
||||
|
||||
public static void writeComments(OutputStreamWriter writer, List<Enum_t> prog) throws Exception {
|
||||
CKIndentHelper indent = new CKIndentHelper(writer);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static void Run(String infilename, String outfilename) {
|
||||
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@ CKGENERAL_COMMA: ',' ;
|
|||
|
||||
// identifider and number
|
||||
CKGENERAL_ID: [_a-zA-Z][_a-zA-Z0-9]* ;
|
||||
CKGENERAL_NUM: '-'? ('0' [xX])? [0-9a-fA-F]+ [uUlL]* ;
|
||||
CKGENERAL_NUM: (('0'[xX]) | '-')? [0-9a-fA-F]+ [uUlL]* ;
|
||||
|
||||
// comments
|
||||
CKGENERAL_LINE_COMMENT: '//' ~[\r\n]* -> channel(COMMENTS);
|
||||
|
|
47
CodeGen/CKIndentHelper.java
Normal file
47
CodeGen/CKIndentHelper.java
Normal file
|
@ -0,0 +1,47 @@
|
|||
import java.io.OutputStreamWriter;
|
||||
|
||||
public class CKIndentHelper {
|
||||
public CKIndentHelper(OutputStreamWriter writer) {
|
||||
mIndent = 0;
|
||||
}
|
||||
|
||||
private int mIndent;
|
||||
private OutputStreamWriter mWriter;
|
||||
|
||||
public void inc() {
|
||||
++mIndent;
|
||||
}
|
||||
|
||||
public void dec() {
|
||||
--mIndent;
|
||||
}
|
||||
|
||||
public void indent() throws Exception {
|
||||
mWriter.write("\n");
|
||||
for (int i = 0; i < mIndent; ++i) {
|
||||
mWriter.write("\t");
|
||||
}
|
||||
}
|
||||
|
||||
public void puts(String data) throws Exception {
|
||||
indent();
|
||||
mWriter.write(data);
|
||||
}
|
||||
|
||||
public void printf(String fmt, Object... args) throws Exception {
|
||||
indent();
|
||||
mWriter.write(String.format(fmt, args));
|
||||
}
|
||||
|
||||
public void briefComment(String fmt) throws Exception {
|
||||
if (fmt == null) return;
|
||||
printf("/**< {} */", fmt.replaceAll("[\\r\\n]+", ""));
|
||||
}
|
||||
|
||||
public void afterMemberComment(String fmt) throws Exception {
|
||||
if (fmt == null) return;
|
||||
mWriter.write("\t");
|
||||
mWriter.write(fmt);
|
||||
}
|
||||
|
||||
}
|
0
CodeGen/src/VXENUMS.txt
Normal file
0
CodeGen/src/VXENUMS.txt
Normal file
Loading…
Reference in New Issue
Block a user