Match compiler: Inline generated pattern match code for Token::findmatch

Verified the output in build/ stayed the same
if Token::findmatch support is disabled.
This commit is contained in:
Thomas Jarosch 2013-01-04 03:09:41 +01:00
parent c9fb7f529d
commit f9c752667e
1 changed files with 34 additions and 31 deletions

View File

@ -43,12 +43,21 @@ def compileCmd(tok, matchStrs):
return '(tok->str()==' + insertMatchStr(matchStrs, tok) + ')/* ' + tok + ' */' return '(tok->str()==' + insertMatchStr(matchStrs, tok) + ')/* ' + tok + ' */'
def compilePattern(matchStrs, pattern, nr, varid): def compilePattern(matchStrs, pattern, nr, varid, isFindMatch=False):
arg2 = '' ret = ''
if varid: returnStatement = ''
arg2 = ', const unsigned int varid'
ret = '// ' + pattern + '\n' if isFindMatch:
ret += 'static bool match' + str(nr) + '(const Token *tok'+arg2+') {\n' ret = '\nconst Token *tok = start_tok;\n'
returnStatement = 'continue;\n';
else:
arg2 = ''
if varid:
arg2 = ', const unsigned int varid'
ret = '// ' + pattern + '\n'
ret += 'static bool match' + str(nr) + '(const Token *tok'+arg2+') {\n'
returnStatement = 'return false;\n';
tokens = pattern.split(' ') tokens = pattern.split(' ')
gotoNextToken = '' gotoNextToken = ''
@ -68,7 +77,7 @@ def compilePattern(matchStrs, pattern, nr, varid):
# [abc] # [abc]
if (len(tok) > 2) and (tok[0] == '[') and (tok[-1] == ']'): if (len(tok) > 2) and (tok[0] == '[') and (tok[-1] == ']'):
ret += ' if (!tok || tok->str().size()!=1U || !strchr("'+tok[1:-1]+'", tok->str()[0]))\n' ret += ' if (!tok || tok->str().size()!=1U || !strchr("'+tok[1:-1]+'", tok->str()[0]))\n'
ret += ' return false;\n' ret += ' ' + returnStatement
# a|b|c # a|b|c
elif tok.find('|') > 0: elif tok.find('|') > 0:
@ -98,45 +107,43 @@ def compilePattern(matchStrs, pattern, nr, varid):
gotoNextToken = '' gotoNextToken = ''
else: else:
ret += '))\n' ret += '))\n'
ret += ' return false;\n' ret += ' ' + returnStatement
# !!a # !!a
elif tok[0:2]=="!!": elif tok[0:2]=="!!":
ret += ' if (tok && tok->str() == ' + insertMatchStr(matchStrs, tok[2:]) + ')/* ' + tok[2:] + ' */\n' ret += ' if (tok && tok->str() == ' + insertMatchStr(matchStrs, tok[2:]) + ')/* ' + tok[2:] + ' */\n'
ret += ' return false;\n' ret += ' ' + returnStatement
gotoNextToken = ' tok = tok ? tok->next() : NULL;\n' gotoNextToken = ' tok = tok ? tok->next() : NULL;\n'
else: else:
ret += ' if (!tok || !' + compileCmd(tok, matchStrs) + ')\n' ret += ' if (!tok || !' + compileCmd(tok, matchStrs) + ')\n'
ret += ' return false;\n' ret += ' ' + returnStatement
ret += ' return true;\n}\n'
if isFindMatch:
ret += ' return start_tok;\n'
else:
ret += ' return true;\n'
ret += '}\n'
return ret return ret
def compileFindPattern(matchFunctions, matchStrs, pattern, findmatchnr, matchnr, endToken, varId): def compileFindPattern(matchFunctions, matchStrs, pattern, findmatchnr, endToken, varId):
more_args = '' more_args = ''
endCondition = '' endCondition = ''
if endToken: if endToken:
more_args += ', const Token *end' more_args += ', const Token *end'
endCondition = ' && tok != end' endCondition = ' && start_tok != end'
if varId: if varId:
more_args += ', unsigned int varId' more_args += ', unsigned int varid'
ret = '// ' + pattern + '\n' ret = '// ' + pattern + '\n'
ret += 'static const Token *findmatch' + str(findmatchnr) + '(const Token *tok'+more_args+') {\n' ret += 'static const Token *findmatch' + str(findmatchnr) + '(const Token *start_tok'+more_args+') {\n'
ret += ' for (; tok' + endCondition + '; tok = tok->next()) {\n' ret += ' for (; start_tok' + endCondition + '; start_tok = start_tok->next()) {\n'
ret += ' if (match' + str(matchnr) + '(tok' ret += compilePattern(matchStrs, pattern, -1, varId, True)
if varId:
ret += ', varId'
ret += '))\n';
ret += ' return tok;\n'
ret += ' }\n' ret += ' }\n'
ret += ' return NULL;\n}\n' ret += ' return NULL;\n}\n'
matchFunctions.append(compilePattern(matchStrs, pattern, matchnr, varId))
return ret return ret
def parseMatch(line, pos1): def parseMatch(line, pos1):
@ -282,10 +289,9 @@ def replaceTokenFindMatch(matchFunctions, matchStrs, line):
a3 += ',' + endToken a3 += ',' + endToken
if varId: if varId:
a3 += ',' + varId a3 += ',' + varId
findMatchNumber = len(matchFunctions) + 2 findMatchNumber = len(matchFunctions) + 1
matchNumber = len(matchFunctions) + 1
line = line[:pos1]+'findmatch'+str(findMatchNumber)+'('+arg1+a3+')'+line[pos1+len(g0):] line = line[:pos1]+'findmatch'+str(findMatchNumber)+'('+arg1+a3+')'+line[pos1+len(g0):]
matchFunctions.append(compileFindPattern(matchFunctions, matchStrs, pattern, findMatchNumber, matchNumber, endToken, varId)) matchFunctions.append(compileFindPattern(matchFunctions, matchStrs, pattern, findMatchNumber, endToken, varId))
return line return line
@ -326,10 +332,7 @@ def convertFile(srcname, destname):
line = replaceTokenMatch(matchFunctions, matchStrs, line) line = replaceTokenMatch(matchFunctions, matchStrs, line)
# Compile Token::findsimplematch # Compile Token::findsimplematch
# NOTE: Not enabled for now since the generated code # NOTE: Not enabled for now since the generated code is slower than before.
# is slower than before. We need to optimize the compilePattern
# function f.e. not to check for "if (!tok) in the findmatch() case
#
# line = replaceTokenFindMatch(matchFunctions, matchStrs, line) # line = replaceTokenFindMatch(matchFunctions, matchStrs, line)
# Cache plain C-strings in C++ strings # Cache plain C-strings in C++ strings