62#define BEGINCONTEXT(ctx) { \
63 int prevState = YYSTATE; \
66 printf("parser.l line#%4d: pushed %s(%d) and started %s(%d) from input-line#%d\n", __LINE__, contextNameFromState(prevState), prevState, contextNameFromState(YYSTATE), YYSTATE, g.mLineNo); \
69#define ENDCONTEXT() { \
70 int prevState = YYSTATE; \
73 printf("parser.l line#%4d: ended %s(%d) and starting %s(%d) from input-line#%d\n", __LINE__, contextNameFromState(prevState), prevState, contextNameFromState(YYSTATE), YYSTATE, g.mLineNo); \
80 printf(
"parser.l line#%4d: returning token %d with value '%s' found @input-line#%d\n",
81 codelinenum, ret, yytext, srclinenum);
86static void Log(
int codelinenum,
int srclinenum)
90 printf(
"parser.l line#%4d and input line#%d\n",
91 codelinenum, srclinenum);
95#define RETURN(ret) return LogAndReturn(ret, __LINE__, g.mLineNo)
96#define LOG() Log(__LINE__, g.mLineNo)
97#define INCREMENT_INPUT_LINE_NUM() \
101 printf("parser.l line#%4d: Incrementing g.mLineNo, found @input-line#%d\n", __LINE__, g.mLineNo); \
109# define fileno _fileno
144 yyposn =
const_cast<char*
>(text);
169 const auto savedlen = yyleng;
170 const auto input = [&]() {
172 return yytext[yyleng-1];
175 while (isspace(c = input()))
180 for (c = input(); openBracket && (c != EOF); c = input())
207 const char openingBracket = (openingBracketType !=
'{') ?
'(' :
'{';
208 const char closingBracket = (openingBracket ==
'{') ?
'}' :
')';
211 assert(*start ==
'\0');
214 for (
auto p = start+1; p != end; ++p)
216 if (*p == openingBracket)
220 else if (*p == closingBracket)
CppToken makeCppToken(const char *sz, size_t len)
Since CppToken cannot have ctor (because it is intended to be used inside union).
@ DisableCommentTokenization
@ EnableCommentTokenization
@ ResetCommentTokenization
static void setOldYytext(const char *p)
static void Log(int codelinenum, int srclinenum)
static int LogAndReturn(int ret, int codelinenum, int srclinenum)
std::set< std::string > gMacroNames
static void startNewMacroDependentParsing()
std::set< std::string > gKnownApiDecorNames
#define INCREMENT_INPUT_LINE_NUM()
std::map< std::string, int > gDefinedNames
bool gParseFunctionBodyAsBlob
static void setBlobToken(TokenSetupFlag flag=TokenSetupFlag::None)
static void tokenizeBracketedContent(YYLessProc yylessfn)
static void setupToken(const char *text, size_t len, TokenSetupFlag flag=TokenSetupFlag::DisableCommentTokenization)
std::set< std::string > gIgnorableMacroNames
static void setCommentTokenizationState(TokenSetupFlag flag)
std::map< std::string, int > gRenamedKeywords
static bool codeSegmentDependsOnMacroDefinition()
std::function< void(int)> YYLessProc
std::set< std::string > gUndefinedNames
bool gParseEnumBodyAsBlob
const char * contextNameFromState(int ctx)
static void updateMacroDependence()
static const char * findMatchedClosingBracket(const char *start, char openingBracketType='(')
MacroDependentCodeEnablement macroDependentCodeEnablement
BracketDepthStack mBracketDepthStack
const char * mInputBuffer
CodeEnablementInfo currentCodeEnablementInfo
bool mTokenizeComment
Comments can appear anywhere in a C/C++ program and unfortunately not all coments can be preserved.
CodeEnablementInfoStack codeEnablementInfoStack
256%option never-interactive
258%option noyy_top_state
274WSNL " "|\r\n|\r|\n|\t
280ID [_a-zA-Z]+[_0-9a-zA-Z]*
282ID2 ({ID}"::"{WS}*)*{ID}
285NUM ([0-9]+((l|L|u|U)*|(\.[0-9]*)?))|\.[0-9]+|(0(b|B)[01']*)|(0(x|X)[0-9a-fA-F]*)|0(x|X)[0-9a-zA-Z]+
287DECNUMLIT (([0-9]+(\.[0-9]*)?)|([0-9]*(\.[0-9]+)))(f|F)?
290SL "\""([^"\\]|\\.)*\"
296CSP (({WS}*{ID}{WS}*,{WS}*)*{ID}{WS}*)*
299FTA ("const"|"final"|"override"|{ID})
301IgnorableTrailingContext {WS}*("//".*)?
306%x ctxFreeStandingBlockComment
307%x ctxSideBlockComment
308%x ctxBlockCommentInsideMacroDefn
347<ctxGeneral>^{WS}*{NL} {
352<ctxGeneral,ctxFreeStandingBlockComment,ctxSideBlockComment>{NL} {
357<ctxPreprocessor>{ID} {
363<ctxGeneral>"__declspec"{WS}*"("{WS}*{ID}{WS}*")" {
375<ctxGeneral>__stdcall {
387<ctxGeneral>"alignas"{WS}*"("{WS}*{ID}{WS}*")" {
393<ctxGeneral>"alignas"{WS}*"("{WS}*{NUM}{WS}*")" {
428<ctxGeneral>")"{WSNL}*({FTA}{WSNL}*)*{WSNL}*"{" {
const char * mExpectedBracePosition
bool mFunctionBodyWillBeEncountered
439<ctxGeneral>")"{WSNL}*":"/{WSNL}{ID2}("("|"{") {
bool mMemInitListWillBeEncountered
const char * mExpectedColonPosition
450<ctxGeneral>asm/{TS} {
456<ctxGeneral>goto/{TS} {
461<ctxGeneral>signed|unsigned/{TS} {
467<ctxGeneral>long{WS}+long{WS}+int|long{WS}+long|long{WS}+int|long|int|short{WS}+int|short/{TS} {
473<ctxGeneral>__int8|__int16|__int32|__int64|__int128/{TS} {
479<ctxGeneral>char/{TS} {
485<ctxGeneral>long{WS}+double|double/{TS} {
491<ctxGeneral>long{WS}+float|float/{TS} {
497<ctxGeneral>auto/{TS} {
503<ctxGeneral>typedef{TS}+ {
509<ctxGeneral>using{TS}+ {
515<ctxGeneral>class/{TS} {
521<ctxGeneral>namespace/{TS} {
527<ctxGeneral>struct/{TS} {
533<ctxGeneral>union/{TS} {
539<ctxGeneral>enum/{WS}+(class{WS}+)?{ID}?({WS}*":"{WS}*{ID})?{WSNL}*"{" {
bool mEnumBodyWillBeEncountered
547<ctxGeneral>enum/{TS} {
553<ctxGeneral>public/{WS}*":" {
559<ctxGeneral>public/{TS} {
565<ctxGeneral>protected/{WS}*":" {
571<ctxGeneral>protected/{TS} {
577<ctxGeneral>private/{WS}*":" {
583<ctxGeneral>private/{TS} {
589<ctxGeneral>template/{TS} {
595<ctxGeneral>typename/{TS} {
601<ctxGeneral>decltype/{TS} {
607<ctxGeneral>^{WS}*"/*" {
#define BEGINCONTEXT(ctx)
621<ctxFreeStandingBlockComment>[^*\n]*"*"+"/"/{WS}*{NL} {
627 RETURN(tknFreeStandingBlockComment);
630<ctxFreeStandingBlockComment>[^*\n]*"*"+"/" {
635<ctxSideBlockComment>[^*\n]*"*"+"/" {
648<ctxSideBlockComment,ctxFreeStandingBlockComment,ctxBlockCommentInsideMacroDefn>[^*\n]* {
651<ctxSideBlockComment,ctxFreeStandingBlockComment,ctxBlockCommentInsideMacroDefn>[^*\n]*\n {
655<ctxSideBlockComment,ctxFreeStandingBlockComment,ctxBlockCommentInsideMacroDefn>{WS}*"*"+[^*/\n]* {
658<ctxSideBlockComment,ctxFreeStandingBlockComment,ctxBlockCommentInsideMacroDefn>{WS}*"*"+[^*/\n]*\n {
662<ctxSideBlockComment,ctxFreeStandingBlockComment,ctxBlockCommentInsideMacroDefn>. {
670 RETURN(tknFreeStandingLineComment);
690<ctxPreprocessor>define/{WS} {
711<ctxDefine>{ID}\({CSP}\) {
DefineLooksLike mDefLooksLike
721<ctxDefine>{ID}\(.*"...".*\) {
790<ctxDefineDefn>{NUM} {
803<ctxDefineDefn>[^\t\r\n ] {
819<ctxDefineDefn>"//".*{NL} {
827<ctxDefineDefn>{WS}*"/*"[^\n]*"*/"{WS}*/{NL} {
831<ctxDefineDefn>{WS}*"/*" {
836<ctxBlockCommentInsideMacroDefn>{NL} {
847<ctxBlockCommentInsideMacroDefn>[^*\n]*"*"+"/" {
852<ctxBlockCommentInsideMacroDefn>.*"*/"/{WS}*"\\"{WS}*{NL} {
857<ctxBlockCommentInsideMacroDefn>.*"\\"{WS}*{NL} {
862<ctxPreprocessor>undef/{WS} {
868<ctxPreprocessor>include/{WS} {
876<ctxPreprocessor>import/{WS} {
903<ctxPreprocessor>if/{WS} {
int numHashIfInMacroDependentCode
Counting of # to keep track of when we need to consider the code outside of disabled segment.
916<ctxPreprocessor>ifdef/{WS} {
926<ctxPreprocessor>ifndef/{WS} {
936<ctxPreprocessor>else/{TS} {
942<ctxPreprocessor>elif/{WS} {
951<ctxPreprocessor>endif/{TS} {
964<ctxGeneral>^{WS}*#{WS}*if/{WS}+"0" {
973<ctxGeneral>^{WS}*"#"{WS}*"if"{WS}+{ID}{WS}*("//"|"/*")?{NL} {
976 std::string id(yyleng,
'\0');
977 sscanf(yytext,
" # if %[a-zA-Z0-9_]",
id.data());
978 id.resize(strlen(
id.data()));
980 if (!idVal.has_value()) {
std::optional< int > getIdValue(const std::string &id)
995<ctxGeneral>^{WS}*"#"{WS}*"if"{WS}+{ID}{WS}*">="{WS}*{NUM}{IgnorableTrailingContext}{NL} {
998 std::string id(yyleng,
'\0');
1000 sscanf(yytext,
" # if %[a-zA-Z0-9_] >= %d",
id.data(), &n);
1001 id.resize(strlen(
id.data()));
1003 if (!idVal.has_value()) {
1017<ctxGeneral>^{WS}*#{WS}*if{WS}+"!"{ID}{IgnorableTrailingContext}{NL} {
1020 std::string id(yyleng,
'\0');
1021 sscanf(yytext,
" # if ! %[a-zA-Z0-9_]",
id.data());
1022 id.resize(strlen(
id.data()));
1025 if (!idVal.has_value()) {
1040<ctxGeneral>^{WS}*#{WS}*ifdef{WS}+{ID}{IgnorableTrailingContext}{NL} {
1043 std::string id(yyleng,
'\0');
1044 sscanf(yytext,
" # ifdef %[a-zA-Z0-9_]",
id.data());
1045 id.resize(strlen(
id.data()));
MacroDefineInfo getMacroDefineInfo(const std::string &id)
1063<ctxGeneral>^{WS}*#{WS}*if{WS}+"defined("{WS}*{ID}{WS}*")"{IgnorableTrailingContext}{NL} {
1066 std::string id(yyleng,
'\0');
1067 sscanf(yytext,
" # if defined( %[a-zA-Z0-9_])",
id.data());
1068 id.resize(strlen(
id.data()));
1086<ctxGeneral>^{WS}*#{WS}*ifndef{WS}+{ID}{IgnorableTrailingContext}{NL} {
1089 std::string id(yyleng,
'\0');
1090 sscanf(yytext,
" # ifndef %[a-zA-Z0-9_]",
id.data());
1091 id.resize(strlen(
id.data()));
1109<ctxGeneral,ctxDisabledCode>^{WS}*#{WS}*else{TS} {
MacroDependentCodeEnablement invert(MacroDependentCodeEnablement enabledCodeDecision)
1131<ctxDisabledCode>{NL} {
1136<ctxDisabledCode>^{WS}*#{WS}*if {
1140<*>^{WS}*#{WS}*endif{IgnorableTrailingContext}{NL}* {
1153 if (YYSTATE == ctxDisabledCode) {
bool parseDisabledCodeAsBlob
1165<ctxPreprocessor>pragma/{WS} {
1174<ctxPreProBody>.*\\{WS}*{NL} {
1183<ctxPreProBody>{NL} {
1191<ctxPreprocessor>{NL} {
1198<ctxPreprocessor>error{WS}[^\n]*{NL} {
1206<ctxPreprocessor>warning{WS}[^\n]*{NL} {
1220<ctxGeneral>const/{TS} {
1226<ctxGeneral>constexpr/{TS} {
1232<ctxGeneral>static/{TS} {
1238<ctxGeneral>inline/{TS} {
1244<ctxGeneral>virtual/{TS} {
1250<ctxGeneral>override/{TS} {
1256<ctxGeneral>final/{TS} {
1262<ctxGeneral>noexcept/{TS} {
1268<ctxGeneral>extern/{TS} {
1274<ctxGeneral>explicit/{TS} {
1280<ctxGeneral>friend/{TS} {
1286<ctxGeneral>"extern"{WS}+"\"C\"" {
1292<ctxGeneral>volatile/{TS} {
1298<ctxGeneral>mutable/{TS} {
1304<ctxGeneral>new/{TS} {
1310<ctxGeneral>delete/{TS} {
1316<ctxGeneral>default/{TS} {
1322<ctxGeneral>return/{TS} {
1328<ctxGeneral>if/{TS} {
1334<ctxGeneral>else/{TS} {
1340<ctxGeneral>for/{TS} {
1346<ctxGeneral>do/{TS} {
1352<ctxGeneral>while/{TS} {
1358<ctxGeneral>switch/{TS} {
1364<ctxGeneral>case/{TS} {
1370<ctxGeneral>const_cast/{TS} {
1376<ctxGeneral>static_cast/{TS} {
1382<ctxGeneral>dynamic_cast/{TS} {
1388<ctxGeneral>reinterpret_cast/{TS} {
1391 RETURN(tknReinterpretCast);
1394<ctxGeneral>try/{TS} {
1400<ctxGeneral>catch/{TS} {
1406<ctxGeneral>throw/{TS} {
1412<ctxGeneral>sizeof/{TS} {
1418<ctxGeneral>operator/{TS} {
1424<ctxGeneral>operator{WSNL}*/">>" {
const char * mExpectedRShiftOperator
1431<ctxGeneral>void/{TS} {
1588<ctxGeneral,ctxDefine>{NUM} {
1594<ctxGeneral>{DECNUMLIT}((e|E)[+-]?{DECNUMLIT})? {
1600<ctxGeneral,ctxInclude>{SL} {
1606<ctxGeneral>(L)?{SL} {
1612<ctxGeneral>(L)?{CL} {
1618<ctxGeneral>"("|"[" {
1625<ctxGeneral>")"|"]" {
1672<ctxEnumBody>[^\}\n]* {
1682<ctxEnumBody>{NL}/"}" {
1689<ctxEnumBody>([^\}\n]*|^{WS}*)/"}" {
1695<ctxFunctionBody>"{" {
int mNestedCurlyBracketDepth
It is currently used for parsing function body as a blob.
1700<ctxFunctionBody>"}" {
1714<ctxFunctionBody>{NL}/"}" {
1724<ctxFunctionBody>([^{}\n]|{WS}*)/"}" {
1733<ctxFunctionBody>{NL} {
1756<ctxMemInitList>({ID2}{WSNL}*)/"(" {
const char * mPossibleFuncImplStartBracePosition
1762<ctxMemInitList>({ID2}{WSNL}*)/"{" {
1768<ctxMemInitList>^{WS}*"#"{WS}*"if"(.*)/{TS} {
1772<ctxMemInitList>^{WS}*"#"{WS}*"endif"/{TS} {
1776<ctxMemInitList>({NL}) {
1781<ctxMemInitList>(.) {
1783 if (yytext[0] ==
'\n')
1787 else if(yytext[0] ==
'{')
1816<ctxGeneral>\)|\]|#|=|\*|\+|-|\.|\/|\~|%|\^|&|\||\?|\! {
1849<*>__attribute__{WS}*\(\(.*\)\) {
1853<ctxGeneral>^"@interface" {
1857<ctxObjectiveC>{NL} {
1865<ctxObjectiveC>^"@end" {
1877 return "ctxGeneral";
1878 case ctxFreeStandingBlockComment :
1879 return "ctxFreeStandingBlockComment";
1880 case ctxSideBlockComment :
1881 return "ctxSideBlockComment";
1882 case ctxBlockCommentInsideMacroDefn :
1883 return "ctxBlockCommentInsideMacroDefn";
1884 case ctxPreprocessor :
1885 return "ctxPreprocessor";
1887 return "ctxInclude";
1890 case ctxDefineDefn :
1891 return "ctxDefineDefn";
1892 case ctxPreProBody :
1893 return "ctxPreProBody";
1895 return "ctxEnumBody";
1896 case ctxFunctionBody :
1897 return "ctxFunctionBody";
1898 case ctxDisabledCode :
1899 return "ctxDisabledCode";
1900 case ctxMemInitList :
1901 return "ctxMemInitList";
1904 return "UNKNOWNCONTEXT";
static YY_BUFFER_STATE gParseBuffer
void setupScanBuffer(char *buf, size_t bufsize)