write shit

This commit is contained in:
yyc12345 2023-08-18 15:55:31 +08:00
parent c1aac0beda
commit 77d8bbf3ba
9 changed files with 372 additions and 4 deletions

2
.gitignore vendored
View File

@ -13,6 +13,8 @@ temp/
## Special Treat of CodeGen ## Special Treat of CodeGen
CodeGen.old/ CodeGen.old/
CodeGen/dest/*.txt CodeGen/dest/*.txt
CodeGen/.*
CodeGen/*.class
CodeGen/CKGeneralLexer*.* CodeGen/CKGeneralLexer*.*
CodeGen/CKEnumParser*.* CodeGen/CKEnumParser*.*

View 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) {
}
}

View 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;
}
}
}

View File

@ -4,11 +4,11 @@ options { tokenVocab = CKGeneralLexer; }
prog: enumBody+ ; prog: enumBody+ ;
enumBody: CKGENERAL_TYPEDEF? CKGENERAL_ENUM CKGENERAL_ID CKGENERAL_LBRACKET enumBody: CKGENERAL_TYPEDEF? CKGENERAL_ENUM CKGENERAL_ID CKGENERAL_LBRACKET
entryPair (CKGENERAL_COMMA entryPair)* entryPair+
CKGENERAL_RBRACKET CKGENERAL_ID? CKGENERAL_SEMICOLON ; 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 | CKGENERAL_ID (CKGENERAL_OR CKGENERAL_ID)* # entryRelativeValue
; ;

192
CodeGen/CKEnumRunner.java Normal file
View 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) {
}
}

View File

@ -17,7 +17,7 @@ CKGENERAL_COMMA: ',' ;
// identifider and number // identifider and number
CKGENERAL_ID: [_a-zA-Z][_a-zA-Z0-9]* ; 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 // comments
CKGENERAL_LINE_COMMENT: '//' ~[\r\n]* -> channel(COMMENTS); CKGENERAL_LINE_COMMENT: '//' ~[\r\n]* -> channel(COMMENTS);

View 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
View File