From c1aac0beda0261462d4467d8fc61c7bfcc9b6d83 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Thu, 17 Aug 2023 15:48:30 +0800 Subject: [PATCH] try use new way to generate code --- .gitignore | 11 +++- CodeGen/CKClassidParser.g4 | 6 +++ CodeGen/CKERROR.py | 34 ------------- CodeGen/CKEnumParser.g4 | 14 +++++ CodeGen/CKErrorParser.g4 | 6 +++ CodeGen/CKGeneralLexer.g4 | 26 ++++++++++ CodeGen/CKMISC.py | 102 ------------------------------------- CodeGen/CKMainGen.java | 1 + CodeGen/CK_CLASSID.py | 76 --------------------------- CodeGen/README.md | 13 +++++ 10 files changed, 76 insertions(+), 213 deletions(-) create mode 100644 CodeGen/CKClassidParser.g4 delete mode 100644 CodeGen/CKERROR.py create mode 100644 CodeGen/CKEnumParser.g4 create mode 100644 CodeGen/CKErrorParser.g4 create mode 100644 CodeGen/CKGeneralLexer.g4 delete mode 100644 CodeGen/CKMISC.py create mode 100644 CodeGen/CKMainGen.java delete mode 100644 CodeGen/CK_CLASSID.py create mode 100644 CodeGen/README.md diff --git a/.gitignore b/.gitignore index c91861f..3187246 100644 --- a/.gitignore +++ b/.gitignore @@ -3,7 +3,6 @@ *.cmo *.nms *.vmo -CodeGen/dest/*.txt PyCmoOld/ out/ @@ -11,6 +10,16 @@ temp/ .vscode/ +## Special Treat of CodeGen +CodeGen.old/ +CodeGen/dest/*.txt + +CodeGen/CKGeneralLexer*.* +CodeGen/CKEnumParser*.* +CodeGen/CKErrorParser*.* +CodeGen/CKClassidParser*.* +!CodeGen/*.g4 + ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. ## diff --git a/CodeGen/CKClassidParser.g4 b/CodeGen/CKClassidParser.g4 new file mode 100644 index 0000000..dac8744 --- /dev/null +++ b/CodeGen/CKClassidParser.g4 @@ -0,0 +1,6 @@ +parser grammar CKClassidParser; +options { tokenVocab = CKGeneralLexer; } + +prog: definePair+ ; + +definePair: CKGENERAL_DEFINE CKGENERAL_ID CKGENERAL_NUM ; diff --git a/CodeGen/CKERROR.py b/CodeGen/CKERROR.py deleted file mode 100644 index b90546a..0000000 --- a/CodeGen/CKERROR.py +++ /dev/null @@ -1,34 +0,0 @@ -full_error = [] -annotation = '' -with open('src/CKERROR.txt', 'r', encoding='utf-8') as fr: - while True: - ln = fr.readline() - if ln == '': - break - ln.strip() - if ln == '': - continue - - if ln.startswith('#define'): - sp = ln[len('#define'):].strip().split(' ') - # name, value, description - full_error.append((sp[0], sp[-1], annotation)) - annotation = '' - elif ln.startswith('//'): - annotation = ln[len('//'):].strip() - - fr.close() - -with open('dest/CKERROR.txt', 'w', encoding='utf-8') as fw: - for item in full_error: - fw.write('{{ LibCmo::CKERROR::{}, {{"{}", "{}"}} }},\n'.format( - item[0], - item[0], - item[-1]) - ) - - fw.write('\n') - - for item in full_error: - fw.write(f'{item[0]} = {item[1]},\n') - fw.close() diff --git a/CodeGen/CKEnumParser.g4 b/CodeGen/CKEnumParser.g4 new file mode 100644 index 0000000..a792e54 --- /dev/null +++ b/CodeGen/CKEnumParser.g4 @@ -0,0 +1,14 @@ +parser grammar CKEnumParser; +options { tokenVocab = CKGeneralLexer; } + +prog: enumBody+ ; + +enumBody: CKGENERAL_TYPEDEF? CKGENERAL_ENUM CKGENERAL_ID CKGENERAL_LBRACKET +entryPair (CKGENERAL_COMMA entryPair)* +CKGENERAL_RBRACKET CKGENERAL_ID? CKGENERAL_SEMICOLON ; + +entryPair: CKGENERAL_ID (CKGENERAL_EQUAL entryValue)? ; + +entryValue: CKGENERAL_NUM (CKGENERAL_LSHIFT CKGENERAL_NUM)* # entryDirectValue +| CKGENERAL_ID (CKGENERAL_OR CKGENERAL_ID)* # entryRelativeValue +; \ No newline at end of file diff --git a/CodeGen/CKErrorParser.g4 b/CodeGen/CKErrorParser.g4 new file mode 100644 index 0000000..6cc9aa7 --- /dev/null +++ b/CodeGen/CKErrorParser.g4 @@ -0,0 +1,6 @@ +parser grammar CKErrorParser; +options { tokenVocab = CKGeneralLexer; } + +prog: definePair+ ; + +definePair: CKGENERAL_DEFINE CKGENERAL_ID CKGENERAL_NUM ; diff --git a/CodeGen/CKGeneralLexer.g4 b/CodeGen/CKGeneralLexer.g4 new file mode 100644 index 0000000..6ce1e37 --- /dev/null +++ b/CodeGen/CKGeneralLexer.g4 @@ -0,0 +1,26 @@ +lexer grammar CKGeneralLexer; + +channels { COMMENTS, WHITESPACE } + +// keywords +CKGENERAL_TYPEDEF: 'typedef' ; +CKGENERAL_DEFINE: '#define' ; +CKGENERAL_ENUM: 'enum' ; +// symbols +CKGENERAL_LBRACKET: '{' ; +CKGENERAL_RBRACKET: '}' ; +CKGENERAL_EQUAL: '='; +CKGENERAL_SEMICOLON: ';' ; +CKGENERAL_LSHIFT: '<<' ; +CKGENERAL_OR: '|' ; +CKGENERAL_COMMA: ',' ; + +// identifider and number +CKGENERAL_ID: [_a-zA-Z][_a-zA-Z0-9]* ; +CKGENERAL_NUM: '-'? ('0' [xX])? [0-9a-fA-F]+ [uUlL]* ; + +// comments +CKGENERAL_LINE_COMMENT: '//' ~[\r\n]* -> channel(COMMENTS); +CKGENERAL_BLOCK_COMMENT: '/*' .*? '*/' -> channel(COMMENTS); +// whitespace +CKGENERAL_WS: [ \t\r\n]+ -> channel(WHITESPACE); diff --git a/CodeGen/CKMISC.py b/CodeGen/CKMISC.py deleted file mode 100644 index da108ba..0000000 --- a/CodeGen/CKMISC.py +++ /dev/null @@ -1,102 +0,0 @@ -def RemoveAnnotation(strl: str) -> str: - idx = strl.find("//") - if idx == -1: return strl.strip() - - return strl[:idx].strip() - -def Underline2Camel(orig: str) -> str: - return ''.join(map( - lambda strl: strl[0].upper() + strl[1:].lower(), - orig.split('_') - )) - -class EnumEntry(): - def __init__(self, name: str, val: str): - self.name: str = name - self.val: str = val - def __repr__(self) -> str: - return f'<{self.name}: {self.val}>' - - -class EnumBody(): - def __init__(self, name: str, is_flag: bool): - self.name: str = name - self.camel_name: str = Underline2Camel(name) - self.is_flag: bool = is_flag - self.entries: list[EnumEntry] = [] - def __repr__(self) -> str: - return self.entries.__repr__() - -full_enum: list[EnumBody] = [] -current_body: EnumEntry = None -with open('src/CKMISC.txt', 'r', encoding='utf-8') as fr: - while True: - ln = fr.readline() - if ln == '': - break - ln = RemoveAnnotation(ln) - if ln == '': - continue - - if ln.startswith('enum'): - ln = ln[len('enum'):].strip() - - is_flag = ln[0] == '!' - name = ln[1:] if is_flag else ln - - if current_body: - full_enum.append(current_body) - current_body = EnumBody(name, is_flag) - - else: - sp = ln.replace(',', '').split('=') - if len(sp) == 1: - entry = EnumEntry(sp[0].strip(), '') - else: - entry = EnumEntry(sp[0].strip(), sp[-1].strip()) - current_body.entries.append(entry) - - fr.close() -if current_body: - full_enum.append(current_body) - -with open('dest/CKMISC.txt', 'w', encoding='utf-8') as fw: - # write define - for item in full_enum: - fw.write('enum class {} : int32_t {{\n'.format(item.name)) - - fw.write(',\n'.join(map( - lambda x: x.name if x.val == '' else (x.name + ' = ' + x.val), - item.entries - ))) - fw.write('\n};\n') - - fw.write('\n') - - # write decl - fw.write('namespace EnumDesc {\n') - for item in full_enum: - fw.write('extern const EnumDescPairArray {};\n'.format( - item.name, item.name - )) - fw.write('}') - - fw.write('\n') - - # write vector - fw.write('namespace EnumDesc {\n') - for item in full_enum: - fw.write('const EnumDescPairArray {} {{\n'.format( - item.name, item.name - )) - fw.write(',\n'.join(map( - lambda x: '{{ LibCmo::{}::{}, "{}" }}'.format(item.name, x.name, x.name), - item.entries - ))) - fw.write('\n};\n') - fw.write('}') - - fw.write('\n') - - - fw.close() diff --git a/CodeGen/CKMainGen.java b/CodeGen/CKMainGen.java new file mode 100644 index 0000000..dd9d241 --- /dev/null +++ b/CodeGen/CKMainGen.java @@ -0,0 +1 @@ +// todo: WIP \ No newline at end of file diff --git a/CodeGen/CK_CLASSID.py b/CodeGen/CK_CLASSID.py deleted file mode 100644 index d3cb70b..0000000 --- a/CodeGen/CK_CLASSID.py +++ /dev/null @@ -1,76 +0,0 @@ -class CKClass(): - def __init__(self, name: str, value: int): - self.name: str = name - self.value: int = value - self.parents: tuple[str] = None - -def GetLevel(strl: str): - counter = 0 - for c in strl: - if c == '\t': - counter += 1 - else: - break - return counter - -def BuildClass(strl: str) -> CKClass: - strl = strl.replace('#define', '\t').replace(' ', '\t').strip() - sp = strl.split('\t') - return CKClass(sp[0], sp[-1]) - -def GetParents(ls: list[CKClass]) -> tuple[str]: - return tuple( - map(lambda x: x.name, ls) - ) - -full_classes = [] -with open('src/CK_CLASSID.txt', 'r', encoding='utf-8') as fr: - level = 0 - node_stack: list[CKClass] = [None] - - while True: - ln = fr.readline() - if ln == '': - break - if ln.strip() == '': - continue - ln = ln.strip('\n') - - new_item = BuildClass(ln) - full_classes.append(new_item) - - this_level = GetLevel(ln) - if this_level > level: - # level up - level += 1 - node_stack.append(new_item) - new_item.parents = GetParents(node_stack) - elif this_level == level: - node_stack.pop() - node_stack.append(new_item) - new_item.parents = GetParents(node_stack) - elif this_level < level: - for i in range(level - this_level + 1): - node_stack.pop() - level = this_level - - node_stack.append(new_item) - new_item.parents = GetParents(node_stack) - - - fr.close() - -with open('dest/CK_CLASSID.txt', 'w', encoding='utf-8') as fw: - for item in full_classes: - fw.write('{{ LibCmo::CK_CLASSID::{}, {{{}}} }},\n'.format( - item.parents[-1], - ', '.join( - map(lambda x: '"' + x + '"', item.parents) - ) - )) - - fw.write('\n') - - for item in full_classes: - fw.write(f'{item.name} = {item.value},\n') - fw.close() diff --git a/CodeGen/README.md b/CodeGen/README.md new file mode 100644 index 0000000..5a3be39 --- /dev/null +++ b/CodeGen/README.md @@ -0,0 +1,13 @@ +# Code Gen + +A helper program to generate some definations. + +``` +antlr4 CKGeneralLexer.g4 +antlr4 CKEnumParser.g4 +antlr4 CKErrorParser.g4 +antlr4 CKClassidParser.g4 + +javac CK*.java +java CKMainGen +```