2023-08-20 12:13:40 +08:00
|
|
|
|
2023-08-20 16:10:22 +08:00
|
|
|
import java.util.Stack;
|
|
|
|
|
2023-08-20 12:13:40 +08:00
|
|
|
import org.antlr.v4.runtime.*;
|
|
|
|
import org.antlr.v4.runtime.tree.*;
|
|
|
|
|
|
|
|
/**
|
2023-08-20 16:10:22 +08:00
|
|
|
* The specialized walker for collecting CK_CLASSID and its inherit
|
|
|
|
* relationship.
|
2023-08-20 12:13:40 +08:00
|
|
|
*/
|
|
|
|
public class ClassidWalker extends CKDefinesParserBaseListener {
|
|
|
|
|
2023-08-20 16:10:22 +08:00
|
|
|
public ClassidWalker(BufferedTokenStream tokenStream) {
|
|
|
|
mTokenStream = tokenStream;
|
|
|
|
mResult = null;
|
|
|
|
|
|
|
|
mLevelStack = null;
|
|
|
|
mCurrentEnum = null;
|
|
|
|
mCurrentEntry = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public EnumsHelper.Enum_t getEnum() {
|
|
|
|
return mResult;
|
|
|
|
}
|
|
|
|
|
|
|
|
private int getClassidLevel(Token defineHead) {
|
|
|
|
Token ws = CommonHelper.getPreChannelToken(mTokenStream, defineHead, CKGeneralLexer.WHITESPACE);
|
|
|
|
if (ws == null)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
// reverse finding how many tab used.
|
|
|
|
int counter = 0;
|
|
|
|
char[] wstxt = ws.getText().toCharArray();
|
|
|
|
for (int i = wstxt.length - 1; i >= 0; i--) {
|
|
|
|
if (wstxt[i] == '\t') {
|
|
|
|
counter++;
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return counter;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void safePop() {
|
|
|
|
if (mLevelStack.size() != 0)
|
|
|
|
mLevelStack.pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void safePopTimes(int times) {
|
|
|
|
for (int i = 0; i < times; i++) {
|
|
|
|
if (mLevelStack.size() != 0)
|
|
|
|
mLevelStack.pop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private BufferedTokenStream mTokenStream;
|
|
|
|
private EnumsHelper.Enum_t mResult;
|
|
|
|
|
|
|
|
private int mLevel;
|
|
|
|
private Stack<EnumsHelper.EnumEntryWithHierarchy_t> mLevelStack;
|
|
|
|
private EnumsHelper.Enum_t mCurrentEnum;
|
|
|
|
private EnumsHelper.EnumEntryWithHierarchy_t mCurrentEntry;
|
|
|
|
|
2023-08-20 12:13:40 +08:00
|
|
|
@Override
|
|
|
|
public void enterProg(CKDefinesParser.ProgContext ctx) {
|
2023-08-20 16:10:22 +08:00
|
|
|
mLevel = 0;
|
|
|
|
mLevelStack = new Stack<EnumsHelper.EnumEntryWithHierarchy_t>();
|
|
|
|
mCurrentEnum = new EnumsHelper.Enum_t();
|
2023-08-20 12:13:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void exitProg(CKDefinesParser.ProgContext ctx) {
|
2023-08-20 16:10:22 +08:00
|
|
|
mLevel = 0;
|
|
|
|
mLevelStack = null;
|
|
|
|
|
|
|
|
// classid is signed int and do not have flags feature.
|
|
|
|
mCurrentEnum.mCanUnsigned = false;
|
|
|
|
mCurrentEnum.mUseFlags = false;
|
|
|
|
mResult = mCurrentEnum;
|
|
|
|
mCurrentEnum = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void enterDefinePair(CKDefinesParser.DefinePairContext ctx) {
|
|
|
|
mCurrentEntry = new EnumsHelper.EnumEntryWithHierarchy_t();
|
2023-08-20 12:13:40 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public void exitDefinePair(CKDefinesParser.DefinePairContext ctx) {
|
2023-08-20 16:10:22 +08:00
|
|
|
// fill entry info
|
|
|
|
mCurrentEntry.mEntryName = ctx.CKGENERAL_ID(0).getText();
|
|
|
|
mCurrentEntry.mEntryValue = ctx.CKGENERAL_NUM().getText();
|
|
|
|
|
|
|
|
// fill entry level info
|
|
|
|
int this_level = getClassidLevel(ctx.getStart());
|
|
|
|
if (this_level > mLevel) {
|
|
|
|
// level up
|
|
|
|
mLevel++;
|
|
|
|
|
|
|
|
mLevelStack.push(mCurrentEntry);
|
|
|
|
mCurrentEntry.mHierarchy.addAll(mLevelStack);
|
|
|
|
} else if (this_level == mLevel) {
|
|
|
|
safePop();
|
|
|
|
mLevelStack.push(mCurrentEntry);
|
|
|
|
mCurrentEntry.mHierarchy.addAll(mLevelStack);
|
|
|
|
} else if (this_level < mLevel) {
|
|
|
|
// level down
|
|
|
|
safePopTimes(mLevel - this_level + 1);
|
|
|
|
mLevel = this_level;
|
|
|
|
|
|
|
|
mLevelStack.push(mCurrentEntry);
|
|
|
|
mCurrentEntry.mHierarchy.addAll(mLevelStack);
|
|
|
|
}
|
|
|
|
|
|
|
|
// move to list
|
|
|
|
mCurrentEnum.mEntries.add(mCurrentEntry);
|
|
|
|
mCurrentEntry = null;
|
2023-08-20 12:13:40 +08:00
|
|
|
}
|
2023-08-20 16:10:22 +08:00
|
|
|
|
2023-08-20 12:13:40 +08:00
|
|
|
}
|