diff --git a/.gitignore b/.gitignore index ccaa8eb..bd921f4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,23 +4,23 @@ *.nms *.vmo PyCmoOld/ - out/ temp/ - .vscode/ - -## Special Treat of CodeGen CodeGen.old/ -CodeGen/dest/*.hpp -CodeGen/.* -CodeGen/*.class -CodeGen/CKGeneralLexer*.* -CodeGen/CKEnumParser*.* -CodeGen/CKErrorParser*.* -CodeGen/CKClassidParser*.* -!CodeGen/*.g4 +## CMake Banned +CMakeLists.txt.user +CMakeCache.txt +CMakeFiles +CMakeScripts +Testing +Makefile +cmake_install.cmake +install_manifest.txt +compile_commands.json +CTestTestfile.cmake +_deps ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. diff --git a/CodeGen/.gitignore b/CodeGen/.gitignore new file mode 100644 index 0000000..808e5c6 --- /dev/null +++ b/CodeGen/.gitignore @@ -0,0 +1,34 @@ +# Antlr output +*.interp +*.tokens + +# Eclipse projects +.classpath +.project +.settings/ +.metadata + +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.jar +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* +replay_pid* diff --git a/CodeGen/CKClassidParser.g4 b/CodeGen/CKDefinesParser.g4 similarity index 79% rename from CodeGen/CKClassidParser.g4 rename to CodeGen/CKDefinesParser.g4 index dac8744..dd00ae3 100644 --- a/CodeGen/CKClassidParser.g4 +++ b/CodeGen/CKDefinesParser.g4 @@ -1,4 +1,4 @@ -parser grammar CKClassidParser; +parser grammar CKDefinesParser; options { tokenVocab = CKGeneralLexer; } prog: definePair+ ; diff --git a/CodeGen/CKDefinesParser.java b/CodeGen/CKDefinesParser.java new file mode 100644 index 0000000..3f8d4a3 --- /dev/null +++ b/CodeGen/CKDefinesParser.java @@ -0,0 +1,217 @@ +// Generated from CKDefinesParser.g4 by ANTLR 4.13.0 +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class CKDefinesParser extends Parser { + static { RuntimeMetaData.checkVersion("4.13.0", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + CKGENERAL_TYPEDEF=1, CKGENERAL_DEFINE=2, CKGENERAL_ENUM=3, CKGENERAL_LBRACKET=4, + CKGENERAL_RBRACKET=5, CKGENERAL_EQUAL=6, CKGENERAL_SEMICOLON=7, CKGENERAL_LSHIFT=8, + CKGENERAL_OR=9, CKGENERAL_COMMA=10, CKGENERAL_ID=11, CKGENERAL_NUM=12, + CKGENERAL_LINE_COMMENT=13, CKGENERAL_BLOCK_COMMENT=14, CKGENERAL_WS=15; + public static final int + RULE_prog = 0, RULE_definePair = 1; + private static String[] makeRuleNames() { + return new String[] { + "prog", "definePair" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'typedef'", "'#define'", "'enum'", "'{'", "'}'", "'='", "';'", + "'<<'", "'|'", "','" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "CKGENERAL_TYPEDEF", "CKGENERAL_DEFINE", "CKGENERAL_ENUM", "CKGENERAL_LBRACKET", + "CKGENERAL_RBRACKET", "CKGENERAL_EQUAL", "CKGENERAL_SEMICOLON", "CKGENERAL_LSHIFT", + "CKGENERAL_OR", "CKGENERAL_COMMA", "CKGENERAL_ID", "CKGENERAL_NUM", "CKGENERAL_LINE_COMMENT", + "CKGENERAL_BLOCK_COMMENT", "CKGENERAL_WS" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + 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] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "CKDefinesParser.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public CKDefinesParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @SuppressWarnings("CheckReturnValue") + public static class ProgContext extends ParserRuleContext { + public List definePair() { + return getRuleContexts(DefinePairContext.class); + } + public DefinePairContext definePair(int i) { + return getRuleContext(DefinePairContext.class,i); + } + public ProgContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_prog; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CKDefinesParserListener ) ((CKDefinesParserListener)listener).enterProg(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CKDefinesParserListener ) ((CKDefinesParserListener)listener).exitProg(this); + } + } + + public final ProgContext prog() throws RecognitionException { + ProgContext _localctx = new ProgContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_prog); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(5); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(4); + definePair(); + } + } + setState(7); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( _la==CKGENERAL_DEFINE ); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class DefinePairContext extends ParserRuleContext { + public TerminalNode CKGENERAL_DEFINE() { return getToken(CKDefinesParser.CKGENERAL_DEFINE, 0); } + public TerminalNode CKGENERAL_ID() { return getToken(CKDefinesParser.CKGENERAL_ID, 0); } + public TerminalNode CKGENERAL_NUM() { return getToken(CKDefinesParser.CKGENERAL_NUM, 0); } + public DefinePairContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_definePair; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CKDefinesParserListener ) ((CKDefinesParserListener)listener).enterDefinePair(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CKDefinesParserListener ) ((CKDefinesParserListener)listener).exitDefinePair(this); + } + } + + public final DefinePairContext definePair() throws RecognitionException { + DefinePairContext _localctx = new DefinePairContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_definePair); + try { + enterOuterAlt(_localctx, 1); + { + setState(9); + match(CKGENERAL_DEFINE); + setState(10); + match(CKGENERAL_ID); + setState(11); + match(CKGENERAL_NUM); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static final String _serializedATN = + "\u0004\u0001\u000f\u000e\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001"+ + "\u0001\u0000\u0004\u0000\u0006\b\u0000\u000b\u0000\f\u0000\u0007\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0000\u0000\u0002"+ + "\u0000\u0002\u0000\u0000\f\u0000\u0005\u0001\u0000\u0000\u0000\u0002\t"+ + "\u0001\u0000\u0000\u0000\u0004\u0006\u0003\u0002\u0001\u0000\u0005\u0004"+ + "\u0001\u0000\u0000\u0000\u0006\u0007\u0001\u0000\u0000\u0000\u0007\u0005"+ + "\u0001\u0000\u0000\u0000\u0007\b\u0001\u0000\u0000\u0000\b\u0001\u0001"+ + "\u0000\u0000\u0000\t\n\u0005\u0002\u0000\u0000\n\u000b\u0005\u000b\u0000"+ + "\u0000\u000b\f\u0005\f\u0000\u0000\f\u0003\u0001\u0000\u0000\u0000\u0001"+ + "\u0007"; + 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); + } + } +} \ No newline at end of file diff --git a/CodeGen/CKDefinesParserBaseListener.java b/CodeGen/CKDefinesParserBaseListener.java new file mode 100644 index 0000000..f9e6965 --- /dev/null +++ b/CodeGen/CKDefinesParserBaseListener.java @@ -0,0 +1,63 @@ +// Generated from CKDefinesParser.g4 by ANTLR 4.13.0 + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link CKDefinesParserListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +@SuppressWarnings("CheckReturnValue") +public class CKDefinesParserBaseListener implements CKDefinesParserListener { + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterProg(CKDefinesParser.ProgContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitProg(CKDefinesParser.ProgContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterDefinePair(CKDefinesParser.DefinePairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitDefinePair(CKDefinesParser.DefinePairContext ctx) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitErrorNode(ErrorNode node) { } +} \ No newline at end of file diff --git a/CodeGen/CKDefinesParserListener.java b/CodeGen/CKDefinesParserListener.java new file mode 100644 index 0000000..41eed41 --- /dev/null +++ b/CodeGen/CKDefinesParserListener.java @@ -0,0 +1,29 @@ +// Generated from CKDefinesParser.g4 by ANTLR 4.13.0 +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link CKDefinesParser}. + */ +public interface CKDefinesParserListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link CKDefinesParser#prog}. + * @param ctx the parse tree + */ + void enterProg(CKDefinesParser.ProgContext ctx); + /** + * Exit a parse tree produced by {@link CKDefinesParser#prog}. + * @param ctx the parse tree + */ + void exitProg(CKDefinesParser.ProgContext ctx); + /** + * Enter a parse tree produced by {@link CKDefinesParser#definePair}. + * @param ctx the parse tree + */ + void enterDefinePair(CKDefinesParser.DefinePairContext ctx); + /** + * Exit a parse tree produced by {@link CKDefinesParser#definePair}. + * @param ctx the parse tree + */ + void exitDefinePair(CKDefinesParser.DefinePairContext ctx); +} \ No newline at end of file diff --git a/CodeGen/CKEnumRunner.java b/CodeGen/CKEnumRunner.java deleted file mode 100644 index a6e062a..0000000 --- a/CodeGen/CKEnumRunner.java +++ /dev/null @@ -1,263 +0,0 @@ -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(); - } - - public String mEnumName; - public String mEnumComment; - public boolean mCanUnsigned; - public Vector 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 getResult() { - return mResult; - } - - private BufferedTokenStream mTokenStream; - private CKEnumCommentsHelper mCommentsHelper; - private Vector mResult; - - private Vector mCurrentProg; - private Enum_t mCurrentEnum; - private EnumEntry_t mCurrentEntry; - - @Override - public void enterProg(CKEnumParser.ProgContext ctx) { - mCurrentProg = new Vector(); - } - - @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 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 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 EnumWriter { - private static void writeEnum(CKIndentHelper indent, List prog) throws Exception { - for (Enum_t enum_t : prog) { - // write enum comment - indent.briefComment(enum_t.mEnumComment); - - // write enum start - indent.printf("enum class %s : %s {", enum_t.mEnumName, - CKCommonHelper.getEnumUnderlyingType(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("%s,", enumEntry_t.mEntryName); - } else { - indent.printf("%s = %s,", enumEntry_t.mEntryName, enumEntry_t.mEntryValue); - } - - // write entry comment after member - indent.afterMemberComment(enumEntry_t.mEntryComment); - } - - // write enum tail - indent.dec(); - indent.puts("};"); - } - } - - public static void writeEnums(OutputStreamWriter writer, List ck2_prog, List vxmath_prog) - throws Exception { - CKIndentHelper indent = new CKIndentHelper(writer); - indent.puts("#pragma once"); - indent.puts("#include "); - - indent.puts("namespace LibCmo::CK2 {"); - indent.inc(); - writeEnum(indent, ck2_prog); - indent.dec(); - indent.puts("}"); - - indent.puts("namespace LibCmo::VxMath {"); - indent.inc(); - writeEnum(indent, vxmath_prog); - indent.dec(); - indent.puts("}"); - } - - private static void writeAccessibleValue(CKIndentHelper indent, String parts, List prog) throws Exception { - for (Enum_t enum_t : prog) { - // write enum desc header - indent.printf("const EnumNameofArray {} {", - parts, enum_t.mEnumName, enum_t.mEnumName); - indent.inc(); - - // write enum desc entries - for (EnumEntry_t enumEntry_t : enum_t.mEntries) { - indent.printf("{ LibCmo::%s::%s::%s, \"%s\" },", - parts, enum_t.mEnumName, enumEntry_t.mEntryName, enumEntry_t.mEntryName); - } - - // write enum tail - indent.dec(); - indent.puts("};"); - } - } - - public static void writeAccessibleValues(OutputStreamWriter writer, List ck2_prog, List vxmath_prog) throws Exception { - CKIndentHelper indent = new CKIndentHelper(writer); - indent.puts("#pragma once"); - indent.puts("#include \"CKEnums.hpp\""); - indent.puts("#include "); - indent.puts("#include "); - indent.puts("#include "); - indent.puts("namespace Unvirt::AccessibleValue::EnumDesc {"); - indent.inc(); - - indent.puts("namespace CK2 {"); - indent.inc(); - writeAccessibleValue(indent, "CK2", ck2_prog); - indent.dec(); - indent.puts("}"); - - indent.puts("namespace VxMath {"); - indent.inc(); - writeAccessibleValue(indent, "VxMath", vxmath_prog); - indent.dec(); - indent.puts("}"); - - indent.dec(); - indent.puts("}"); - } - } - - private static List getProg(String infile) throws Exception { - CKCommonHelper.InputFilePair pair = CKCommonHelper.openInputFile(infile); - CKGeneralLexer lexer = new CKGeneralLexer(pair.mAntlrStream); - CommonTokenStream tokens = new CommonTokenStream(lexer); - CKEnumParser parser = new CKEnumParser(tokens); - - ParseTree tree = parser.prog(); - ParseTreeWalker walker = new ParseTreeWalker(); - EnumWalker worker = new EnumWalker(tokens); - walker.walk(worker, tree); - - pair.mUnderlyingStream.close(); - return worker.getResult(); - } - public static void run(String inCk2Enums, String inVxEnums, String outEnums, String outAccessibleValues) throws Exception { - List ck2prog = getProg(inCk2Enums); - List vxprog = getProg(inVxEnums); - - OutputStreamWriter fs = CKCommonHelper.openOutputFile(outEnums); - EnumWriter.writeEnums(fs, ck2prog, vxprog); - fs.close(); - - fs = CKCommonHelper.openOutputFile(outAccessibleValues); - EnumWriter.writeAccessibleValues(fs, ck2prog, vxprog); - fs.close(); - } -} diff --git a/CodeGen/CKEnumParser.g4 b/CodeGen/CKEnumsParser.g4 similarity index 93% rename from CodeGen/CKEnumParser.g4 rename to CodeGen/CKEnumsParser.g4 index bfaff38..a067a01 100644 --- a/CodeGen/CKEnumParser.g4 +++ b/CodeGen/CKEnumsParser.g4 @@ -1,4 +1,4 @@ -parser grammar CKEnumParser; +parser grammar CKEnumsParser; options { tokenVocab = CKGeneralLexer; } prog: enumBody* ; diff --git a/CodeGen/CKEnumsParser.java b/CodeGen/CKEnumsParser.java new file mode 100644 index 0000000..e59a52b --- /dev/null +++ b/CodeGen/CKEnumsParser.java @@ -0,0 +1,477 @@ +// Generated from CKEnumsParser.g4 by ANTLR 4.13.0 +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.misc.*; +import org.antlr.v4.runtime.tree.*; +import java.util.List; +import java.util.Iterator; +import java.util.ArrayList; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class CKEnumsParser extends Parser { + static { RuntimeMetaData.checkVersion("4.13.0", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + CKGENERAL_TYPEDEF=1, CKGENERAL_DEFINE=2, CKGENERAL_ENUM=3, CKGENERAL_LBRACKET=4, + CKGENERAL_RBRACKET=5, CKGENERAL_EQUAL=6, CKGENERAL_SEMICOLON=7, CKGENERAL_LSHIFT=8, + CKGENERAL_OR=9, CKGENERAL_COMMA=10, CKGENERAL_ID=11, CKGENERAL_NUM=12, + CKGENERAL_LINE_COMMENT=13, CKGENERAL_BLOCK_COMMENT=14, CKGENERAL_WS=15; + public static final int + RULE_prog = 0, RULE_enumBody = 1, RULE_entryPair = 2, RULE_entryValue = 3; + private static String[] makeRuleNames() { + return new String[] { + "prog", "enumBody", "entryPair", "entryValue" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'typedef'", "'#define'", "'enum'", "'{'", "'}'", "'='", "';'", + "'<<'", "'|'", "','" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "CKGENERAL_TYPEDEF", "CKGENERAL_DEFINE", "CKGENERAL_ENUM", "CKGENERAL_LBRACKET", + "CKGENERAL_RBRACKET", "CKGENERAL_EQUAL", "CKGENERAL_SEMICOLON", "CKGENERAL_LSHIFT", + "CKGENERAL_OR", "CKGENERAL_COMMA", "CKGENERAL_ID", "CKGENERAL_NUM", "CKGENERAL_LINE_COMMENT", + "CKGENERAL_BLOCK_COMMENT", "CKGENERAL_WS" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + 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] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + @Override + public String getGrammarFileName() { return "CKEnumsParser.g4"; } + + @Override + public String[] getRuleNames() { return ruleNames; } + + @Override + public String getSerializedATN() { return _serializedATN; } + + @Override + public ATN getATN() { return _ATN; } + + public CKEnumsParser(TokenStream input) { + super(input); + _interp = new ParserATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @SuppressWarnings("CheckReturnValue") + public static class ProgContext extends ParserRuleContext { + public List enumBody() { + return getRuleContexts(EnumBodyContext.class); + } + public EnumBodyContext enumBody(int i) { + return getRuleContext(EnumBodyContext.class,i); + } + public ProgContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_prog; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).enterProg(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).exitProg(this); + } + } + + public final ProgContext prog() throws RecognitionException { + ProgContext _localctx = new ProgContext(_ctx, getState()); + enterRule(_localctx, 0, RULE_prog); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(11); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==CKGENERAL_TYPEDEF || _la==CKGENERAL_ENUM) { + { + { + setState(8); + enumBody(); + } + } + setState(13); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class EnumBodyContext extends ParserRuleContext { + public TerminalNode CKGENERAL_ENUM() { return getToken(CKEnumsParser.CKGENERAL_ENUM, 0); } + public List CKGENERAL_ID() { return getTokens(CKEnumsParser.CKGENERAL_ID); } + public TerminalNode CKGENERAL_ID(int i) { + return getToken(CKEnumsParser.CKGENERAL_ID, i); + } + public TerminalNode CKGENERAL_LBRACKET() { return getToken(CKEnumsParser.CKGENERAL_LBRACKET, 0); } + public TerminalNode CKGENERAL_RBRACKET() { return getToken(CKEnumsParser.CKGENERAL_RBRACKET, 0); } + public TerminalNode CKGENERAL_SEMICOLON() { return getToken(CKEnumsParser.CKGENERAL_SEMICOLON, 0); } + public TerminalNode CKGENERAL_TYPEDEF() { return getToken(CKEnumsParser.CKGENERAL_TYPEDEF, 0); } + public List entryPair() { + return getRuleContexts(EntryPairContext.class); + } + public EntryPairContext entryPair(int i) { + return getRuleContext(EntryPairContext.class,i); + } + public EnumBodyContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_enumBody; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).enterEnumBody(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).exitEnumBody(this); + } + } + + public final EnumBodyContext enumBody() throws RecognitionException { + EnumBodyContext _localctx = new EnumBodyContext(_ctx, getState()); + enterRule(_localctx, 2, RULE_enumBody); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(15); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==CKGENERAL_TYPEDEF) { + { + setState(14); + match(CKGENERAL_TYPEDEF); + } + } + + setState(17); + match(CKGENERAL_ENUM); + setState(18); + match(CKGENERAL_ID); + setState(19); + match(CKGENERAL_LBRACKET); + setState(21); + _errHandler.sync(this); + _la = _input.LA(1); + do { + { + { + setState(20); + entryPair(); + } + } + setState(23); + _errHandler.sync(this); + _la = _input.LA(1); + } while ( _la==CKGENERAL_ID ); + setState(25); + match(CKGENERAL_RBRACKET); + setState(27); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==CKGENERAL_ID) { + { + setState(26); + match(CKGENERAL_ID); + } + } + + setState(29); + match(CKGENERAL_SEMICOLON); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class EntryPairContext extends ParserRuleContext { + public TerminalNode CKGENERAL_ID() { return getToken(CKEnumsParser.CKGENERAL_ID, 0); } + public TerminalNode CKGENERAL_EQUAL() { return getToken(CKEnumsParser.CKGENERAL_EQUAL, 0); } + public EntryValueContext entryValue() { + return getRuleContext(EntryValueContext.class,0); + } + public TerminalNode CKGENERAL_COMMA() { return getToken(CKEnumsParser.CKGENERAL_COMMA, 0); } + public EntryPairContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_entryPair; } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).enterEntryPair(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).exitEntryPair(this); + } + } + + public final EntryPairContext entryPair() throws RecognitionException { + EntryPairContext _localctx = new EntryPairContext(_ctx, getState()); + enterRule(_localctx, 4, RULE_entryPair); + int _la; + try { + enterOuterAlt(_localctx, 1); + { + setState(31); + match(CKGENERAL_ID); + setState(34); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==CKGENERAL_EQUAL) { + { + setState(32); + match(CKGENERAL_EQUAL); + setState(33); + entryValue(); + } + } + + setState(37); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==CKGENERAL_COMMA) { + { + setState(36); + match(CKGENERAL_COMMA); + } + } + + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + @SuppressWarnings("CheckReturnValue") + public static class EntryValueContext extends ParserRuleContext { + public EntryValueContext(ParserRuleContext parent, int invokingState) { + super(parent, invokingState); + } + @Override public int getRuleIndex() { return RULE_entryValue; } + + public EntryValueContext() { } + public void copyFrom(EntryValueContext ctx) { + super.copyFrom(ctx); + } + } + @SuppressWarnings("CheckReturnValue") + public static class EntryDirectValueContext extends EntryValueContext { + public List CKGENERAL_NUM() { return getTokens(CKEnumsParser.CKGENERAL_NUM); } + public TerminalNode CKGENERAL_NUM(int i) { + return getToken(CKEnumsParser.CKGENERAL_NUM, i); + } + public TerminalNode CKGENERAL_LSHIFT() { return getToken(CKEnumsParser.CKGENERAL_LSHIFT, 0); } + public EntryDirectValueContext(EntryValueContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).enterEntryDirectValue(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).exitEntryDirectValue(this); + } + } + @SuppressWarnings("CheckReturnValue") + public static class EntryRelativeValueContext extends EntryValueContext { + public List CKGENERAL_ID() { return getTokens(CKEnumsParser.CKGENERAL_ID); } + public TerminalNode CKGENERAL_ID(int i) { + return getToken(CKEnumsParser.CKGENERAL_ID, i); + } + public List CKGENERAL_OR() { return getTokens(CKEnumsParser.CKGENERAL_OR); } + public TerminalNode CKGENERAL_OR(int i) { + return getToken(CKEnumsParser.CKGENERAL_OR, i); + } + public EntryRelativeValueContext(EntryValueContext ctx) { copyFrom(ctx); } + @Override + public void enterRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).enterEntryRelativeValue(this); + } + @Override + public void exitRule(ParseTreeListener listener) { + if ( listener instanceof CKEnumsParserListener ) ((CKEnumsParserListener)listener).exitEntryRelativeValue(this); + } + } + + public final EntryValueContext entryValue() throws RecognitionException { + EntryValueContext _localctx = new EntryValueContext(_ctx, getState()); + enterRule(_localctx, 6, RULE_entryValue); + int _la; + try { + setState(52); + _errHandler.sync(this); + switch (_input.LA(1)) { + case CKGENERAL_NUM: + _localctx = new EntryDirectValueContext(_localctx); + enterOuterAlt(_localctx, 1); + { + setState(39); + match(CKGENERAL_NUM); + setState(42); + _errHandler.sync(this); + _la = _input.LA(1); + if (_la==CKGENERAL_LSHIFT) { + { + setState(40); + match(CKGENERAL_LSHIFT); + setState(41); + match(CKGENERAL_NUM); + } + } + + } + break; + case CKGENERAL_ID: + _localctx = new EntryRelativeValueContext(_localctx); + enterOuterAlt(_localctx, 2); + { + setState(44); + match(CKGENERAL_ID); + setState(49); + _errHandler.sync(this); + _la = _input.LA(1); + while (_la==CKGENERAL_OR) { + { + { + setState(45); + match(CKGENERAL_OR); + setState(46); + match(CKGENERAL_ID); + } + } + setState(51); + _errHandler.sync(this); + _la = _input.LA(1); + } + } + break; + default: + throw new NoViableAltException(this); + } + } + catch (RecognitionException re) { + _localctx.exception = re; + _errHandler.reportError(this, re); + _errHandler.recover(this, re); + } + finally { + exitRule(); + } + return _localctx; + } + + public static final String _serializedATN = + "\u0004\u0001\u000f7\u0002\u0000\u0007\u0000\u0002\u0001\u0007\u0001\u0002"+ + "\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0001\u0000\u0005\u0000\n\b"+ + "\u0000\n\u0000\f\u0000\r\t\u0000\u0001\u0001\u0003\u0001\u0010\b\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0004\u0001\u0016\b\u0001"+ + "\u000b\u0001\f\u0001\u0017\u0001\u0001\u0001\u0001\u0003\u0001\u001c\b"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001\u0002\u0003"+ + "\u0002#\b\u0002\u0001\u0002\u0003\u0002&\b\u0002\u0001\u0003\u0001\u0003"+ + "\u0001\u0003\u0003\u0003+\b\u0003\u0001\u0003\u0001\u0003\u0001\u0003"+ + "\u0005\u00030\b\u0003\n\u0003\f\u00033\t\u0003\u0003\u00035\b\u0003\u0001"+ + "\u0003\u0000\u0000\u0004\u0000\u0002\u0004\u0006\u0000\u0000;\u0000\u000b"+ + "\u0001\u0000\u0000\u0000\u0002\u000f\u0001\u0000\u0000\u0000\u0004\u001f"+ + "\u0001\u0000\u0000\u0000\u00064\u0001\u0000\u0000\u0000\b\n\u0003\u0002"+ + "\u0001\u0000\t\b\u0001\u0000\u0000\u0000\n\r\u0001\u0000\u0000\u0000\u000b"+ + "\t\u0001\u0000\u0000\u0000\u000b\f\u0001\u0000\u0000\u0000\f\u0001\u0001"+ + "\u0000\u0000\u0000\r\u000b\u0001\u0000\u0000\u0000\u000e\u0010\u0005\u0001"+ + "\u0000\u0000\u000f\u000e\u0001\u0000\u0000\u0000\u000f\u0010\u0001\u0000"+ + "\u0000\u0000\u0010\u0011\u0001\u0000\u0000\u0000\u0011\u0012\u0005\u0003"+ + "\u0000\u0000\u0012\u0013\u0005\u000b\u0000\u0000\u0013\u0015\u0005\u0004"+ + "\u0000\u0000\u0014\u0016\u0003\u0004\u0002\u0000\u0015\u0014\u0001\u0000"+ + "\u0000\u0000\u0016\u0017\u0001\u0000\u0000\u0000\u0017\u0015\u0001\u0000"+ + "\u0000\u0000\u0017\u0018\u0001\u0000\u0000\u0000\u0018\u0019\u0001\u0000"+ + "\u0000\u0000\u0019\u001b\u0005\u0005\u0000\u0000\u001a\u001c\u0005\u000b"+ + "\u0000\u0000\u001b\u001a\u0001\u0000\u0000\u0000\u001b\u001c\u0001\u0000"+ + "\u0000\u0000\u001c\u001d\u0001\u0000\u0000\u0000\u001d\u001e\u0005\u0007"+ + "\u0000\u0000\u001e\u0003\u0001\u0000\u0000\u0000\u001f\"\u0005\u000b\u0000"+ + "\u0000 !\u0005\u0006\u0000\u0000!#\u0003\u0006\u0003\u0000\" \u0001\u0000"+ + "\u0000\u0000\"#\u0001\u0000\u0000\u0000#%\u0001\u0000\u0000\u0000$&\u0005"+ + "\n\u0000\u0000%$\u0001\u0000\u0000\u0000%&\u0001\u0000\u0000\u0000&\u0005"+ + "\u0001\u0000\u0000\u0000\'*\u0005\f\u0000\u0000()\u0005\b\u0000\u0000"+ + ")+\u0005\f\u0000\u0000*(\u0001\u0000\u0000\u0000*+\u0001\u0000\u0000\u0000"+ + "+5\u0001\u0000\u0000\u0000,1\u0005\u000b\u0000\u0000-.\u0005\t\u0000\u0000"+ + ".0\u0005\u000b\u0000\u0000/-\u0001\u0000\u0000\u000003\u0001\u0000\u0000"+ + "\u00001/\u0001\u0000\u0000\u000012\u0001\u0000\u0000\u000025\u0001\u0000"+ + "\u0000\u000031\u0001\u0000\u0000\u00004\'\u0001\u0000\u0000\u00004,\u0001"+ + "\u0000\u0000\u00005\u0007\u0001\u0000\u0000\u0000\t\u000b\u000f\u0017"+ + "\u001b\"%*14"; + 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); + } + } +} \ No newline at end of file diff --git a/CodeGen/CKEnumsParserBaseListener.java b/CodeGen/CKEnumsParserBaseListener.java new file mode 100644 index 0000000..7e1cc45 --- /dev/null +++ b/CodeGen/CKEnumsParserBaseListener.java @@ -0,0 +1,99 @@ +// Generated from CKEnumsParser.g4 by ANTLR 4.13.0 + +import org.antlr.v4.runtime.ParserRuleContext; +import org.antlr.v4.runtime.tree.ErrorNode; +import org.antlr.v4.runtime.tree.TerminalNode; + +/** + * This class provides an empty implementation of {@link CKEnumsParserListener}, + * which can be extended to create a listener which only needs to handle a subset + * of the available methods. + */ +@SuppressWarnings("CheckReturnValue") +public class CKEnumsParserBaseListener implements CKEnumsParserListener { + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterProg(CKEnumsParser.ProgContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitProg(CKEnumsParser.ProgContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEnumBody(CKEnumsParser.EnumBodyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEnumBody(CKEnumsParser.EnumBodyContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEntryPair(CKEnumsParser.EntryPairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEntryPair(CKEnumsParser.EntryPairContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEntryDirectValue(CKEnumsParser.EntryDirectValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEntryDirectValue(CKEnumsParser.EntryDirectValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEntryRelativeValue(CKEnumsParser.EntryRelativeValueContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEntryRelativeValue(CKEnumsParser.EntryRelativeValueContext ctx) { } + + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void enterEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void exitEveryRule(ParserRuleContext ctx) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitTerminal(TerminalNode node) { } + /** + * {@inheritDoc} + * + *

The default implementation does nothing.

+ */ + @Override public void visitErrorNode(ErrorNode node) { } +} \ No newline at end of file diff --git a/CodeGen/CKEnumsParserListener.java b/CodeGen/CKEnumsParserListener.java new file mode 100644 index 0000000..d1d0102 --- /dev/null +++ b/CodeGen/CKEnumsParserListener.java @@ -0,0 +1,63 @@ +// Generated from CKEnumsParser.g4 by ANTLR 4.13.0 +import org.antlr.v4.runtime.tree.ParseTreeListener; + +/** + * This interface defines a complete listener for a parse tree produced by + * {@link CKEnumsParser}. + */ +public interface CKEnumsParserListener extends ParseTreeListener { + /** + * Enter a parse tree produced by {@link CKEnumsParser#prog}. + * @param ctx the parse tree + */ + void enterProg(CKEnumsParser.ProgContext ctx); + /** + * Exit a parse tree produced by {@link CKEnumsParser#prog}. + * @param ctx the parse tree + */ + void exitProg(CKEnumsParser.ProgContext ctx); + /** + * Enter a parse tree produced by {@link CKEnumsParser#enumBody}. + * @param ctx the parse tree + */ + void enterEnumBody(CKEnumsParser.EnumBodyContext ctx); + /** + * Exit a parse tree produced by {@link CKEnumsParser#enumBody}. + * @param ctx the parse tree + */ + void exitEnumBody(CKEnumsParser.EnumBodyContext ctx); + /** + * Enter a parse tree produced by {@link CKEnumsParser#entryPair}. + * @param ctx the parse tree + */ + void enterEntryPair(CKEnumsParser.EntryPairContext ctx); + /** + * Exit a parse tree produced by {@link CKEnumsParser#entryPair}. + * @param ctx the parse tree + */ + void exitEntryPair(CKEnumsParser.EntryPairContext ctx); + /** + * Enter a parse tree produced by the {@code entryDirectValue} + * labeled alternative in {@link CKEnumsParser#entryValue}. + * @param ctx the parse tree + */ + void enterEntryDirectValue(CKEnumsParser.EntryDirectValueContext ctx); + /** + * Exit a parse tree produced by the {@code entryDirectValue} + * labeled alternative in {@link CKEnumsParser#entryValue}. + * @param ctx the parse tree + */ + void exitEntryDirectValue(CKEnumsParser.EntryDirectValueContext ctx); + /** + * Enter a parse tree produced by the {@code entryRelativeValue} + * labeled alternative in {@link CKEnumsParser#entryValue}. + * @param ctx the parse tree + */ + void enterEntryRelativeValue(CKEnumsParser.EntryRelativeValueContext ctx); + /** + * Exit a parse tree produced by the {@code entryRelativeValue} + * labeled alternative in {@link CKEnumsParser#entryValue}. + * @param ctx the parse tree + */ + void exitEntryRelativeValue(CKEnumsParser.EntryRelativeValueContext ctx); +} \ No newline at end of file diff --git a/CodeGen/CKEnumsRunner.java b/CodeGen/CKEnumsRunner.java new file mode 100644 index 0000000..8c32242 --- /dev/null +++ b/CodeGen/CKEnumsRunner.java @@ -0,0 +1,37 @@ +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 CKEnumsRunner { + + private static List getProg(String infile) throws Exception { + CKCommonHelper.InputFilePair pair = CKCommonHelper.openInputFile(infile); + CKGeneralLexer lexer = new CKGeneralLexer(pair.mAntlrStream); + CommonTokenStream tokens = new CommonTokenStream(lexer); + CKEnumParser parser = new CKEnumParser(tokens); + + ParseTree tree = parser.prog(); + ParseTreeWalker walker = new ParseTreeWalker(); + EnumWalker worker = new EnumWalker(tokens); + walker.walk(worker, tree); + + pair.mUnderlyingStream.close(); + return worker.getResult(); + } + public static void run(String inCk2Enums, String inVxEnums, String outEnums, String outAccessibleValues) throws Exception { + List ck2prog = getProg(inCk2Enums); + List vxprog = getProg(inVxEnums); + + OutputStreamWriter fs = CKCommonHelper.openOutputFile(outEnums); + EnumWriter.writeEnums(fs, ck2prog, vxprog); + fs.close(); + + fs = CKCommonHelper.openOutputFile(outAccessibleValues); + EnumWriter.writeAccessibleValues(fs, ck2prog, vxprog); + fs.close(); + } +} diff --git a/CodeGen/CKErrorParser.g4 b/CodeGen/CKErrorParser.g4 deleted file mode 100644 index 6cc9aa7..0000000 --- a/CodeGen/CKErrorParser.g4 +++ /dev/null @@ -1,6 +0,0 @@ -parser grammar CKErrorParser; -options { tokenVocab = CKGeneralLexer; } - -prog: definePair+ ; - -definePair: CKGENERAL_DEFINE CKGENERAL_ID CKGENERAL_NUM ; diff --git a/CodeGen/CKGeneralLexer.java b/CodeGen/CKGeneralLexer.java new file mode 100644 index 0000000..41fbac4 --- /dev/null +++ b/CodeGen/CKGeneralLexer.java @@ -0,0 +1,196 @@ +// Generated from CKGeneralLexer.g4 by ANTLR 4.13.0 +import org.antlr.v4.runtime.Lexer; +import org.antlr.v4.runtime.CharStream; +import org.antlr.v4.runtime.Token; +import org.antlr.v4.runtime.TokenStream; +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.atn.*; +import org.antlr.v4.runtime.dfa.DFA; +import org.antlr.v4.runtime.misc.*; + +@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast", "CheckReturnValue"}) +public class CKGeneralLexer extends Lexer { + static { RuntimeMetaData.checkVersion("4.13.0", RuntimeMetaData.VERSION); } + + protected static final DFA[] _decisionToDFA; + protected static final PredictionContextCache _sharedContextCache = + new PredictionContextCache(); + public static final int + CKGENERAL_TYPEDEF=1, CKGENERAL_DEFINE=2, CKGENERAL_ENUM=3, CKGENERAL_LBRACKET=4, + CKGENERAL_RBRACKET=5, CKGENERAL_EQUAL=6, CKGENERAL_SEMICOLON=7, CKGENERAL_LSHIFT=8, + CKGENERAL_OR=9, CKGENERAL_COMMA=10, CKGENERAL_ID=11, CKGENERAL_NUM=12, + CKGENERAL_LINE_COMMENT=13, CKGENERAL_BLOCK_COMMENT=14, CKGENERAL_WS=15; + public static final int + COMMENTS=2, WHITESPACE=3; + public static String[] channelNames = { + "DEFAULT_TOKEN_CHANNEL", "HIDDEN", "COMMENTS", "WHITESPACE" + }; + + public static String[] modeNames = { + "DEFAULT_MODE" + }; + + private static String[] makeRuleNames() { + return new String[] { + "CKGENERAL_TYPEDEF", "CKGENERAL_DEFINE", "CKGENERAL_ENUM", "CKGENERAL_LBRACKET", + "CKGENERAL_RBRACKET", "CKGENERAL_EQUAL", "CKGENERAL_SEMICOLON", "CKGENERAL_LSHIFT", + "CKGENERAL_OR", "CKGENERAL_COMMA", "CKGENERAL_ID", "CKGENERAL_NUM", "CKGENERAL_LINE_COMMENT", + "CKGENERAL_BLOCK_COMMENT", "CKGENERAL_WS" + }; + } + public static final String[] ruleNames = makeRuleNames(); + + private static String[] makeLiteralNames() { + return new String[] { + null, "'typedef'", "'#define'", "'enum'", "'{'", "'}'", "'='", "';'", + "'<<'", "'|'", "','" + }; + } + private static final String[] _LITERAL_NAMES = makeLiteralNames(); + private static String[] makeSymbolicNames() { + return new String[] { + null, "CKGENERAL_TYPEDEF", "CKGENERAL_DEFINE", "CKGENERAL_ENUM", "CKGENERAL_LBRACKET", + "CKGENERAL_RBRACKET", "CKGENERAL_EQUAL", "CKGENERAL_SEMICOLON", "CKGENERAL_LSHIFT", + "CKGENERAL_OR", "CKGENERAL_COMMA", "CKGENERAL_ID", "CKGENERAL_NUM", "CKGENERAL_LINE_COMMENT", + "CKGENERAL_BLOCK_COMMENT", "CKGENERAL_WS" + }; + } + private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames(); + 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] = ""; + } + } + } + + @Override + @Deprecated + public String[] getTokenNames() { + return tokenNames; + } + + @Override + + public Vocabulary getVocabulary() { + return VOCABULARY; + } + + + public CKGeneralLexer(CharStream input) { + super(input); + _interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache); + } + + @Override + public String getGrammarFileName() { return "CKGeneralLexer.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 = + "\u0004\u0000\u000fz\u0006\uffff\uffff\u0002\u0000\u0007\u0000\u0002\u0001"+ + "\u0007\u0001\u0002\u0002\u0007\u0002\u0002\u0003\u0007\u0003\u0002\u0004"+ + "\u0007\u0004\u0002\u0005\u0007\u0005\u0002\u0006\u0007\u0006\u0002\u0007"+ + "\u0007\u0007\u0002\b\u0007\b\u0002\t\u0007\t\u0002\n\u0007\n\u0002\u000b"+ + "\u0007\u000b\u0002\f\u0007\f\u0002\r\u0007\r\u0002\u000e\u0007\u000e\u0001"+ + "\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001\u0000\u0001"+ + "\u0000\u0001\u0000\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001"+ + "\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0001\u0002\u0001\u0002\u0001"+ + "\u0002\u0001\u0002\u0001\u0002\u0001\u0003\u0001\u0003\u0001\u0004\u0001"+ + "\u0004\u0001\u0005\u0001\u0005\u0001\u0006\u0001\u0006\u0001\u0007\u0001"+ + "\u0007\u0001\u0007\u0001\b\u0001\b\u0001\t\u0001\t\u0001\n\u0001\n\u0005"+ + "\nF\b\n\n\n\f\nI\t\n\u0001\u000b\u0001\u000b\u0001\u000b\u0003\u000bN"+ + "\b\u000b\u0001\u000b\u0004\u000bQ\b\u000b\u000b\u000b\f\u000bR\u0001\u000b"+ + "\u0005\u000bV\b\u000b\n\u000b\f\u000bY\t\u000b\u0001\f\u0001\f\u0001\f"+ + "\u0001\f\u0005\f_\b\f\n\f\f\fb\t\f\u0001\f\u0001\f\u0001\r\u0001\r\u0001"+ + "\r\u0001\r\u0005\rj\b\r\n\r\f\rm\t\r\u0001\r\u0001\r\u0001\r\u0001\r\u0001"+ + "\r\u0001\u000e\u0004\u000eu\b\u000e\u000b\u000e\f\u000ev\u0001\u000e\u0001"+ + "\u000e\u0001k\u0000\u000f\u0001\u0001\u0003\u0002\u0005\u0003\u0007\u0004"+ + "\t\u0005\u000b\u0006\r\u0007\u000f\b\u0011\t\u0013\n\u0015\u000b\u0017"+ + "\f\u0019\r\u001b\u000e\u001d\u000f\u0001\u0000\u0007\u0003\u0000AZ__a"+ + "z\u0004\u000009AZ__az\u0002\u0000XXxx\u0003\u000009AFaf\u0004\u0000LL"+ + "UUlluu\u0002\u0000\n\n\r\r\u0003\u0000\t\n\r\r \u0081\u0000\u0001\u0001"+ + "\u0000\u0000\u0000\u0000\u0003\u0001\u0000\u0000\u0000\u0000\u0005\u0001"+ + "\u0000\u0000\u0000\u0000\u0007\u0001\u0000\u0000\u0000\u0000\t\u0001\u0000"+ + "\u0000\u0000\u0000\u000b\u0001\u0000\u0000\u0000\u0000\r\u0001\u0000\u0000"+ + "\u0000\u0000\u000f\u0001\u0000\u0000\u0000\u0000\u0011\u0001\u0000\u0000"+ + "\u0000\u0000\u0013\u0001\u0000\u0000\u0000\u0000\u0015\u0001\u0000\u0000"+ + "\u0000\u0000\u0017\u0001\u0000\u0000\u0000\u0000\u0019\u0001\u0000\u0000"+ + "\u0000\u0000\u001b\u0001\u0000\u0000\u0000\u0000\u001d\u0001\u0000\u0000"+ + "\u0000\u0001\u001f\u0001\u0000\u0000\u0000\u0003\'\u0001\u0000\u0000\u0000"+ + "\u0005/\u0001\u0000\u0000\u0000\u00074\u0001\u0000\u0000\u0000\t6\u0001"+ + "\u0000\u0000\u0000\u000b8\u0001\u0000\u0000\u0000\r:\u0001\u0000\u0000"+ + "\u0000\u000f<\u0001\u0000\u0000\u0000\u0011?\u0001\u0000\u0000\u0000\u0013"+ + "A\u0001\u0000\u0000\u0000\u0015C\u0001\u0000\u0000\u0000\u0017M\u0001"+ + "\u0000\u0000\u0000\u0019Z\u0001\u0000\u0000\u0000\u001be\u0001\u0000\u0000"+ + "\u0000\u001dt\u0001\u0000\u0000\u0000\u001f \u0005t\u0000\u0000 !\u0005"+ + "y\u0000\u0000!\"\u0005p\u0000\u0000\"#\u0005e\u0000\u0000#$\u0005d\u0000"+ + "\u0000$%\u0005e\u0000\u0000%&\u0005f\u0000\u0000&\u0002\u0001\u0000\u0000"+ + "\u0000\'(\u0005#\u0000\u0000()\u0005d\u0000\u0000)*\u0005e\u0000\u0000"+ + "*+\u0005f\u0000\u0000+,\u0005i\u0000\u0000,-\u0005n\u0000\u0000-.\u0005"+ + "e\u0000\u0000.\u0004\u0001\u0000\u0000\u0000/0\u0005e\u0000\u000001\u0005"+ + "n\u0000\u000012\u0005u\u0000\u000023\u0005m\u0000\u00003\u0006\u0001\u0000"+ + "\u0000\u000045\u0005{\u0000\u00005\b\u0001\u0000\u0000\u000067\u0005}"+ + "\u0000\u00007\n\u0001\u0000\u0000\u000089\u0005=\u0000\u00009\f\u0001"+ + "\u0000\u0000\u0000:;\u0005;\u0000\u0000;\u000e\u0001\u0000\u0000\u0000"+ + "<=\u0005<\u0000\u0000=>\u0005<\u0000\u0000>\u0010\u0001\u0000\u0000\u0000"+ + "?@\u0005|\u0000\u0000@\u0012\u0001\u0000\u0000\u0000AB\u0005,\u0000\u0000"+ + "B\u0014\u0001\u0000\u0000\u0000CG\u0007\u0000\u0000\u0000DF\u0007\u0001"+ + "\u0000\u0000ED\u0001\u0000\u0000\u0000FI\u0001\u0000\u0000\u0000GE\u0001"+ + "\u0000\u0000\u0000GH\u0001\u0000\u0000\u0000H\u0016\u0001\u0000\u0000"+ + "\u0000IG\u0001\u0000\u0000\u0000JK\u00050\u0000\u0000KN\u0007\u0002\u0000"+ + "\u0000LN\u0005-\u0000\u0000MJ\u0001\u0000\u0000\u0000ML\u0001\u0000\u0000"+ + "\u0000MN\u0001\u0000\u0000\u0000NP\u0001\u0000\u0000\u0000OQ\u0007\u0003"+ + "\u0000\u0000PO\u0001\u0000\u0000\u0000QR\u0001\u0000\u0000\u0000RP\u0001"+ + "\u0000\u0000\u0000RS\u0001\u0000\u0000\u0000SW\u0001\u0000\u0000\u0000"+ + "TV\u0007\u0004\u0000\u0000UT\u0001\u0000\u0000\u0000VY\u0001\u0000\u0000"+ + "\u0000WU\u0001\u0000\u0000\u0000WX\u0001\u0000\u0000\u0000X\u0018\u0001"+ + "\u0000\u0000\u0000YW\u0001\u0000\u0000\u0000Z[\u0005/\u0000\u0000[\\\u0005"+ + "/\u0000\u0000\\`\u0001\u0000\u0000\u0000]_\b\u0005\u0000\u0000^]\u0001"+ + "\u0000\u0000\u0000_b\u0001\u0000\u0000\u0000`^\u0001\u0000\u0000\u0000"+ + "`a\u0001\u0000\u0000\u0000ac\u0001\u0000\u0000\u0000b`\u0001\u0000\u0000"+ + "\u0000cd\u0006\f\u0000\u0000d\u001a\u0001\u0000\u0000\u0000ef\u0005/\u0000"+ + "\u0000fg\u0005*\u0000\u0000gk\u0001\u0000\u0000\u0000hj\t\u0000\u0000"+ + "\u0000ih\u0001\u0000\u0000\u0000jm\u0001\u0000\u0000\u0000kl\u0001\u0000"+ + "\u0000\u0000ki\u0001\u0000\u0000\u0000ln\u0001\u0000\u0000\u0000mk\u0001"+ + "\u0000\u0000\u0000no\u0005*\u0000\u0000op\u0005/\u0000\u0000pq\u0001\u0000"+ + "\u0000\u0000qr\u0006\r\u0000\u0000r\u001c\u0001\u0000\u0000\u0000su\u0007"+ + "\u0006\u0000\u0000ts\u0001\u0000\u0000\u0000uv\u0001\u0000\u0000\u0000"+ + "vt\u0001\u0000\u0000\u0000vw\u0001\u0000\u0000\u0000wx\u0001\u0000\u0000"+ + "\u0000xy\u0006\u000e\u0001\u0000y\u001e\u0001\u0000\u0000\u0000\b\u0000"+ + "GMRW`kv\u0002\u0000\u0002\u0000\u0000\u0003\u0000"; + 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); + } + } +} \ No newline at end of file diff --git a/CodeGen/CKMainGen.java b/CodeGen/CKMain.java similarity index 89% rename from CodeGen/CKMainGen.java rename to CodeGen/CKMain.java index 64072d9..a12d73a 100644 --- a/CodeGen/CKMainGen.java +++ b/CodeGen/CKMain.java @@ -1,5 +1,5 @@ -public class CKMainGen { +public class CKMain { public static void main(String[] args) throws Exception { CKEnumRunner.run("src/CKENUMS.txt", "src/VXENUMS.txt", "dest/CKEnums.gen.hpp", "dest/AccessibleValue.gen.hpp"); System.out.println("DONE!"); diff --git a/CodeGen/ClassidWalker.java b/CodeGen/ClassidWalker.java new file mode 100644 index 0000000..00065cb --- /dev/null +++ b/CodeGen/ClassidWalker.java @@ -0,0 +1,28 @@ + +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.tree.*; + +/** + * The specialized walker for collecting CK_CLASSID and its inherit relationship. + */ +public class ClassidWalker extends CKDefinesParserBaseListener { + + @Override + public void enterProg(CKDefinesParser.ProgContext ctx) { + // TODO Auto-generated method stub + super.enterProg(ctx); + } + + @Override + public void exitProg(CKDefinesParser.ProgContext ctx) { + // TODO Auto-generated method stub + super.exitProg(ctx); + } + + @Override + public void exitDefinePair(CKDefinesParser.DefinePairContext ctx) { + // TODO Auto-generated method stub + super.exitDefinePair(ctx); + } + +} diff --git a/CodeGen/ClassidWriter.java b/CodeGen/ClassidWriter.java new file mode 100644 index 0000000..2403d0f --- /dev/null +++ b/CodeGen/ClassidWriter.java @@ -0,0 +1,7 @@ + +/** + * The accessible values writer of CK_CLASSID. + */ +public class ClassidWriter { + +} diff --git a/CodeGen/CKEnumCommentsHelper.java b/CodeGen/CommentsFinder.java similarity index 53% rename from CodeGen/CKEnumCommentsHelper.java rename to CodeGen/CommentsFinder.java index 1d4122b..59bd0d7 100644 --- a/CodeGen/CKEnumCommentsHelper.java +++ b/CodeGen/CommentsFinder.java @@ -1,12 +1,14 @@ +import java.util.List; + import org.antlr.v4.runtime.*; -public class CKEnumCommentsHelper { +public class CommentsFinder { enum CommentsPosition { Unknown, Precomment, Postcomment } - public CKEnumCommentsHelper(BufferedTokenStream tokenStream) { + public CommentsFinder(BufferedTokenStream tokenStream) { mTokenStream = tokenStream; mCommentsPos = CommentsPosition.Unknown; } @@ -20,28 +22,26 @@ public class CKEnumCommentsHelper { // 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); + List precomment = CommonHelper.getPreChannelTokens(mTokenStream, preToken, CKGeneralLexer.COMMENTS); if (precomment != null) { mCommentsPos = CommentsPosition.Precomment; - return CKCommonHelper.cutComment(precomment); + return CommonHelper.cutComments(precomment); } - Token postcomment = CKCommonHelper.getPostChannelToken(mTokenStream, postToken, CKGeneralLexer.COMMENTS); + List postcomment = CommonHelper.getPostChannelTokens(mTokenStream, postToken, CKGeneralLexer.COMMENTS); if (postcomment != null) { mCommentsPos = CommentsPosition.Postcomment; - return CKCommonHelper.cutComment(postcomment); + return CommonHelper.cutComments(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); + return CommonHelper.cutComments(CommonHelper.getPreChannelTokens(mTokenStream, preToken, CKGeneralLexer.COMMENTS)); } case Postcomment: { - Token comment = CKCommonHelper.getPostChannelToken(mTokenStream, postToken, CKGeneralLexer.COMMENTS); - return CKCommonHelper.cutComment(comment); + return CommonHelper.cutComments(CommonHelper.getPostChannelTokens(mTokenStream, postToken, CKGeneralLexer.COMMENTS)); } default: return null; diff --git a/CodeGen/CKCommonHelper.java b/CodeGen/CommonHelper.java similarity index 64% rename from CodeGen/CKCommonHelper.java rename to CodeGen/CommonHelper.java index 00a32ee..f6f4ff5 100644 --- a/CodeGen/CKCommonHelper.java +++ b/CodeGen/CommonHelper.java @@ -3,10 +3,13 @@ import java.io.FileOutputStream; import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.List; +import java.util.stream.Collectors; import org.antlr.v4.runtime.*; -public class CKCommonHelper { +public class CommonHelper { + + // =========== Token Finder & Comments Processing =========== public static Token getPreChannelToken(BufferedTokenStream stream, Token token, int channel) { List tokens = stream.getHiddenTokensToLeft(token.getTokenIndex(), channel); @@ -21,7 +24,21 @@ public class CKCommonHelper { return null; return tokens.get(0); } + + public static List getPreChannelTokens(BufferedTokenStream stream, Token token, int channel) { + return stream.getHiddenTokensToLeft(token.getTokenIndex(), channel); + } + public static List 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. + */ public static String cutComment(Token comment) { if (comment == null) return null; @@ -39,10 +56,60 @@ public class CKCommonHelper { } } - public static boolean isNegtiveNumber(String numstr) { + /** + * Cut multiple comments. + *

+ * Each comment will be cut the head and tail first. + * And strip all whitespace. + * Then join together. + * + * @param tokens Multiple comments. + * @return The joined comment. + */ + public static String cutComments(List tokens) { + if (tokens == null) + return null; + + return tokens.stream().map(value -> { + String text = cutComment(value).strip(); + return text + " "; + }).collect(Collectors.joining("")); + } + + // =========== 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) { return numstr.startsWith("-"); } + /** + * Check whether Altlr captured CKGENERAL_NUM is a hex number. + * @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"); + } + + /** + * 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) { + return canUnsigned ? "uint32_t" : "int32_t"; + } + + // =========== Parts =========== + enum CKParts { CK2, VxMath } @@ -58,31 +125,23 @@ public class CKCommonHelper { } } - /** - * 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) { - return canUnsigned ? "uint32_t" : "int32_t"; - } - // =========== File Operations =========== - + public static class InputFilePair { public CharStream mAntlrStream; public FileInputStream mUnderlyingStream; } + 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; } - + /** * Get output file for writing. + * * @param filename The name of file opening. * @return An OutputStreamWriter. * @throws Exception diff --git a/CodeGen/DefinesWalker.java b/CodeGen/DefinesWalker.java new file mode 100644 index 0000000..1d9da94 --- /dev/null +++ b/CodeGen/DefinesWalker.java @@ -0,0 +1,28 @@ + +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.tree.*; + +/** + * The generic walker for collecting defines as a enum. + */ +public class DefinesWalker extends CKDefinesParserBaseListener { + + @Override + public void enterProg(CKDefinesParser.ProgContext ctx) { + // TODO Auto-generated method stub + super.enterProg(ctx); + } + + @Override + public void exitProg(CKDefinesParser.ProgContext ctx) { + // TODO Auto-generated method stub + super.exitProg(ctx); + } + + @Override + public void exitDefinePair(CKDefinesParser.DefinePairContext ctx) { + // TODO Auto-generated method stub + super.exitDefinePair(ctx); + } + +} diff --git a/CodeGen/EnumsHelper.java b/CodeGen/EnumsHelper.java new file mode 100644 index 0000000..34ce548 --- /dev/null +++ b/CodeGen/EnumsHelper.java @@ -0,0 +1,49 @@ +import java.util.Vector; + +public class EnumsHelper { + /** + * The struct to describe the entry of an enum. + */ + public static class EnumEntry_t { + public EnumEntry_t() { + mEntryName = null; + mEntryValue = null; + mEntryComment = null; + } + + public String mEntryName; ///< The name of this entry. Can not be null. + public String mEntryValue; ///< The value of this entry. null if this entry do not have explicit value. + public String mEntryComment; ///< The comment of this entry. null if no comment. + } + + /** + * The struct to describe an enum. + */ + public static class Enum_t { + public Enum_t() { + mEnumName = null; + mEnumComment = null; + mCanUnsigned = true; + mUseFlags = false; + mEntries = new Vector(); + } + + public String mEnumName; ///< The name of this enum. Can not be null. + public String mEnumComment; ///< The comment of this enum. null if no comment. + public boolean mCanUnsigned; ///< true if this enum can use unsigned integer as its underlaying type. + public boolean mUseFlags; ///< true if this enum will have flags feature (supporting OR, AND, operators). + public Vector mEntries; ///< The list to store entries of this enum. + } + + /** + * The struct to describe a collection of enums. + */ + public static class EnumCollection_t { + public EnumCollection_t() { + mEnums = new Vector(); + } + + public Vector mEnums; ///< The list to store enums. + } + +} diff --git a/CodeGen/EnumsWalker.java b/CodeGen/EnumsWalker.java new file mode 100644 index 0000000..48c5909 --- /dev/null +++ b/CodeGen/EnumsWalker.java @@ -0,0 +1,131 @@ +import java.util.List; +import java.util.stream.Collectors; + +import org.antlr.v4.runtime.*; +import org.antlr.v4.runtime.tree.*; + +/** + * The generic walker for collecting multiple enums. + */ +public class EnumsWalker extends CKEnumsParserBaseListener { + public EnumsWalker(BufferedTokenStream tokenStream) { + mTokenStream = tokenStream; + mCommentsFinder = new CommentsFinder(tokenStream); + mResult = null; + + mCurrentProg = null; + mCurrentEnum = null; + mCurrentEntry = null; + } + + public EnumsHelper.EnumCollection_t getEnums() { + return mResult; + } + + private String getEnumComment(Token enumHead) { + return CommonHelper + .cutComment(CommonHelper.getPreChannelToken(mTokenStream, enumHead, CKGeneralLexer.COMMENTS)); + } + + private BufferedTokenStream mTokenStream; + private CommentsFinder mCommentsFinder; + private EnumsHelper.EnumCollection_t mResult; + + private EnumsHelper.EnumCollection_t mCurrentProg; + private EnumsHelper.Enum_t mCurrentEnum; + private EnumsHelper.EnumEntry_t mCurrentEntry; + + @Override + public void enterProg(CKEnumsParser.ProgContext ctx) { + mCurrentProg = new EnumsHelper.EnumCollection_t(); + } + + @Override + public void exitProg(CKEnumsParser.ProgContext ctx) { + mResult = mCurrentProg; + mCurrentProg = null; + } + + @Override + public void enterEnumBody(CKEnumsParser.EnumBodyContext ctx) { + mCurrentEnum = new EnumsHelper.Enum_t(); + } + + @Override + public void exitEnumBody(CKEnumsParser.EnumBodyContext ctx) { + // get enum comment + mCurrentEnum.mEnumComment = getEnumComment(ctx.getStart()); + // get the last name (for typedef case) + List allNames = ctx.CKGENERAL_ID(); + mCurrentEnum.mEnumName = allNames.get(allNames.size() - 1).getText(); + + mCurrentProg.mEnums.add(mCurrentEnum); + mCurrentEnum = null; + } + + @Override + public void enterEntryPair(CKEnumsParser.EntryPairContext ctx) { + mCurrentEntry = new EnumsHelper.EnumEntry_t(); + } + + @Override + public void exitEntryPair(CKEnumsParser.EntryPairContext ctx) { + // get entry comment + mCurrentEntry.mEntryComment = mCommentsFinder.getComment(ctx.getStart(), ctx.getStop()); + // get entry name + mCurrentEntry.mEntryName = ctx.CKGENERAL_ID().getText(); + + mCurrentEnum.mEntries.add(mCurrentEntry); + mCurrentEntry = null; + } + + @Override + public void exitEntryDirectValue(CKEnumsParser.EntryDirectValueContext ctx) { + // get all numbers + List nums = ctx.CKGENERAL_NUM(); + + switch (nums.size()) { + case 1: { + // set value + TerminalNode node = nums.get(0); + mCurrentEntry.mEntryValue = node.getText(); + + // check whether this enum can be unsigned + if (CommonHelper.isNegativeNumber(node.getText())) { + mCurrentEnum.mCanUnsigned = false; + } + // if the number is in hex form, this enum MIGHT have flags feature + if (CommonHelper.isHexNumber(node.getText())) { + mCurrentEnum.mUseFlags = true; + } + + break; + } + case 2: { + // set value + TerminalNode num = nums.get(0), offset = nums.get(1); + mCurrentEntry.mEntryValue = String.format("{} << {}", num.getText(), offset.getText()); + + // << operator appears. this enum must have flags feature + mCurrentEnum.mUseFlags = true; + + break; + } + default: + throw new IllegalArgumentException("Unexpected value: " + nums.size()); + } + + } + + @Override + public void exitEntryRelativeValue(CKEnumsParser.EntryRelativeValueContext ctx) { + // get all identifiers and join them + mCurrentEntry.mEntryValue = ctx.CKGENERAL_ID().stream().map(value -> value.getText()) + .collect(Collectors.joining(" | ")); + + // | operator appears. this enum must have flags feature + mCurrentEnum.mUseFlags = true; + + } + +} \ No newline at end of file diff --git a/CodeGen/EnumsWriter.java b/CodeGen/EnumsWriter.java new file mode 100644 index 0000000..d39a1a1 --- /dev/null +++ b/CodeGen/EnumsWriter.java @@ -0,0 +1,101 @@ +import java.io.OutputStreamWriter; + +/** + * Generic Enum Writer + */ +public class EnumsWriter { + private static void writeEnum(IndentHelper indent, EnumsHelper.EnumCollection_t prog) throws Exception { + for (EnumsHelper.Enum_t enum_t : prog.mEnums) { + // write enum comment + indent.briefComment(enum_t.mEnumComment); + + // write enum start + indent.printf("enum class %s : %s {", enum_t.mEnumName, + CommonHelper.getEnumUnderlyingType(enum_t.mCanUnsigned)); + indent.inc(); + + // write enum entries + for (EnumsHelper.EnumEntry_t enumEntry_t : enum_t.mEntries) { + // write entry self + if (enumEntry_t.mEntryValue == null) { + indent.printf("%s,", enumEntry_t.mEntryName); + } else { + indent.printf("%s = %s,", enumEntry_t.mEntryName, enumEntry_t.mEntryValue); + } + + // write entry comment after member + indent.afterMemberComment(enumEntry_t.mEntryComment); + } + + // write enum tail + indent.dec(); + indent.puts("};"); + } + } + + public static void writeEnums(OutputStreamWriter writer, EnumsHelper.EnumCollection_t ck2_prog, + EnumsHelper.EnumCollection_t vxmath_prog) throws Exception { + IndentHelper indent = new IndentHelper(writer); + indent.puts("#pragma once"); + indent.puts("#include "); + + indent.puts("namespace LibCmo::CK2 {"); + indent.inc(); + writeEnum(indent, ck2_prog); + indent.dec(); + indent.puts("}"); + + indent.puts("namespace LibCmo::VxMath {"); + indent.inc(); + writeEnum(indent, vxmath_prog); + indent.dec(); + indent.puts("}"); + } + + private static void writeAccessibleValue(IndentHelper indent, CommonHelper.CKParts parts, + EnumsHelper.EnumCollection_t prog) throws Exception { + for (EnumsHelper.Enum_t enum_t : prog.mEnums) { + // write enum desc header + indent.printf("const EnumNameofArray {} {", CommonHelper.getCKPartsNamespace(parts), + enum_t.mEnumName, enum_t.mEnumName); + indent.inc(); + + // write enum desc entries + for (EnumsHelper.EnumEntry_t enumEntry_t : enum_t.mEntries) { + indent.printf("{ LibCmo::%s::%s::%s, \"%s\" },", parts, enum_t.mEnumName, enumEntry_t.mEntryName, + enumEntry_t.mEntryName); + } + + // write enum tail + indent.dec(); + indent.puts("};"); + } + } + + public static void writeAccessibleValues(OutputStreamWriter writer, EnumsHelper.EnumCollection_t ck2_prog, + EnumsHelper.EnumCollection_t vxmath_prog) throws Exception { + IndentHelper indent = new IndentHelper(writer); + indent.puts("#pragma once"); + indent.puts("#include \"CKEnums.hpp\""); + indent.puts("#include "); + indent.puts("#include "); + indent.puts("#include "); + indent.puts("namespace Unvirt::AccessibleValue::EnumDesc {"); + indent.inc(); + + indent.puts("namespace CK2 {"); + indent.inc(); + writeAccessibleValue(indent, CommonHelper.CKParts.CK2, ck2_prog); + indent.dec(); + indent.puts("}"); + + indent.puts("namespace VxMath {"); + indent.inc(); + writeAccessibleValue(indent, CommonHelper.CKParts.VxMath, vxmath_prog); + indent.dec(); + indent.puts("}"); + + indent.dec(); + indent.puts("}"); + } +} diff --git a/CodeGen/ErrorsWriter.java b/CodeGen/ErrorsWriter.java new file mode 100644 index 0000000..4bd4d52 --- /dev/null +++ b/CodeGen/ErrorsWriter.java @@ -0,0 +1,7 @@ + +/** + * The accessible values writer of CKERROR + */ +public class ErrorsWriter { + +} diff --git a/CodeGen/CKIndentHelper.java b/CodeGen/IndentHelper.java similarity index 61% rename from CodeGen/CKIndentHelper.java rename to CodeGen/IndentHelper.java index 53deaed..c28a756 100644 --- a/CodeGen/CKIndentHelper.java +++ b/CodeGen/IndentHelper.java @@ -1,7 +1,7 @@ import java.io.OutputStreamWriter; -public class CKIndentHelper { - public CKIndentHelper(OutputStreamWriter writer) { +public class IndentHelper { + public IndentHelper(OutputStreamWriter writer) { mIndent = 0; mWriter = writer; } @@ -23,27 +23,29 @@ public class CKIndentHelper { 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; + + public void briefComment(String comment) throws Exception { + if (comment == null) + return; puts("/**"); - puts(fmt); + puts(comment); puts(" */"); } - - public void afterMemberComment(String fmt) throws Exception { - if (fmt == null) return; - mWriter.write(String.format("\t/**< %s */", CKCommonHelper.removeEol(fmt))); + + public void afterMemberComment(String comment) throws Exception { + if (comment == null) + return; + mWriter.write(String.format("\t/**< %s */", CommonHelper.removeEol(comment))); } } diff --git a/CodeGen/README.md b/CodeGen/README.md index 5a3be39..f607b85 100644 --- a/CodeGen/README.md +++ b/CodeGen/README.md @@ -4,10 +4,9 @@ A helper program to generate some definations. ``` antlr4 CKGeneralLexer.g4 -antlr4 CKEnumParser.g4 -antlr4 CKErrorParser.g4 -antlr4 CKClassidParser.g4 +antlr4 CKEnumsParser.g4 +antlr4 CKDefinesParser.g4 -javac CK*.java -java CKMainGen +javac *.java +java CKMain ``` diff --git a/CodeGen/dest/.gitkeep b/CodeGen/dest/.gitkeep deleted file mode 100644 index e69de29..0000000