#include "matchcompiler.h"
#include <string>
#include <cstring>
#include "errorlogger.h"
#include "token.h"
// pattern: (|[|{
static bool match1(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("(")) || (tok->str() == MatchCompiler::makeConstString("[")) || (tok->str() == MatchCompiler::makeConstString("{"))))
        return false;
    return true;
}
// pattern: )|]|}
static bool match2(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString(")")) || (tok->str() == MatchCompiler::makeConstString("]")) || (tok->str() == MatchCompiler::makeConstString("}"))))
        return false;
    return true;
}
// pattern: ( %name%
static bool match3(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: %name%|*|&|::|<
static bool match4(const Token* tok) {
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("*")) || (tok->str() == MatchCompiler::makeConstString("&")) || (tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString("<"))))
        return false;
    return true;
}
// pattern: %var% [:=(]
static bool match5(const Token* tok) {
    if (!tok || !(tok->varId() != 0))
        return false;
    tok = tok->next();
    if (!tok || tok->str().size() != 1U || !strchr(":=(", tok->str()[0]))
        return false;
    return true;
}
// pattern: ) [,)]
static bool match6(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || tok->str().size() != 1U || !strchr(",)", tok->str()[0]))
        return false;
    return true;
}
// pattern: decltype (
static bool match7(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("decltype")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: ( ::| %name%
static bool match8(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("::"))))
        tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: ) ( )
static bool match9(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    return true;
}
// pattern: >
static bool match10(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(">")))
        return false;
    return true;
}
// pattern: ( (| typeof (
static bool match11(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("("))))
        tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("typeof")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: ) %num%
static bool match12(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isNumber())
        return false;
    return true;
}
// pattern: ) }|)|]|;
static bool match13(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("}")) || (tok->str() == MatchCompiler::makeConstString(")")) || (tok->str() == MatchCompiler::makeConstString("]")) || (tok->str() == MatchCompiler::makeConstString(";"))))
        return false;
    return true;
}
// pattern: ) %cop%
static bool match14(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isConstOp())
        return false;
    return true;
}
// pattern: ) [&*+-~!]
static bool match15(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || tok->str().size() != 1U || !strchr("&*+-~!", tok->str()[0]))
        return false;
    return true;
}
// pattern: = ( %name% ) {
static bool match16(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("=")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: (|[|<
static bool match17(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("(")) || (tok->str() == MatchCompiler::makeConstString("[")) || (tok->str() == MatchCompiler::makeConstString("<"))))
        return false;
    return true;
}
// pattern: ) (
static bool match18(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: ) .
static bool match19(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(".")))
        return false;
    return true;
}
// pattern: ) {
static bool match20(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: [{}]
static bool match21(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("{}", tok->str()[0]))
        return false;
    return true;
}
// pattern: ) ~
static bool match22(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("~")))
        return false;
    return true;
}
// pattern: ) %any%
static bool match23(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || false)
        return false;
    return true;
}
// pattern: [[]);,?:.]
static bool match24(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("[]);,?:.", tok->str()[0]))
        return false;
    return true;
}
// pattern: &|&& )
static bool match25(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("&")) || (tok->str() == MatchCompiler::makeConstString("&&"))))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    return true;
}
// pattern: %name%|*|::
static bool match26(const Token* tok) {
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("*")) || (tok->str() == MatchCompiler::makeConstString("::"))))
        return false;
    return true;
}
// pattern: ( * *| )
static bool match27(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("*")))
        return false;
    tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("*"))))
        tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    return true;
}
// pattern: [,()] %name%
static bool match28(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr(",()", tok->str()[0]))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: %name%|::|<
static bool match29(const Token* tok) {
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString("<"))))
        return false;
    return true;
}
// pattern: [*&]
static bool match30(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("*&", tok->str()[0]))
        return false;
    return true;
}
// pattern: {
static bool match31(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: ; }
static bool match32(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(";")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    return true;
}
// pattern: } ,
static bool match33(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(",")))
        return false;
    return true;
}
// pattern: %name%|return|: {
static bool match34(const Token* tok) {
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("return")) || (tok->str() == MatchCompiler::makeConstString(":"))))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: [
static bool match35(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("[")))
        return false;
    return true;
}
// pattern: %name% <
static bool match36(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("<")))
        return false;
    return true;
}
// pattern: > {
static bool match37(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(">")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: %name% ( {
static bool match38(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: else|try|do|const|constexpr|override|volatile|&|&&
static bool match39(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("else")) || (tok->str() == MatchCompiler::makeConstString("try")) || (tok->str() == MatchCompiler::makeConstString("do")) || (tok->str() == MatchCompiler::makeConstString("const")) || (tok->str() == MatchCompiler::makeConstString("constexpr")) || (tok->str() == MatchCompiler::makeConstString("override")) || (tok->str() == MatchCompiler::makeConstString("volatile")) || (tok->str() == MatchCompiler::makeConstString("&")) || (tok->str() == MatchCompiler::makeConstString("&&"))))
        return false;
    return true;
}
// pattern: namespace
static bool match40(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("namespace")))
        return false;
    return true;
}
// pattern: %any% {
static bool match41(const Token* tok) {
    if (!tok || false)
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: return|:
static bool match42(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("return")) || (tok->str() == MatchCompiler::makeConstString(":"))))
        return false;
    return true;
}
// pattern: } ;
static bool match43(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(";")))
        return false;
    return true;
}
// pattern: %name%|::|:|<|>
static bool match44(const Token* tok) {
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString(":")) || (tok->str() == MatchCompiler::makeConstString("<")) || (tok->str() == MatchCompiler::makeConstString(">"))))
        return false;
    return true;
}
// pattern: class|struct
static bool match45(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("class")) || (tok->str() == MatchCompiler::makeConstString("struct"))))
        return false;
    return true;
}
// pattern: &|&&|*
static bool match46(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("&")) || (tok->str() == MatchCompiler::makeConstString("&&")) || (tok->str() == MatchCompiler::makeConstString("*"))))
        return false;
    return true;
}
// pattern: {|;
static bool match47(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("{")) || (tok->str() == MatchCompiler::makeConstString(";"))))
        return false;
    return true;
}
// pattern: ::|. ~
static bool match48(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString("."))))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("~")))
        return false;
    return true;
}
// pattern: L %str%|%char%
static bool match49(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("L")))
        return false;
    tok = tok->next();
    if (!tok || !((tok->tokType() == Token::eString) || (tok->tokType() == Token::eChar)))
        return false;
    return true;
}
// pattern: [{,] . %name%
static bool match50(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("{,", tok->str()[0]))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(".")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: [{,] [ %num%|%name% ]
static bool match51(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("{,", tok->str()[0]))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("[")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isNumber() || tok->isName()))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("]")))
        return false;
    return true;
}
// pattern: %name%|%str%
static bool match52(const Token* tok) {
    if (!tok || !(tok->isName() || (tok->tokType() == Token::eString)))
        return false;
    return true;
}
// pattern: return|case
static bool match53(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("return")) || (tok->str() == MatchCompiler::makeConstString("case"))))
        return false;
    return true;
}
// pattern: : ;
static bool match54(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(":")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(";")))
        return false;
    return true;
}
// pattern: sizeof !!(
static bool match55(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("sizeof")))
        return false;
    tok = tok->next();
    if (tok && tok->str() == MatchCompiler::makeConstString("("))
        return false;
    return true;
}
// pattern: { . %name% =|{
static bool match56(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(".")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("=")) || (tok->str() == MatchCompiler::makeConstString("{"))))
        return false;
    return true;
}
// pattern: { }
static bool match57(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    return true;
}
// pattern: new|delete %name%|*|&|::|(|[
static bool match58(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("new")) || (tok->str() == MatchCompiler::makeConstString("delete"))))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("*")) || (tok->str() == MatchCompiler::makeConstString("&")) || (tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString("(")) || (tok->str() == MatchCompiler::makeConstString("["))))
        return false;
    return true;
}
// pattern: %name%
static bool match59(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: > %name%
static bool match60(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(">")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: <
static bool match61(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("<")))
        return false;
    return true;
}
// pattern: %name% ...
static bool match62(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("...")))
        return false;
    return true;
}
// pattern: %str%
static bool match63(const Token* tok) {
    if (!tok || !(tok->tokType() == Token::eString))
        return false;
    return true;
}
// pattern: %name% %assign%
static bool match64(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !tok->isAssignmentOp())
        return false;
    return true;
}
// pattern: } [
static bool match65(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("[")))
        return false;
    return true;
}
// pattern: [{,]
static bool match66(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("{,", tok->str()[0]))
        return false;
    return true;
}
// pattern: %name% (
static bool match67(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: { !!}
static bool match68(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    tok = tok->next();
    if (tok && tok->str() == MatchCompiler::makeConstString("}"))
        return false;
    return true;
}
// pattern: } ,|:|)
static bool match69(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString(",")) || (tok->str() == MatchCompiler::makeConstString(":")) || (tok->str() == MatchCompiler::makeConstString(")"))))
        return false;
    return true;
}
// pattern: ;
template<class T> static T * findmatch70(T * start_tok, const Token * end) {
    for (; start_tok && start_tok != end; start_tok = start_tok->next()) {

    T * tok = start_tok;
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(";")))
        continue;
    return start_tok;
    }
    return nullptr;
}
// pattern: =
static bool match71(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("=")))
        return false;
    return true;
}
// pattern: } [,};]
static bool match72(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    tok = tok->next();
    if (!tok || tok->str().size() != 1U || !strchr(",};", tok->str()[0]))
        return false;
    return true;
}
// pattern: :: %name%
static bool match73(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("::")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: (|[|{|%op%|;|}|?|:|,|.|return|::
static bool match74(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("(")) || (tok->str() == MatchCompiler::makeConstString("[")) || (tok->str() == MatchCompiler::makeConstString("{")) || tok->isOp() || (tok->str() == MatchCompiler::makeConstString(";")) || (tok->str() == MatchCompiler::makeConstString("}")) || (tok->str() == MatchCompiler::makeConstString("?")) || (tok->str() == MatchCompiler::makeConstString(":")) || (tok->str() == MatchCompiler::makeConstString(",")) || (tok->str() == MatchCompiler::makeConstString(".")) || (tok->str() == MatchCompiler::makeConstString("return")) || (tok->str() == MatchCompiler::makeConstString("::"))))
        return false;
    return true;
}
// pattern: ] (|{
static bool match75(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("]")))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("(")) || (tok->str() == MatchCompiler::makeConstString("{"))))
        return false;
    return true;
}
// pattern: ] (
static bool match76(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("]")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: mutable|const|constexpr
static bool match77(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("mutable")) || (tok->str() == MatchCompiler::makeConstString("const")) || (tok->str() == MatchCompiler::makeConstString("constexpr"))))
        return false;
    return true;
}
// pattern: noexcept (
static bool match78(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("noexcept")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: if|while|for|switch|catch
static bool match79(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("if")) || (tok->str() == MatchCompiler::makeConstString("while")) || (tok->str() == MatchCompiler::makeConstString("for")) || (tok->str() == MatchCompiler::makeConstString("switch")) || (tok->str() == MatchCompiler::makeConstString("catch"))))
        return false;
    return true;
}
// pattern: } (
static bool match80(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: throw|delete
static bool match81(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("throw")) || (tok->str() == MatchCompiler::makeConstString("delete"))))
        return false;
    return true;
}
// pattern: new|delete
static bool match82(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("new")) || (tok->str() == MatchCompiler::makeConstString("delete"))))
        return false;
    return true;
}
// pattern: }
static bool match83(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    return true;
}
// pattern: [+-!~*&]
static bool match84(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("+-!~*&", tok->str()[0]))
        return false;
    return true;
}
// pattern: * [*,)]
static bool match85(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("*")))
        return false;
    tok = tok->next();
    if (!tok || tok->str().size() != 1U || !strchr("*,)", tok->str()[0]))
        return false;
    return true;
}
// pattern: [>),]
static bool match86(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr(">),", tok->str()[0]))
        return false;
    return true;
}
// pattern: new %name%|::|(
static bool match87(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("new")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString("("))))
        return false;
    return true;
}
// pattern: ( &| %name%
static bool match88(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("&"))))
        tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: ) ( %type%
static bool match89(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isName() && tok->varId() == 0U && (tok->str() != "delete" || !tok->isKeyword())))
        return false;
    return true;
}
// pattern: ) ::| %type%
static bool match90(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("::"))))
        tok = tok->next();
    if (!tok || !(tok->isName() && tok->varId() == 0U && (tok->str() != "delete" || !tok->isKeyword())))
        return false;
    return true;
}
// pattern: ( !!)
static bool match91(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (tok && tok->str() == MatchCompiler::makeConstString(")"))
        return false;
    return true;
}
// pattern: ( %type%
static bool match92(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isName() && tok->varId() == 0U && (tok->str() != "delete" || !tok->isKeyword())))
        return false;
    return true;
}
// pattern: ) [();,[]
static bool match93(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || tok->str().size() != 1U || !strchr("();,[", tok->str()[0]))
        return false;
    return true;
}
// pattern: %name%|*|&|<|::
static bool match94(const Token* tok) {
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("*")) || (tok->str() == MatchCompiler::makeConstString("&")) || (tok->str() == MatchCompiler::makeConstString("<")) || (tok->str() == MatchCompiler::makeConstString("::"))))
        return false;
    return true;
}
// pattern: ( const| %type% ) (
static bool match95(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("const"))))
        tok = tok->next();
    if (!tok || !(tok->isName() && tok->varId() == 0U && (tok->str() != "delete" || !tok->isKeyword())))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: ) [
static bool match96(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("[")))
        return false;
    return true;
}
// pattern: ) ,
static bool match97(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(",")))
        return false;
    return true;
}
// pattern: delete %name%|*|&|::|(|[
static bool match98(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("delete")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("*")) || (tok->str() == MatchCompiler::makeConstString("&")) || (tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString("(")) || (tok->str() == MatchCompiler::makeConstString("["))))
        return false;
    return true;
}
// pattern: . *
static bool match99(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(".")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("*")))
        return false;
    return true;
}
// pattern: [/%]
static bool match100(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("/%", tok->str()[0]))
        return false;
    return true;
}
// pattern: +|-
static bool match101(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("+")) || (tok->str() == MatchCompiler::makeConstString("-"))))
        return false;
    return true;
}
// pattern: <<|>>
static bool match102(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("<<")) || (tok->str() == MatchCompiler::makeConstString(">>"))))
        return false;
    return true;
}
// pattern: <|<=|>=|>
static bool match103(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("<")) || (tok->str() == MatchCompiler::makeConstString("<=")) || (tok->str() == MatchCompiler::makeConstString(">=")) || (tok->str() == MatchCompiler::makeConstString(">"))))
        return false;
    return true;
}
// pattern: ==|!=
static bool match104(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("==")) || (tok->str() == MatchCompiler::makeConstString("!="))))
        return false;
    return true;
}
// pattern: ,|)
static bool match105(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString(",")) || (tok->str() == MatchCompiler::makeConstString(")"))))
        return false;
    return true;
}
// pattern: , }
static bool match106(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(",")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("}")))
        return false;
    return true;
}
// pattern: ( {
static bool match107(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: for (
static bool match108(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("for")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: for ( const| auto &|&&| [
static bool match109(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("for")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("const"))))
        tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("auto")))
        return false;
    tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("&")) || (tok->str() == MatchCompiler::makeConstString("&&"))))
        tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("[")))
        return false;
    return true;
}
// pattern: [
template<class T> static T * findmatch110(T * start_tok) {
    for (; start_tok; start_tok = start_tok->next()) {

    T * tok = start_tok;
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("[")))
        continue;
    return start_tok;
    }
    return nullptr;
}
// pattern: ] :
static bool match111(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("]")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(":")))
        return false;
    return true;
}
// pattern: %name% ,|]
static bool match112(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString(",")) || (tok->str() == MatchCompiler::makeConstString("]"))))
        return false;
    return true;
}
// pattern: %op%|(
static bool match113(const Token* tok) {
    if (!tok || !(tok->isOp() || (tok->str() == MatchCompiler::makeConstString("("))))
        return false;
    return true;
}
// pattern: ( !!{
static bool match114(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    tok = tok->next();
    if (tok && tok->str() == MatchCompiler::makeConstString("{"))
        return false;
    return true;
}
// pattern: %op%|(|[
static bool match115(const Token* tok) {
    if (!tok || !(tok->isOp() || (tok->str() == MatchCompiler::makeConstString("(")) || (tok->str() == MatchCompiler::makeConstString("["))))
        return false;
    return true;
}
// pattern: %name% %op%|(|[|.|:|::
static bool match116(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->isOp() || (tok->str() == MatchCompiler::makeConstString("(")) || (tok->str() == MatchCompiler::makeConstString("[")) || (tok->str() == MatchCompiler::makeConstString(".")) || (tok->str() == MatchCompiler::makeConstString(":")) || (tok->str() == MatchCompiler::makeConstString("::"))))
        return false;
    return true;
}
// pattern: [(;{}] %cop%|(
static bool match117(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("(;{}", tok->str()[0]))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isConstOp() || (tok->str() == MatchCompiler::makeConstString("("))))
        return false;
    return true;
}
// pattern: ;|)
static bool match118(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString(";")) || (tok->str() == MatchCompiler::makeConstString(")"))))
        return false;
    return true;
}
// pattern: :
static bool match119(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(":")))
        return false;
    return true;
}
// pattern: %type% <
static bool match120(const Token* tok) {
    if (!tok || !(tok->isName() && tok->varId() == 0U && (tok->str() != "delete" || !tok->isKeyword())))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("<")))
        return false;
    return true;
}
// pattern: > [({]
static bool match121(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(">")))
        return false;
    tok = tok->next();
    if (!tok || tok->str().size() != 1U || !strchr("({", tok->str()[0]))
        return false;
    return true;
}
// pattern: %type% ::|<|%name%
static bool match122(const Token* tok) {
    if (!tok || !(tok->isName() && tok->varId() == 0U && (tok->str() != "delete" || !tok->isKeyword())))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString("<")) || tok->isName()))
        return false;
    return true;
}
// pattern: %name%|> :: %name%
static bool match123(const Token* tok) {
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString(">"))))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("::")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: %name%|> %name% {
static bool match124(const Token* tok) {
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString(">"))))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: %type% %name%|*|&|::
static bool match125(const Token* tok) {
    if (!tok || !(tok->isName() && tok->varId() == 0U && (tok->str() != "delete" || !tok->isKeyword())))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isName() || (tok->str() == MatchCompiler::makeConstString("*")) || (tok->str() == MatchCompiler::makeConstString("&")) || (tok->str() == MatchCompiler::makeConstString("::"))))
        return false;
    return true;
}
// pattern: %type%|::|*|&
static bool match126(const Token* tok) {
    if (!tok || !((tok->isName() && tok->varId() == 0U && (tok->str() != "delete" || !tok->isKeyword())) || (tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString("*")) || (tok->str() == MatchCompiler::makeConstString("&"))))
        return false;
    return true;
}
// pattern: ::
static bool match127(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("::")))
        return false;
    return true;
}
// pattern: %var% =
static bool match128(const Token* tok) {
    if (!tok || !(tok->varId() != 0))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("=")))
        return false;
    return true;
}
// pattern: return|throw
static bool match129(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("return")) || (tok->str() == MatchCompiler::makeConstString("throw"))))
        return false;
    return true;
}
// pattern: ) const|;|{
static bool match130(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("const")) || (tok->str() == MatchCompiler::makeConstString(";")) || (tok->str() == MatchCompiler::makeConstString("{"))))
        return false;
    return true;
}
// pattern: %name% %op%|(|[|.|::|<|?|;
static bool match131(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->isOp() || (tok->str() == MatchCompiler::makeConstString("(")) || (tok->str() == MatchCompiler::makeConstString("[")) || (tok->str() == MatchCompiler::makeConstString(".")) || (tok->str() == MatchCompiler::makeConstString("::")) || (tok->str() == MatchCompiler::makeConstString("<")) || (tok->str() == MatchCompiler::makeConstString("?")) || (tok->str() == MatchCompiler::makeConstString(";"))))
        return false;
    return true;
}
// pattern: %name% {
static bool match132(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("{")))
        return false;
    return true;
}
// pattern: [;{}] %cop%|++|--|( !!{
static bool match133(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr(";{}", tok->str()[0]))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isConstOp() || (tok->str() == MatchCompiler::makeConstString("++")) || (tok->str() == MatchCompiler::makeConstString("--")) || (tok->str() == MatchCompiler::makeConstString("("))))
        return false;
    tok = tok->next();
    if (tok && tok->str() == MatchCompiler::makeConstString("{"))
        return false;
    return true;
}
// pattern: [;{}] %num%|%str%|%char%
static bool match134(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr(";{}", tok->str()[0]))
        return false;
    tok = tok->next();
    if (!tok || !(tok->isNumber() || (tok->tokType() == Token::eString) || (tok->tokType() == Token::eChar)))
        return false;
    return true;
}
// pattern: [;{}] new|delete %name%
static bool match135(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr(";{}", tok->str()[0]))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("new")) || (tok->str() == MatchCompiler::makeConstString("delete"))))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: [;{}] :: new|delete %name%
static bool match136(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr(";{}", tok->str()[0]))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("::")))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("new")) || (tok->str() == MatchCompiler::makeConstString("delete"))))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: [|^/%]
static bool match137(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr("|^/%", tok->str()[0]))
        return false;
    return true;
}
// pattern: %or%|%oror%|%assign%|%comp%
static bool match138(const Token* tok) {
    if (!tok || !((tok->tokType() == Token::eBitOp && tok->str() == MatchCompiler::makeConstString("|") ) || (tok->tokType() == Token::eLogicalOp && tok->str() == MatchCompiler::makeConstString("||")) || tok->isAssignmentOp() || tok->isComparisonOp()))
        return false;
    return true;
}
// pattern: = ,|]
static bool match139(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("=")))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString(",")) || (tok->str() == MatchCompiler::makeConstString("]"))))
        return false;
    return true;
}
// pattern: ) = 0
static bool match140(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(")")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("=")))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("0")))
        return false;
    return true;
}
// pattern: operator
static bool match141(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("operator")))
        return false;
    return true;
}
// pattern: = {|^|[
static bool match142(const Token* tok) {
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("=")))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("{")) || (tok->str() == MatchCompiler::makeConstString("^")) || (tok->str() == MatchCompiler::makeConstString("["))))
        return false;
    return true;
}
// pattern: %name% = %name%
static bool match143(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("=")))
        return false;
    tok = tok->next();
    if (!tok || !tok->isName())
        return false;
    return true;
}
// pattern: if|while|for|switch|assert|ASSERT (
static bool match144(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("if")) || (tok->str() == MatchCompiler::makeConstString("while")) || (tok->str() == MatchCompiler::makeConstString("for")) || (tok->str() == MatchCompiler::makeConstString("switch")) || (tok->str() == MatchCompiler::makeConstString("assert")) || (tok->str() == MatchCompiler::makeConstString("ASSERT"))))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString("(")))
        return false;
    return true;
}
// pattern: %var% .
static bool match145(const Token* tok) {
    if (!tok || !(tok->varId() != 0))
        return false;
    tok = tok->next();
    if (!tok || !(tok->str() == MatchCompiler::makeConstString(".")))
        return false;
    return true;
}
// pattern: std| ::| %type%
static bool match146(const Token* tok) {
    if (tok && ((tok->str() == MatchCompiler::makeConstString("std"))))
        tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("::"))))
        tok = tok->next();
    if (!tok || !(tok->isName() && tok->varId() == 0U && (tok->str() != "delete" || !tok->isKeyword())))
        return false;
    return true;
}
// pattern: std| ::| size_t|uintptr_t|uintmax_t
static bool match147(const Token* tok) {
    if (tok && ((tok->str() == MatchCompiler::makeConstString("std"))))
        tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("::"))))
        tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("size_t")) || (tok->str() == MatchCompiler::makeConstString("uintptr_t")) || (tok->str() == MatchCompiler::makeConstString("uintmax_t"))))
        return false;
    return true;
}
// pattern: std| ::| ssize_t|ptrdiff_t|intptr_t|intmax_t
static bool match148(const Token* tok) {
    if (tok && ((tok->str() == MatchCompiler::makeConstString("std"))))
        tok = tok->next();
    if (tok && ((tok->str() == MatchCompiler::makeConstString("::"))))
        tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("ssize_t")) || (tok->str() == MatchCompiler::makeConstString("ptrdiff_t")) || (tok->str() == MatchCompiler::makeConstString("intptr_t")) || (tok->str() == MatchCompiler::makeConstString("intmax_t"))))
        return false;
    return true;
}
// pattern: const|extern *|&|%name%
static bool match149(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("const")) || (tok->str() == MatchCompiler::makeConstString("extern"))))
        return false;
    tok = tok->next();
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("*")) || (tok->str() == MatchCompiler::makeConstString("&")) || tok->isName()))
        return false;
    return true;
}
// pattern: [;{}]
static bool match150(const Token* tok) {
    if (!tok || tok->str().size() != 1U || !strchr(";{}", tok->str()[0]))
        return false;
    return true;
}
// pattern: %name% !!;
static bool match151(const Token* tok) {
    if (!tok || !tok->isName())
        return false;
    tok = tok->next();
    if (tok && tok->str() == MatchCompiler::makeConstString(";"))
        return false;
    return true;
}
// pattern: char|short|int|long|unsigned|signed|double|float
static bool match152(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("char")) || (tok->str() == MatchCompiler::makeConstString("short")) || (tok->str() == MatchCompiler::makeConstString("int")) || (tok->str() == MatchCompiler::makeConstString("long")) || (tok->str() == MatchCompiler::makeConstString("unsigned")) || (tok->str() == MatchCompiler::makeConstString("signed")) || (tok->str() == MatchCompiler::makeConstString("double")) || (tok->str() == MatchCompiler::makeConstString("float"))))
        return false;
    return true;
}
// pattern: complex|_Complex
static bool match153(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("complex")) || (tok->str() == MatchCompiler::makeConstString("_Complex"))))
        return false;
    return true;
}
// pattern: float|double
static bool match154(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("float")) || (tok->str() == MatchCompiler::makeConstString("double"))))
        return false;
    return true;
}
// pattern: *|&|%name%
static bool match155(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("*")) || (tok->str() == MatchCompiler::makeConstString("&")) || tok->isName()))
        return false;
    return true;
}
// pattern: char|int
static bool match156(const Token* tok) {
    if (!tok || !((tok->str() == MatchCompiler::makeConstString("char")) || (tok->str() == MatchCompiler::makeConstString("int"))))
        return false;
    return true;
}
#line 1 "/build/cppcheck/src/cppcheck/lib/tokenlist.cpp"
/*
 * Cppcheck - A tool for static C/C++ code analysis
 * Copyright (C) 2007-2022 Cppcheck team.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

//---------------------------------------------------------------------------
#include "tokenlist.h"

#include "astutils.h"
#include "errorlogger.h"
#include "errortypes.h"
#include "library.h"
#include "path.h"
#include "settings.h"
#include "standards.h"
#include "token.h"

#include <algorithm>
#include <cctype>
#include <cstring>
#include <exception>
#include <functional>
#include <utility>
#include <set>
#include <stack>

#include <simplecpp.h>

// How many compileExpression recursions are allowed?
// For practical code this could be endless. But in some special torture test
// there needs to be a limit.
static const int AST_MAX_DEPTH = 100;


TokenList::TokenList(const Settings* settings) :
    mTokensFrontBack(),
    mSettings(settings),
    mIsC(false),
    mIsCpp(false)
{
    mTokensFrontBack.list = this;
    mKeywords.insert("auto");
    mKeywords.insert("break");
    mKeywords.insert("case");
    //mKeywords.insert("char"); // type
    mKeywords.insert("const");
    mKeywords.insert("continue");
    mKeywords.insert("default");
    mKeywords.insert("do");
    //mKeywords.insert("double"); // type
    mKeywords.insert("else");
    mKeywords.insert("enum");
    mKeywords.insert("extern");
    //mKeywords.insert("float"); // type
    mKeywords.insert("for");
    mKeywords.insert("goto");
    mKeywords.insert("if");
    mKeywords.insert("inline");
    //mKeywords.insert("int"); // type
    //mKeywords.insert("long"); // type
    mKeywords.insert("register");
    mKeywords.insert("restrict");
    mKeywords.insert("return");
    //mKeywords.insert("short"); // type
    mKeywords.insert("signed");
    mKeywords.insert("sizeof");
    mKeywords.insert("static");
    mKeywords.insert("struct");
    mKeywords.insert("switch");
    mKeywords.insert("typedef");
    mKeywords.insert("union");
    mKeywords.insert("unsigned");
    mKeywords.insert("void");
    mKeywords.insert("volatile");
    mKeywords.insert("while");
}

TokenList::~TokenList()
{
    deallocateTokens();
}

//---------------------------------------------------------------------------

const std::string& TokenList::getSourceFilePath() const
{
    if (getFiles().empty()) {
        return emptyString;
    }
    return getFiles()[0];
}

//---------------------------------------------------------------------------

// Deallocate lists..
void TokenList::deallocateTokens()
{
    deleteTokens(mTokensFrontBack.front);
    mTokensFrontBack.front = nullptr;
    mTokensFrontBack.back = nullptr;
    mFiles.clear();
}

void TokenList::determineCppC()
{
    if (!mSettings) {
        mIsC = Path::isC(getSourceFilePath());
        mIsCpp = Path::isCPP(getSourceFilePath());
    } else {
        mIsC = mSettings->enforcedLang == Settings::C || (mSettings->enforcedLang == Settings::None && Path::isC(getSourceFilePath()));
        mIsCpp = mSettings->enforcedLang == Settings::CPP || (mSettings->enforcedLang == Settings::None && Path::isCPP(getSourceFilePath()));
    }

    if (mIsCpp) {
        //mKeywords.insert("bool"); // type
        mKeywords.insert("catch");
        mKeywords.insert("class");
        mKeywords.insert("constexpr");
        mKeywords.insert("const_cast");
        mKeywords.insert("decltype");
        mKeywords.insert("delete");
        mKeywords.insert("dynamic_cast");
        mKeywords.insert("explicit");
        mKeywords.insert("export");
        //mKeywords.insert("false"); // literal
        mKeywords.insert("friend");
        mKeywords.insert("mutable");
        mKeywords.insert("namespace");
        mKeywords.insert("new");
        mKeywords.insert("noexcept");
        mKeywords.insert("operator");
        mKeywords.insert("private");
        mKeywords.insert("protected");
        mKeywords.insert("public");
        mKeywords.insert("reinterpret_cast");
        mKeywords.insert("static_assert");
        mKeywords.insert("static_cast");
        mKeywords.insert("template");
        mKeywords.insert("this");
        mKeywords.insert("thread_local");
        mKeywords.insert("throw");
        //mKeywords.insert("true"); // literal
        mKeywords.insert("try");
        mKeywords.insert("typeid");
        mKeywords.insert("typename");
        mKeywords.insert("typeof");
        mKeywords.insert("using");
        mKeywords.insert("virtual");
        //mKeywords.insert("wchar_t"); // type
        if (!mSettings || mSettings->standards.cpp >= Standards::CPP20) {
            mKeywords.insert("alignas");
            mKeywords.insert("alignof");
            mKeywords.insert("axiom");
            mKeywords.insert("co_await");
            mKeywords.insert("co_return");
            mKeywords.insert("co_yield");
            mKeywords.insert("concept");
            mKeywords.insert("synchronized");
            mKeywords.insert("consteval");
            mKeywords.insert("reflexpr");
            mKeywords.insert("requires");
        }
    }
}

int TokenList::appendFileIfNew(const std::string &fileName)
{
    // Has this file been tokenized already?
    for (int i = 0; i < mFiles.size(); ++i)
        if (Path::sameFileName(mFiles[i], fileName))
            return i;

    // The "mFiles" vector remembers what files have been tokenized..
    mFiles.push_back(fileName);

    // Update mIsC and mIsCpp properties
    if (mFiles.size() == 1) { // Update only useful if first file added to _files
        determineCppC();
    }
    return mFiles.size() - 1;
}

void TokenList::clangSetOrigFiles()
{
    mOrigFiles = mFiles;
}

void TokenList::deleteTokens(Token *tok)
{
    while (tok) {
        Token *next = tok->next();
        delete tok;
        tok = next;
    }
}

//---------------------------------------------------------------------------
// add a token.
//---------------------------------------------------------------------------

void TokenList::addtoken(std::string str, const nonneg int lineno, const nonneg int column, const nonneg int fileno, bool split)
{
    if (str.empty())
        return;

    // If token contains # characters, split it up
    if (split) {
        size_t begin = 0;
        size_t end = 0;
        while ((end = str.find("##", begin)) != std::string::npos) {
            addtoken(str.substr(begin, end - begin), lineno, fileno, false);
            addtoken("##", lineno, column, fileno, false);
            begin = end+2;
        }
        if (begin != 0) {
            addtoken(str.substr(begin), lineno, column, fileno, false);
            return;
        }
    }

    if (mTokensFrontBack.back) {
        mTokensFrontBack.back->insertToken(str);
    } else {
        mTokensFrontBack.front = new Token(&mTokensFrontBack);
        mTokensFrontBack.back = mTokensFrontBack.front;
        mTokensFrontBack.back->str(str);
    }

    mTokensFrontBack.back->linenr(lineno);
    mTokensFrontBack.back->column(column);
    mTokensFrontBack.back->fileIndex(fileno);
}

void TokenList::addtoken(std::string str, const Token *locationTok)
{
    if (str.empty())
        return;

    if (mTokensFrontBack.back) {
        mTokensFrontBack.back->insertToken(str);
    } else {
        mTokensFrontBack.front = new Token(&mTokensFrontBack);
        mTokensFrontBack.back = mTokensFrontBack.front;
        mTokensFrontBack.back->str(str);
    }

    mTokensFrontBack.back->linenr(locationTok->linenr());
    mTokensFrontBack.back->column(locationTok->column());
    mTokensFrontBack.back->fileIndex(locationTok->fileIndex());
}

void TokenList::addtoken(const Token * tok, const nonneg int lineno, const nonneg int column, const nonneg int fileno)
{
    if (tok == nullptr)
        return;

    if (mTokensFrontBack.back) {
        mTokensFrontBack.back->insertToken(tok->str(), tok->originalName());
    } else {
        mTokensFrontBack.front = new Token(&mTokensFrontBack);
        mTokensFrontBack.back = mTokensFrontBack.front;
        mTokensFrontBack.back->str(tok->str());
        if (!tok->originalName().empty())
            mTokensFrontBack.back->originalName(tok->originalName());
    }

    mTokensFrontBack.back->linenr(lineno);
    mTokensFrontBack.back->column(column);
    mTokensFrontBack.back->fileIndex(fileno);
    mTokensFrontBack.back->flags(tok->flags());
}

void TokenList::addtoken(const Token *tok, const Token *locationTok)
{
    if (tok == nullptr || locationTok == nullptr)
        return;

    if (mTokensFrontBack.back) {
        mTokensFrontBack.back->insertToken(tok->str(), tok->originalName());
    } else {
        mTokensFrontBack.front = new Token(&mTokensFrontBack);
        mTokensFrontBack.back = mTokensFrontBack.front;
        mTokensFrontBack.back->str(tok->str());
        if (!tok->originalName().empty())
            mTokensFrontBack.back->originalName(tok->originalName());
    }

    mTokensFrontBack.back->flags(tok->flags());
    mTokensFrontBack.back->linenr(locationTok->linenr());
    mTokensFrontBack.back->column(locationTok->column());
    mTokensFrontBack.back->fileIndex(locationTok->fileIndex());
}

void TokenList::addtoken(const Token *tok)
{
    if (tok == nullptr)
        return;

    if (mTokensFrontBack.back) {
        mTokensFrontBack.back->insertToken(tok->str(), tok->originalName());
    } else {
        mTokensFrontBack.front = new Token(&mTokensFrontBack);
        mTokensFrontBack.back = mTokensFrontBack.front;
        mTokensFrontBack.back->str(tok->str());
        if (!tok->originalName().empty())
            mTokensFrontBack.back->originalName(tok->originalName());
    }

    mTokensFrontBack.back->flags(tok->flags());
    mTokensFrontBack.back->linenr(tok->linenr());
    mTokensFrontBack.back->column(tok->column());
    mTokensFrontBack.back->fileIndex(tok->fileIndex());
}


//---------------------------------------------------------------------------
// copyTokens - Copy and insert tokens
//---------------------------------------------------------------------------

Token *TokenList::copyTokens(Token *dest, const Token *first, const Token *last, bool one_line)
{
    std::stack<Token *> links;
    Token *tok2 = dest;
    int linenr = dest->linenr();
    const int commonFileIndex = dest->fileIndex();
    for (const Token *tok = first; tok != last->next(); tok = tok->next()) {
        tok2->insertToken(tok->str());
        tok2 = tok2->next();
        tok2->fileIndex(commonFileIndex);
        tok2->linenr(linenr);
        tok2->tokType(tok->tokType());
        tok2->flags(tok->flags());
        tok2->varId(tok->varId());

        // Check for links and fix them up
        if (match1(tok2))
            links.push(tok2);
        else if (match2(tok2)) {
            if (links.empty())
                return tok2;

            Token * link = links.top();

            tok2->link(link);
            link->link(tok2);

            links.pop();
        }
        if (!one_line && tok->next())
            linenr += tok->next()->linenr() - tok->linenr();
    }
    return tok2;
}

//---------------------------------------------------------------------------
// InsertTokens - Copy and insert tokens
//---------------------------------------------------------------------------

void TokenList::insertTokens(Token *dest, const Token *src, nonneg int n)
{
    std::stack<Token *> link;

    while (n > 0) {
        dest->insertToken(src->str(), src->originalName());
        dest = dest->next();

        // Set links
        if (match1(dest))
            link.push(dest);
        else if (!link.empty() && match2(dest)) {
            Token::createMutualLinks(dest, link.top());
            link.pop();
        }

        dest->fileIndex(src->fileIndex());
        dest->linenr(src->linenr());
        dest->column(src->column());
        dest->varId(src->varId());
        dest->tokType(src->tokType());
        dest->flags(src->flags());
        src  = src->next();
        --n;
    }
}

//---------------------------------------------------------------------------
// Tokenize - tokenizes a given file.
//---------------------------------------------------------------------------

bool TokenList::createTokens(std::istream &code, const std::string& file0)
{
    appendFileIfNew(file0);

    simplecpp::OutputList outputList;
    simplecpp::TokenList tokens(code, mFiles, file0, &outputList);

    createTokens(std::move(tokens));

    return outputList.empty();
}

//---------------------------------------------------------------------------

void TokenList::createTokens(simplecpp::TokenList&& tokenList)
{
    if (tokenList.cfront())
        mOrigFiles = mFiles = tokenList.cfront()->location.files;
    else
        mFiles.clear();

    determineCppC();

    for (const simplecpp::Token *tok = tokenList.cfront(); tok;) {

        std::string str = tok->str();

        // Float literal
        if (str.size() > 1 && str[0] == '.' && std::isdigit(str[1]))
            str = '0' + str;

        if (mTokensFrontBack.back) {
            mTokensFrontBack.back->insertToken(str);
        } else {
            mTokensFrontBack.front = new Token(&mTokensFrontBack);
            mTokensFrontBack.back = mTokensFrontBack.front;
            mTokensFrontBack.back->str(str);
        }

        mTokensFrontBack.back->fileIndex(tok->location.fileIndex);
        mTokensFrontBack.back->linenr(tok->location.line);
        mTokensFrontBack.back->column(tok->location.col);
        mTokensFrontBack.back->isExpandedMacro(!tok->macro.empty());

        tok = tok->next;
        if (tok)
            tokenList.deleteToken(tok->previous);
    }

    if (mSettings && mSettings->relativePaths) {
        for (std::string & mFile : mFiles)
            mFile = Path::getRelativePath(mFile, mSettings->basePaths);
    }

    Token::assignProgressValues(mTokensFrontBack.front);
}

//---------------------------------------------------------------------------

unsigned long long TokenList::calculateChecksum() const
{
    unsigned long long checksum = 0;
    for (const Token* tok = front(); tok; tok = tok->next()) {
        const unsigned int subchecksum1 = tok->flags() + tok->varId() + tok->tokType();
        unsigned int subchecksum2 = 0;
        for (char i : tok->str())
            subchecksum2 += (unsigned int)i;
        if (!tok->originalName().empty()) {
            for (char i : tok->originalName())
                subchecksum2 += (unsigned int) i;
        }

        checksum ^= ((static_cast<unsigned long long>(subchecksum1) << 32) | subchecksum2);

        const bool bit1 = (checksum & 1) != 0;
        checksum >>= 1;
        if (bit1)
            checksum |= (1ULL << 63);
    }
    return checksum;
}


//---------------------------------------------------------------------------

struct AST_state {
    std::stack<Token*> op;
    int depth;
    int inArrayAssignment;
    bool cpp;
    int assign;
    bool inCase; // true from case to :
    bool stopAtColon; // help to properly parse ternary operators
    const Token *functionCallEndPar;
    explicit AST_state(bool cpp) : depth(0), inArrayAssignment(0), cpp(cpp), assign(0), inCase(false),stopAtColon(false), functionCallEndPar(nullptr) {}
};

static Token * skipDecl(Token *tok)
{
    if (!match3(tok->previous()))
        return tok;
    Token *vartok = tok;
    while (match4(vartok)) {
        if (vartok->str() == MatchCompiler::makeConstString("<")) {
            if (vartok->link())
                vartok = vartok->link();
            else
                return tok;
        } else if (match5(vartok)) {
            return vartok;
        } else if (match7(vartok) && !match6(tok->linkAt(1))) {
            return vartok->linkAt(1)->next();
        }
        vartok = vartok->next();
    }
    return tok;
}

static bool iscast(const Token *tok, bool cpp)
{
    if (!match8(tok))
        return false;

    if (match9(tok->link()))
        return false;

    if (tok->previous() && tok->previous()->isName() && tok->previous()->str() != MatchCompiler::makeConstString("return") &&
        (!cpp || tok->previous()->str() != MatchCompiler::makeConstString("throw")))
        return false;

    if (match10(tok->previous()) && tok->previous()->link())
        return false;

    if (match11(tok) && match12(tok->link()))
        return true;

    if (match13(tok->link()))
        return false;

    if (match14(tok->link()) && !match15(tok->link()))
        return false;

    if (match16(tok->previous()) && tok->next()->varId() == 0)
        return true;

    bool type = false;
    for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
        if (tok2->varId() != 0)
            return false;

        while (tok2->link() && match17(tok2))
            tok2 = tok2->link()->next();

        if (tok2->str() == MatchCompiler::makeConstString(")")) {
            if (match18(tok2) && match19(tok2->linkAt(1)))
                return true;
            if (match20(tok2) && !type) {
                const Token *tok3 = tok2->linkAt(1);
                while (tok3 != tok2 && match21(tok3))
                    tok3 = tok3->previous();
                return tok3 != tok2 && tok3->str() != MatchCompiler::makeConstString(";");
            }
            return type || tok2->strAt(-1) == MatchCompiler::makeConstString("*") || match22(tok2) ||
                   (match23(tok2) &&
                    !tok2->next()->isOp() &&
                    !match24(tok2->next()));
        }

        if (match25(tok2))
            return true;

        if (!match26(tok2))
            return false;

        if (tok2->isStandardType() && (tok2->next()->str() != MatchCompiler::makeConstString("(") || match27(tok2->next())))
            type = true;
    }

    return false;
}

// int(1), int*(2), ..
static Token * findCppTypeInitPar(Token *tok)
{
    if (!tok || !match28(tok->previous()))
        return nullptr;
    bool istype = false;
    while (match29(tok)) {
        if (tok->str() == MatchCompiler::makeConstString("<")) {
            tok = tok->link();
            if (!tok)
                return nullptr;
        }
        istype |= tok->isStandardType();
        tok = tok->next();
    }
    if (!istype)
        return nullptr;
    if (!match30(tok))
        return nullptr;
    while (match30(tok))
        tok = tok->next();
    return (tok && tok->str() == MatchCompiler::makeConstString("(")) ? tok : nullptr;
}

// X{} X<Y>{} etc
static bool iscpp11init_impl(const Token * const tok);
static bool iscpp11init(const Token * const tok)
{
    if (tok->isCpp11init() == TokenImpl::Cpp11init::UNKNOWN)
        tok->setCpp11init(iscpp11init_impl(tok));
    return tok->isCpp11init() == TokenImpl::Cpp11init::CPP11INIT;
}

static bool iscpp11init_impl(const Token * const tok)
{
    if (match31(tok) && match32(tok->link()->previous()))
        return false;
    const Token *nameToken = tok;
    while (nameToken && nameToken->str() == MatchCompiler::makeConstString("{")) {
        if (nameToken->isCpp11init() != TokenImpl::Cpp11init::UNKNOWN)
            return nameToken->isCpp11init() == TokenImpl::Cpp11init::CPP11INIT;
        nameToken = nameToken->previous();
        if (nameToken && nameToken->str() == MatchCompiler::makeConstString(",") && match33(nameToken->previous()))
            nameToken = nameToken->linkAt(-1);
    }
    if (!nameToken)
        return false;
    if (nameToken->str() == MatchCompiler::makeConstString(")") && match7(nameToken->link()->previous()))
        return true;
    if (nameToken->str() == MatchCompiler::makeConstString(">") && nameToken->link())
        nameToken = nameToken->link()->previous();

    const Token *endtok = nullptr;
    if (match34(nameToken) &&
        (!match35(nameToken->tokAt(2)) || findLambdaEndScope(nameToken->tokAt(2))))
        endtok = nameToken->linkAt(1);
    else if (match36(nameToken) && match37(nameToken->linkAt(1)))
        endtok = nameToken->linkAt(1)->linkAt(1);
    else if (match38(nameToken->previous()))
        endtok = nameToken->linkAt(1);
    else
        return false;
    if (match39(nameToken))
        return false;
    if (match40(nameToken->previous()))
        return false;
    if (match41(nameToken) && !match42(nameToken)) {
        // If there is semicolon between {..} this is not a initlist
        for (const Token *tok2 = nameToken->next(); tok2 != endtok; tok2 = tok2->next()) {
            if (tok2->str() == MatchCompiler::makeConstString(";"))
                return false;
            const Token * lambdaEnd = findLambdaEndScope(tok2);
            if (lambdaEnd)
                tok2 = lambdaEnd;
        }
    }
    // There is no initialisation for example here: 'class Fred {};'
    if (!match43(endtok))
        return true;
    const Token *prev = nameToken;
    while (match44(prev)) {
        if (match45(prev))
            return false;

        prev = prev->previous();
    }
    return true;
}

static bool isQualifier(const Token* tok)
{
    while (match46(tok))
        tok = tok->next();
    if (!match47(tok))
        return false;
    return true;
}

static void compileUnaryOp(Token *&tok, AST_state& state, void (*f)(Token *&tok, AST_state& state))
{
    Token *unaryop = tok;
    if (f) {
        tok = tok->next();
        state.depth++;
        if (state.depth > AST_MAX_DEPTH)
            throw InternalError(tok, "maximum AST depth exceeded", InternalError::AST);
        if (tok)
            f(tok, state);
        state.depth--;
    }

    if (!state.op.empty()) {
        unaryop->astOperand1(state.op.top());
        state.op.pop();
    }
    state.op.push(unaryop);
}

static void compileBinOp(Token *&tok, AST_state& state, void (*f)(Token *&tok, AST_state& state))
{
    Token *binop = tok;
    if (f) {
        tok = tok->next();
        if (match48(binop))
            tok = tok->next();
        state.depth++;
        if (tok && state.depth <= AST_MAX_DEPTH)
            f(tok, state);
        state.depth--;
    }

    // TODO: Should we check if op is empty.
    // * Is it better to add assertion that it isn't?
    // * Write debug warning if it's empty?
    if (!state.op.empty()) {
        binop->astOperand2(state.op.top());
        state.op.pop();
    }
    if (!state.op.empty()) {
        binop->astOperand1(state.op.top());
        state.op.pop();
    }
    state.op.push(binop);
}

static void compileExpression(Token *&tok, AST_state& state);

static void compileTerm(Token *&tok, AST_state& state)
{
    if (!tok)
        return;
    if (match49(tok))
        tok = tok->next();
    if (state.inArrayAssignment && match50(tok->previous())) { // Jump over . in C style struct initialization
        state.op.push(tok);
        tok->astOperand1(tok->next());
        tok = tok->tokAt(2);
    }
    if (state.inArrayAssignment && match51(tok->previous())) {
        state.op.push(tok);
        tok->astOperand1(tok->next());
        tok = tok->tokAt(3);
    }
    if (tok->isLiteral()) {
        state.op.push(tok);
        do {
            tok = tok->next();
        } while (match52(tok));
    } else if (tok->isName()) {
        if (match53(tok) || (state.cpp && tok->str() == MatchCompiler::makeConstString("throw"))) {
            if (tok->str() == MatchCompiler::makeConstString("case"))
                state.inCase = true;
            const bool tokIsReturn = tok->str() == MatchCompiler::makeConstString("return");
            const bool stopAtColon = state.stopAtColon;
            state.stopAtColon=true;
            compileUnaryOp(tok, state, compileExpression);
            state.stopAtColon=stopAtColon;
            if (tokIsReturn)
                state.op.pop();
            if (state.inCase && match54(tok)) {
                state.inCase = false;
                tok = tok->next();
            }
        } else if (match55(tok)) {
            compileUnaryOp(tok, state, compileExpression);
            state.op.pop();
        } else if (state.cpp && findCppTypeInitPar(tok)) {  // int(0), int*(123), ..
            tok = findCppTypeInitPar(tok);
            state.op.push(tok);
            tok = tok->tokAt(2);
        } else if (state.cpp && iscpp11init(tok)) { // X{} X<Y>{} etc
            state.op.push(tok);
            tok = tok->next();
            if (tok->str() == MatchCompiler::makeConstString("<"))
                tok = tok->link()->next();

            if (match56(tok)) {
                const int inArrayAssignment = state.inArrayAssignment;
                state.inArrayAssignment = 1;
                compileBinOp(tok, state, compileExpression);
                state.inArrayAssignment = inArrayAssignment;
            } else if (match57(tok)) {
                tok->astOperand1(state.op.top());
                state.op.pop();
                state.op.push(tok);
                tok = tok->tokAt(2);
            }
        } else if (!state.cpp || !match58(tok)) {
            Token* tok2 = tok;
            tok = skipDecl(tok);
            if (match7(tok2)) {
                Token* tok3 = tok2->next();
                AST_state state1(state.cpp);
                compileExpression(tok3, state1);
            }
            bool repeat = true;
            while (repeat) {
                repeat = false;
                if (match59(tok->next())) {
                    tok = tok->next();
                    repeat = true;
                }
                if (match61(tok->next()) && match60(tok->linkAt(1))) {
                    tok = tok->next()->link()->next();
                    repeat = true;
                }
            }
            state.op.push(tok);
            if (match36(tok) && tok->linkAt(1))
                tok = tok->linkAt(1);
            else if (match62(tok))
                tok = tok->next();
            tok = tok->next();
            if (match63(tok)) {
                while (match52(tok))
                    tok = tok->next();
            }
            if (match64(tok))
                tok = tok->next();
        }
    } else if (tok->str() == MatchCompiler::makeConstString("{")) {
        const Token *prev = tok->previous();
        if (match20(prev) && iscast(prev->link(), state.cpp))
            prev = prev->link()->previous();
        if (match65(tok->link())) {
            tok = tok->next();
        } else if (state.cpp && iscpp11init(tok)) {
            if (state.op.empty() || match66(tok->previous()) || match67(tok->tokAt(-2))) {
                if (match68(tok)) {
                    Token *const end = tok->link();
                    if (match56(tok)) {
                        const int inArrayAssignment = state.inArrayAssignment;
                        state.inArrayAssignment = 1;
                        compileBinOp(tok, state, compileExpression);
                        state.inArrayAssignment = inArrayAssignment;
                    } else {
                        compileUnaryOp(tok, state, compileExpression);
                    }
                    if (precedes(tok,end))
                        tok = end;
                } else {
                    state.op.push(tok);
                    tok = tok->tokAt(2);
                }
            } else
                compileBinOp(tok, state, compileExpression);
            if (match69(tok))
                tok = tok->next();
        } else if (state.cpp && match38(tok->tokAt(-2)) && !findmatch70(tok, tok->link()) ) {
            if (match57(tok))
                tok = tok->tokAt(2);
            else {
                Token *tok1 = tok;
                state.inArrayAssignment++;
                compileUnaryOp(tok, state, compileExpression);
                state.inArrayAssignment--;
                tok = tok1->link()->next();
            }
        } else if (!state.inArrayAssignment && !match71(prev)) {
            state.op.push(tok);
            tok = tok->link()->next();
        } else {
            if (tok->link() != tok->next()) {
                state.inArrayAssignment++;
                compileUnaryOp(tok, state, compileExpression);
                if (match72(tok) && state.inArrayAssignment > 0) {
                    tok = tok->next();
                    state.inArrayAssignment--;
                }
            } else {
                state.op.push(tok);
                tok = tok->tokAt(2);
            }
        }
    }
}

static void compileScope(Token *&tok, AST_state& state)
{
    compileTerm(tok, state);
    while (tok) {
        if (tok->str() == MatchCompiler::makeConstString("::")) {
            const Token *lastOp = state.op.empty() ? nullptr : state.op.top();
            if (match73(lastOp))
                lastOp = lastOp->next();
            if (match59(lastOp) &&
                (lastOp->next() == tok || (match36(lastOp) && lastOp->linkAt(1) && tok == lastOp->linkAt(1)->next())))
                compileBinOp(tok, state, compileTerm);
            else
                compileUnaryOp(tok, state, compileTerm);
        } else break;
    }
}

static bool isPrefixUnary(const Token* tok, bool cpp)
{
    if (!tok->previous()
        || ((match74(tok->previous()) || (cpp && tok->strAt(-1) == MatchCompiler::makeConstString("throw")))
            && (tok->previous()->tokType() != Token::eIncDecOp || tok->tokType() == Token::eIncDecOp)))
        return true;

    if (tok->str() == MatchCompiler::makeConstString("*") && tok->previous()->tokType() == Token::eIncDecOp && isPrefixUnary(tok->previous(), cpp))
        return true;

    return tok->strAt(-1) == MatchCompiler::makeConstString(")") && iscast(tok->linkAt(-1), cpp);
}

static void compilePrecedence2(Token *&tok, AST_state& state)
{
    compileScope(tok, state);
    while (tok) {
        if (tok->tokType() == Token::eIncDecOp && !isPrefixUnary(tok, state.cpp)) {
            compileUnaryOp(tok, state, compileScope);
        } else if (tok->str() == MatchCompiler::makeConstString("...")) {
            state.op.push(tok);
            tok = tok->next();
            break;
        } else if (tok->str() == MatchCompiler::makeConstString(".") && tok->strAt(1) != MatchCompiler::makeConstString("*")) {
            if (tok->strAt(1) == MatchCompiler::makeConstString(".")) {
                state.op.push(tok);
                tok = tok->tokAt(3);
                break;
            }
            compileBinOp(tok, state, compileScope);
        } else if (tok->str() == MatchCompiler::makeConstString("[")) {
            if (state.cpp && isPrefixUnary(tok, state.cpp) && match75(tok->link())) { // Lambda
                // What we do here:
                // - Nest the round bracket under the square bracket.
                // - Nest what follows the lambda (if anything) with the lambda opening [
                // - Compile the content of the lambda function as separate tree (this is done later)
                // this must be consistent with isLambdaCaptureList
                Token* const squareBracket = tok;
                // Parse arguments in the capture list
                if (tok->strAt(1) != MatchCompiler::makeConstString("]")) {
                    Token* tok2 = tok->next();
                    AST_state state2(state.cpp);
                    compileExpression(tok2, state2);
                    if (!state2.op.empty()) {
                        squareBracket->astOperand2(state2.op.top());
                    }
                }

                if (match76(squareBracket->link())) {
                    Token* const roundBracket = squareBracket->link()->next();
                    Token* curlyBracket = roundBracket->link()->next();
                    while (match77(curlyBracket))
                        curlyBracket = curlyBracket->next();
                    if (match78(curlyBracket))
                        curlyBracket = curlyBracket->linkAt(1)->next();
                    if (curlyBracket && curlyBracket->originalName() == MatchCompiler::makeConstString("->"))
                        curlyBracket = findTypeEnd(curlyBracket->next());
                    if (curlyBracket && curlyBracket->str() == MatchCompiler::makeConstString("{")) {
                        squareBracket->astOperand1(roundBracket);
                        roundBracket->astOperand1(curlyBracket);
                        state.op.push(squareBracket);
                        tok = curlyBracket->link()->next();
                        continue;
                    }
                } else {
                    Token* const curlyBracket = squareBracket->link()->next();
                    squareBracket->astOperand1(curlyBracket);
                    state.op.push(squareBracket);
                    tok = curlyBracket->link()->next();
                    continue;
                }
            }

            const Token* const tok2 = tok;
            if (tok->strAt(1) != MatchCompiler::makeConstString("]"))
                compileBinOp(tok, state, compileExpression);
            else
                compileUnaryOp(tok, state, compileExpression);
            tok = tok2->link()->next();
        } else if (tok->str() == MatchCompiler::makeConstString("(") && (!iscast(tok, state.cpp) || match79(tok->previous()))) {
            Token* tok2 = tok;
            tok = tok->next();
            const bool opPrevTopSquare = !state.op.empty() && state.op.top() && state.op.top()->str() == MatchCompiler::makeConstString("[");
            const std::size_t oldOpSize = state.op.size();
            compileExpression(tok, state);
            tok = tok2;
            if ((oldOpSize > 0 && match80(tok->previous()))
                || (tok->previous() && tok->previous()->isName() && !match53(tok->previous()) && (!state.cpp || !match81(tok->previous())))
                || (tok->strAt(-1) == MatchCompiler::makeConstString("]") && (!state.cpp || !match82(tok->linkAt(-1)->previous())))
                || (tok->strAt(-1) == MatchCompiler::makeConstString(">") && tok->linkAt(-1))
                || (tok->strAt(-1) == MatchCompiler::makeConstString(")") && !iscast(tok->linkAt(-1), state.cpp)) // Don't treat brackets to clarify precedence as function calls
                || (tok->strAt(-1) == MatchCompiler::makeConstString("}") && opPrevTopSquare)) {
                const bool operandInside = oldOpSize < state.op.size();
                if (operandInside)
                    compileBinOp(tok, state, nullptr);
                else
                    compileUnaryOp(tok, state, nullptr);
            }
            tok = tok->link()->next();
        } else if (iscast(tok, state.cpp) && match20(tok->link()) && match65(tok->link()->linkAt(1))) {
            Token *cast = tok;
            tok = tok->link()->next();
            Token *tok1 = tok;
            compileUnaryOp(tok, state, compileExpression);
            cast->astOperand1(tok1);
            tok = tok1->link()->next();
        } else if (state.cpp && tok->str() == MatchCompiler::makeConstString("{") && iscpp11init(tok)) {
            if (match57(tok))
                compileUnaryOp(tok, state, compileExpression);
            else
                compileBinOp(tok, state, compileExpression);
            while (match83(tok))
                tok = tok->next();
        } else break;
    }
}

static void compilePrecedence3(Token *&tok, AST_state& state)
{
    compilePrecedence2(tok, state);
    while (tok) {
        if ((match84(tok) || tok->tokType() == Token::eIncDecOp) &&
            isPrefixUnary(tok, state.cpp)) {
            if (match85(tok)) {
                Token* tok2 = tok->next();
                while (tok2->next() && tok2->str() == MatchCompiler::makeConstString("*"))
                    tok2 = tok2->next();
                if (match86(tok2)) {
                    tok = tok2;
                    continue;
                }
            }
            compileUnaryOp(tok, state, compilePrecedence3);
        } else if (tok->str() == MatchCompiler::makeConstString("(") && iscast(tok, state.cpp)) {
            Token* castTok = tok;
            castTok->isCast(true);
            tok = tok->link()->next();
            const int inArrayAssignment = state.inArrayAssignment;
            if (tok && tok->str() == MatchCompiler::makeConstString("{"))
                state.inArrayAssignment = 1;
            compilePrecedence3(tok, state);
            state.inArrayAssignment = inArrayAssignment;
            compileUnaryOp(castTok, state, nullptr);
        } else if (state.cpp && match87(tok)) {
            Token* newtok = tok;
            tok = tok->next();
            bool innertype = false;
            if (tok->str() == MatchCompiler::makeConstString("(")) {
                if (match88(tok) && match89(tok->link()) && match18(tok->link()->linkAt(1)))
                    tok = tok->link()->next();
                if (match90(tok->link())) {
                    if (match91(tok)) {
                        Token *innerTok = tok->next();
                        AST_state innerState(true);
                        compileExpression(innerTok, innerState);
                    }
                    tok = tok->link()->next();
                } else if (match92(tok) && match93(tok->link())) {
                    tok = tok->next();
                    innertype = true;
                } else if (match88(tok) && match18(tok->link())) {
                    tok = tok->next();
                    innertype = true;
                } else {
                    /* bad code */
                    continue;
                }
            }

            Token* leftToken = tok;
            while (match73(tok->next())) {
                Token* scopeToken = tok->next(); //The ::
                scopeToken->astOperand1(leftToken);
                scopeToken->astOperand2(scopeToken->next());
                leftToken = scopeToken;
                tok = scopeToken->next();
            }

            state.op.push(tok);
            while (match94(tok)) {
                if (tok->link())
                    tok = tok->link();
                tok = tok->next();
            }
            if (match95(tok)) {
                state.op.push(tok->next());
                tok = tok->link()->next();
                compileBinOp(tok, state, compilePrecedence2);
            } else if (tok && (tok->str() == MatchCompiler::makeConstString("[") || tok->str() == MatchCompiler::makeConstString("(") || tok->str() == MatchCompiler::makeConstString("{")))
                compilePrecedence2(tok, state);
            else if (innertype && match96(tok)) {
                tok = tok->next();
                compilePrecedence2(tok, state);
            }
            compileUnaryOp(newtok, state, nullptr);
            if (innertype && match97(tok))
                tok = tok->next();
        } else if (state.cpp && match98(tok)) {
            Token* tok2 = tok;
            tok = tok->next();
            if (tok && tok->str() == MatchCompiler::makeConstString("["))
                tok = tok->link()->next();
            compilePrecedence3(tok, state);
            compileUnaryOp(tok2, state, nullptr);
        }
        // TODO: Handle sizeof
        else break;
    }
}

static void compilePointerToElem(Token *&tok, AST_state& state)
{
    compilePrecedence3(tok, state);
    while (tok) {
        if (match99(tok)) {
            compileBinOp(tok, state, compilePrecedence3);
        } else break;
    }
}

static void compileMulDiv(Token *&tok, AST_state& state)
{
    compilePointerToElem(tok, state);
    while (tok) {
        if (match100(tok) || (tok->str() == MatchCompiler::makeConstString("*") && !tok->astOperand1() && !isQualifier(tok))) {
            if (match85(tok)) {
                Token* tok2 = tok->next();
                while (tok2->next() && tok2->str() == MatchCompiler::makeConstString("*"))
                    tok2 = tok2->next();
                if (match86(tok2)) {
                    tok = tok2;
                    break;
                }
            }
            compileBinOp(tok, state, compilePointerToElem);
        } else break;
    }
}

static void compileAddSub(Token *&tok, AST_state& state)
{
    compileMulDiv(tok, state);
    while (tok) {
        if (match101(tok) && !tok->astOperand1()) {
            compileBinOp(tok, state, compileMulDiv);
        } else break;
    }
}

static void compileShift(Token *&tok, AST_state& state)
{
    compileAddSub(tok, state);
    while (tok) {
        if (match102(tok)) {
            compileBinOp(tok, state, compileAddSub);
        } else break;
    }
}

static void compileThreewayComp(Token *&tok, AST_state& state)
{
    compileShift(tok, state);
    while (tok) {
        if (tok->str() == MatchCompiler::makeConstString("<=>")) {
            compileBinOp(tok, state, compileShift);
        } else break;
    }
}

static void compileRelComp(Token *&tok, AST_state& state)
{
    compileThreewayComp(tok, state);
    while (tok) {
        if (match103(tok) && !tok->link()) {
            compileBinOp(tok, state, compileThreewayComp);
        } else break;
    }
}

static void compileEqComp(Token *&tok, AST_state& state)
{
    compileRelComp(tok, state);
    while (tok) {
        if (match104(tok)) {
            compileBinOp(tok, state, compileRelComp);
        } else break;
    }
}

static void compileAnd(Token *&tok, AST_state& state)
{
    compileEqComp(tok, state);
    while (tok) {
        if (tok->str() == MatchCompiler::makeConstString("&") && !tok->astOperand1() && !isQualifier(tok)) {
            Token* tok2 = tok->next();
            if (!tok2)
                break;
            if (tok2->str() == MatchCompiler::makeConstString("&"))
                tok2 = tok2->next();
            if (state.cpp && match105(tok2)) {
                tok = tok2;
                break; // rValue reference
            }
            compileBinOp(tok, state, compileEqComp);
        } else break;
    }
}

static void compileXor(Token *&tok, AST_state& state)
{
    compileAnd(tok, state);
    while (tok) {
        if (tok->str() == MatchCompiler::makeConstString("^")) {
            compileBinOp(tok, state, compileAnd);
        } else break;
    }
}

static void compileOr(Token *&tok, AST_state& state)
{
    compileXor(tok, state);
    while (tok) {
        if (tok->str() == MatchCompiler::makeConstString("|")) {
            compileBinOp(tok, state, compileXor);
        } else break;
    }
}

static void compileLogicAnd(Token *&tok, AST_state& state)
{
    compileOr(tok, state);
    while (tok) {
        if (tok->str() == MatchCompiler::makeConstString("&&") && !isQualifier(tok)) {
            if (!tok->astOperand1()) {
                Token* tok2 = tok->next();
                if (!tok2)
                    break;
                if (state.cpp && match105(tok2)) {
                    tok = tok2;
                    break; // rValue reference
                }
            }
            compileBinOp(tok, state, compileOr);
        } else break;
    }
}

static void compileLogicOr(Token *&tok, AST_state& state)
{
    compileLogicAnd(tok, state);
    while (tok) {
        if (tok->str() == MatchCompiler::makeConstString("||")) {
            compileBinOp(tok, state, compileLogicAnd);
        } else break;
    }
}

static void compileAssignTernary(Token *&tok, AST_state& state)
{
    compileLogicOr(tok, state);
    while (tok) {
        if (tok->isAssignmentOp()) {
            state.assign++;
            const Token *tok1 = tok->next();
            compileBinOp(tok, state, compileAssignTernary);
            if (match31(tok1) && tok == tok1->link() && tok->next())
                tok = tok->next();
            if (state.assign > 0)
                state.assign--;
        } else if (tok->str() == MatchCompiler::makeConstString("?")) {
            // http://en.cppreference.com/w/cpp/language/operator_precedence says about ternary operator:
            //       "The expression in the middle of the conditional operator (between ? and :) is parsed as if parenthesized: its precedence relative to ?: is ignored."
            // Hence, we rely on Tokenizer::prepareTernaryOpForAST() to add such parentheses where necessary.
            const bool stopAtColon = state.stopAtColon;
            state.stopAtColon = false;
            if (tok->strAt(1) == MatchCompiler::makeConstString(":")) {
                state.op.push(nullptr);
            }
            const int assign = state.assign;
            state.assign = 0;
            compileBinOp(tok, state, compileAssignTernary);
            state.assign = assign;
            state.stopAtColon = stopAtColon;
        } else if (tok->str() == MatchCompiler::makeConstString(":")) {
            if (state.depth == 1U && state.inCase) {
                state.inCase = false;
                tok = tok->next();
                break;
            }
            if (state.stopAtColon)
                break;
            if (state.assign > 0)
                break;
            compileBinOp(tok, state, compileAssignTernary);
        } else break;
    }
}

static void compileComma(Token *&tok, AST_state& state)
{
    compileAssignTernary(tok, state);
    while (tok) {
        if (tok->str() == MatchCompiler::makeConstString(",")) {
            if (match106(tok))
                tok = tok->next();
            else
                compileBinOp(tok, state, compileAssignTernary);
        } else if (tok->str() == MatchCompiler::makeConstString(";") && state.functionCallEndPar && tok->index() < state.functionCallEndPar->index()) {
            compileBinOp(tok, state, compileAssignTernary);
        } else break;
    }
}

static void compileExpression(Token *&tok, AST_state& state)
{
    if (state.depth > AST_MAX_DEPTH)
        throw InternalError(tok, "maximum AST depth exceeded", InternalError::AST); // ticket #5592
    if (tok)
        compileComma(tok, state);
}

static bool isLambdaCaptureList(const Token * tok)
{
    // a lambda expression '[x](y){}' is compiled as:
    // [
    // `-(  <<-- optional
    //   `-{
    // see compilePrecedence2
    if (tok->str() != MatchCompiler::makeConstString("["))
        return false;
    if (!match75(tok->link()))
        return false;
    if (match31(tok->astOperand1()) && tok->astOperand1() == tok->link()->next())
        return true;
    if (!tok->astOperand1() || tok->astOperand1()->str() != MatchCompiler::makeConstString("("))
        return false;
    const Token * params = tok->astOperand1();
    if (!params->astOperand1() || params->astOperand1()->str() != MatchCompiler::makeConstString("{"))
        return false;
    return true;
}

static Token * createAstAtToken(Token *tok, bool cpp);

// Compile inner expressions inside inner ({..}) and lambda bodies
static void createAstAtTokenInner(Token * const tok1, const Token *endToken, bool cpp)
{
    for (Token* tok = tok1; precedes(tok, endToken); tok = tok ? tok->next() : nullptr) {
        if (tok->str() == MatchCompiler::makeConstString("{") && !iscpp11init(tok)) {
            const Token * const endToken2 = tok->link();
            bool hasAst = false;
            for (const Token *inner = tok->next(); inner != endToken2; inner = inner->next()) {
                if (inner->astOperand1()) {
                    hasAst = true;
                    break;
                }
                if (tok->isConstOp())
                    break;
                if (inner->str() == MatchCompiler::makeConstString("{"))
                    inner = inner->link();
            }
            if (!hasAst) {
                for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr)
                    tok = createAstAtToken(tok, cpp);
            }
        } else if (cpp && tok->str() == MatchCompiler::makeConstString("[")) {
            if (isLambdaCaptureList(tok)) {
                tok = tok->astOperand1();
                if (tok->str() == MatchCompiler::makeConstString("("))
                    tok = tok->astOperand1();
                const Token * const endToken2 = tok->link();
                tok = tok->next();
                for (; tok && tok != endToken && tok != endToken2; tok = tok ? tok->next() : nullptr)
                    tok = createAstAtToken(tok, cpp);
            }
        }
    }
}

static Token * findAstTop(Token *tok1, Token *tok2)
{
    for (Token *tok = tok1; tok && (tok != tok2); tok = tok->next()) {
        if (tok->astParent() || tok->astOperand1() || tok->astOperand2()) {
            while (tok->astParent() && tok->astParent()->index() >= tok1->index() && tok->astParent()->index() <= tok2->index())
                tok = tok->astParent();
            return tok;
        }
        if (match107(tok))
            tok = tok->link();
    }
    for (Token *tok = tok1; tok && (tok != tok2); tok = tok->next()) {
        if (tok->isName() || tok->isNumber())
            return tok;
        if (match107(tok))
            tok = tok->link();
    }
    return nullptr;
}

static Token * createAstAtToken(Token *tok, bool cpp)
{
    if (match108(tok)) {
        if (cpp && match109(tok)) {
            Token *decl = findmatch110(tok) ;
            if (match111(decl->link())) {
                AST_state state1(cpp);
                while (decl->str() != MatchCompiler::makeConstString("]")) {
                    if (match112(decl)) {
                        state1.op.push(decl);
                    } else if (decl->str() == MatchCompiler::makeConstString(",")) {
                        if (!state1.op.empty()) {
                            decl->astOperand1(state1.op.top());
                            state1.op.pop();
                        }
                        if (!state1.op.empty()) {
                            state1.op.top()->astOperand2(decl);
                            state1.op.pop();
                        }
                        state1.op.push(decl);
                    }
                    decl = decl->next();
                }
                if (state1.op.size() > 1) {
                    Token *lastName = state1.op.top();
                    state1.op.pop();
                    state1.op.top()->astOperand2(lastName);
                }
                decl = decl->next();

                Token *colon = decl;
                compileExpression(decl, state1);

                tok->next()->astOperand1(tok);
                tok->next()->astOperand2(colon);

                return decl;
            }
        }

        Token *tok2 = skipDecl(tok->tokAt(2));
        if (match7(tok->tokAt(2))) {
            Token* tok3 = tok->tokAt(4);
            AST_state state1(cpp);
            compileExpression(tok3, state1);
        }
        Token *init1 = nullptr;
        Token * const endPar = tok->next()->link();
        if (tok2 == tok->tokAt(2) && match113(tok2)) {
            init1 = tok2;
            AST_state state1(cpp);
            compileExpression(tok2, state1);
            if (match114(init1)) {
                for (Token *tok3 = init1; tok3 != tok3->link(); tok3 = tok3->next()) {
                    if (tok3->astParent()) {
                        while (tok3->astParent())
                            tok3 = tok3->astParent();
                        init1 = tok3;
                        break;
                    }
                    if (!match115(tok3))
                        init1 = tok3;
                }
            }
        } else {
            while (tok2 && tok2 != endPar && tok2->str() != MatchCompiler::makeConstString(";")) {
                if (tok2->str() == MatchCompiler::makeConstString("<") && tok2->link()) {
                    tok2 = tok2->link();
                } else if (match116(tok2) || match117(tok2->previous())) {
                    init1 = tok2;
                    AST_state state1(cpp);
                    compileExpression(tok2, state1);
                    if (match118(tok2))
                        break;
                    init1 = nullptr;
                }
                if (!tok2) // #7109 invalid code
                    return nullptr;
                tok2 = tok2->next();
            }
        }
        if (!tok2 || tok2->str() != MatchCompiler::makeConstString(";")) {
            if (tok2 == endPar && init1) {
                tok->next()->astOperand2(init1);
                tok->next()->astOperand1(tok);
            }
            return tok2;
        }

        Token * const init = init1 ? init1 : tok2;

        Token * const semicolon1 = tok2;
        tok2 = tok2->next();
        AST_state state2(cpp);
        compileExpression(tok2, state2);

        Token * const semicolon2 = tok2;
        if (!semicolon2)
            return nullptr; // invalid code #7235

        if (semicolon2->str() == MatchCompiler::makeConstString(";")) {
            tok2 = tok2->next();
            AST_state state3(cpp);
            if (match107(tok2)) {
                state3.op.push(tok2->next());
                tok2 = tok2->link()->next();
            }
            compileExpression(tok2, state3);

            tok2 = findAstTop(semicolon1->next(), semicolon2);
            if (tok2)
                semicolon2->astOperand1(tok2);
            tok2 = findAstTop(semicolon2->next(), endPar);
            if (tok2)
                semicolon2->astOperand2(tok2);
            else if (!state3.op.empty())
                semicolon2->astOperand2(state3.op.top());
            semicolon1->astOperand2(semicolon2);
        } else {
            if (!cpp || !match119(state2.op.top()))
                throw InternalError(tok, "syntax error", InternalError::SYNTAX);

            semicolon1->astOperand2(state2.op.top());
        }

        if (init != semicolon1)
            semicolon1->astOperand1(init->astTop());
        tok->next()->astOperand1(tok);
        tok->next()->astOperand2(semicolon1);

        createAstAtTokenInner(endPar->link(), endPar, cpp);

        return endPar;
    }

    if (match107(tok))
        return tok;

    if (match120(tok) && tok->linkAt(1) && !match121(tok->linkAt(1)))
        return tok->linkAt(1);

    if (cpp && match122(tok)) {
        Token *tok2 = tok;
        while (true) {
            if (match123(tok2))
                tok2 = tok2->tokAt(2);
            else if (match36(tok2) && tok2->linkAt(1))
                tok2 = tok2->linkAt(1);
            else
                break;
        }
        if (match124(tok2) && tok2->next()->varId() && iscpp11init(tok2->tokAt(2))) {
            Token *const tok1 = tok = tok2->next();
            AST_state state(cpp);
            compileExpression(tok, state);
            createAstAtTokenInner(tok1->next(), tok1->linkAt(1), cpp);
            return tok;
        }
    }

    if (match125(tok) && tok->str() != MatchCompiler::makeConstString("return")) {
        int typecount = 0;
        Token *typetok = tok;
        while (match126(typetok)) {
            if (typetok->isName() && !match127(typetok->previous()))
                typecount++;
            typetok = typetok->next();
        }
        if (match128(typetok) && typetok->varId())
            tok = typetok;

        // Do not create AST for function declaration
        if (typetok &&
            typecount >= 2 &&
            !match129(tok) &&
            match67(typetok->previous()) &&
            typetok->previous()->varId() == 0 &&
            !typetok->previous()->isKeyword() &&
            match130(typetok->link()))
            return typetok;
    }

    if (match53(tok) ||
        (cpp && tok->str() == MatchCompiler::makeConstString("throw")) ||
        !tok->previous() ||
        match131(tok) ||
        (cpp && match132(tok) && iscpp11init(tok->next())) ||
        match133(tok->previous()) ||
        match134(tok->previous())) {
        if (cpp && (match135(tok->tokAt(-2)) || match136(tok->tokAt(-3))))
            tok = tok->previous();

        Token * const tok1 = tok;
        AST_state state(cpp);
        if (match67(tok))
            state.functionCallEndPar = tok->linkAt(1);
        compileExpression(tok, state);
        const Token * const endToken = tok;
        if (endToken == tok1 || !endToken)
            return tok1;

        createAstAtTokenInner(tok1->next(), endToken, cpp);

        return endToken->previous();
    }

    if (cpp && tok->str() == MatchCompiler::makeConstString("{") && iscpp11init(tok)) {
        Token * const tok1 = tok;
        AST_state state(cpp);
        compileExpression(tok, state);
        const Token * const endToken = tok;
        if (endToken == tok1 || !endToken)
            return tok1;

        createAstAtTokenInner(tok1->next(), endToken, cpp);
        return endToken->previous();
    }

    return tok;
}

void TokenList::createAst() const
{
    for (Token *tok = mTokensFrontBack.front; tok; tok = tok ? tok->next() : nullptr) {
        tok = createAstAtToken(tok, isCPP());
    }
}

struct OnException {
    std::function<void()> f;

    ~OnException() {
#ifndef _MSC_VER
        if (std::uncaught_exception())
            f();
#endif
    }
};

void TokenList::validateAst() const
{
    OnException oe{[&] {
            if (mSettings->debugnormal)
                mTokensFrontBack.front->printOut();
        }};
    // Check for some known issues in AST to avoid crash/hang later on
    std::set<const Token*> safeAstTokens;    // list of "safe" AST tokens without endless recursion
    for (const Token *tok = mTokensFrontBack.front; tok; tok = tok->next()) {
        // Syntax error if binary operator only has 1 operand
        if ((tok->isAssignmentOp() || tok->isComparisonOp() || match137(tok)) && tok->astOperand1() && !tok->astOperand2())
            throw InternalError(tok, "Syntax Error: AST broken, binary operator has only one operand.", InternalError::AST);

        // Syntax error if we encounter "?" with operand2 that is not ":"
        if (tok->str() == MatchCompiler::makeConstString("?")) {
            if (!tok->astOperand1() || !tok->astOperand2())
                throw InternalError(tok, "AST broken, ternary operator missing operand(s)", InternalError::AST);
            else if (tok->astOperand2()->str() != MatchCompiler::makeConstString(":"))
                throw InternalError(tok, "Syntax Error: AST broken, ternary operator lacks ':'.", InternalError::AST);
        }

        // Check for endless recursion
        const Token* parent = tok->astParent();
        if (parent) {
            std::set<const Token*> astTokens;    // list of ancestors
            astTokens.insert(tok);
            do {
                if (safeAstTokens.find(parent) != safeAstTokens.end())
                    break;
                if (astTokens.find(parent) != astTokens.end())
                    throw InternalError(tok, "AST broken: endless recursion from '" + tok->str() + "'", InternalError::AST);
                astTokens.insert(parent);
            } while ((parent = parent->astParent()) != nullptr);
            safeAstTokens.insert(astTokens.begin(), astTokens.end());
        } else if (tok->str() == MatchCompiler::makeConstString(";")) {
            safeAstTokens.clear();
        } else {
            safeAstTokens.insert(tok);
        }

        // Don't check templates
        if (tok->str() == MatchCompiler::makeConstString("<") && tok->link()) {
            tok = tok->link();
            continue;
        }

        // Check binary operators
        if (match138(tok)) {
            // Skip lambda captures
            if (match139(tok))
                continue;
            // Skip pure virtual functions
            if (match140(tok->previous()))
                continue;
            // Skip operator definitions
            if (match141(tok->previous()))
                continue;
            // Skip incomplete code
            if (!tok->astOperand1() && !tok->astOperand2() && !tok->astParent())
                continue;
            // Skip lambda assignment and/or initializer
            if (match142(tok))
                continue;
            // FIXME: Workaround broken AST assignment in type aliases
            if (match143(tok->previous()))
                continue;
            if (!tok->astOperand1() || !tok->astOperand2())
                throw InternalError(tok, "Syntax Error: AST broken, binary operator '" + tok->str() + "' doesn't have two operands.", InternalError::AST);
        }

        // Check control blocks and asserts
        if (match144(tok->previous())) {
            if (!tok->astOperand1() || !tok->astOperand2())
                throw InternalError(tok,
                                    "Syntax Error: AST broken, '" + tok->previous()->str() +
                                    "' doesn't have two operands.",
                                    InternalError::AST);
        }

        // Check member access
        if (match145(tok)) {
            if (!tok->astParent()) {
                throw InternalError(
                          tok, "Syntax Error: AST broken, '" + tok->str() + "' doesn't have a parent.", InternalError::AST);
            }
            if (!tok->next()->astOperand1() || !tok->next()->astOperand2()) {
                const std::string& op =
                    tok->next()->originalName().empty() ? tok->next()->str() : tok->next()->originalName();
                throw InternalError(
                          tok, "Syntax Error: AST broken, '" + op + "' doesn't have two operands.", InternalError::AST);
            }
        }
    }
}

std::string TokenList::getOrigFile(const Token *tok) const
{
    return mOrigFiles.at(tok->fileIndex());
}

const std::string& TokenList::file(const Token *tok) const
{
    return mFiles.at(tok->fileIndex());
}

std::string TokenList::fileLine(const Token *tok) const
{
    return ErrorMessage::FileLocation(tok, this).stringify();
}

bool TokenList::validateToken(const Token* tok) const
{
    if (!tok)
        return true;
    for (const Token *t = mTokensFrontBack.front; t; t = t->next()) {
        if (tok==t)
            return true;
    }
    return false;
}

void TokenList::simplifyPlatformTypes()
{
    const bool isCPP11  = mSettings->standards.cpp >= Standards::CPP11;

    enum { isLongLong, isLong, isInt } type;

    /** @todo This assumes a flat address space. Not true for segmented address space (FAR *). */

    if (mSettings->sizeof_size_t == mSettings->sizeof_long)
        type = isLong;
    else if (mSettings->sizeof_size_t == mSettings->sizeof_long_long)
        type = isLongLong;
    else if (mSettings->sizeof_size_t == mSettings->sizeof_int)
        type = isInt;
    else
        return;

    for (Token *tok = front(); tok; tok = tok->next()) {
        // pre-check to reduce unneeded match calls
        if (!match146(tok))
            continue;
        bool isUnsigned;
        if (match147(tok)) {
            if (isCPP11 && tok->strAt(-1) == MatchCompiler::makeConstString("using") && tok->strAt(1) == MatchCompiler::makeConstString("="))
                continue;
            isUnsigned = true;
        } else if (match148(tok)) {
            if (isCPP11 && tok->strAt(-1) == MatchCompiler::makeConstString("using") && tok->strAt(1) == MatchCompiler::makeConstString("="))
                continue;
            isUnsigned = false;
        } else
            continue;

        bool inStd = false;
        if (tok->str() == MatchCompiler::makeConstString("::")) {
            tok->deleteThis();
        } else if (tok->str() == MatchCompiler::makeConstString("std")) {
            if (tok->next()->str() != MatchCompiler::makeConstString("::"))
                continue;
            inStd = true;
            tok->deleteNext();
            tok->deleteThis();
        }

        if (inStd)
            tok->originalName("std::" + tok->str());
        else
            tok->originalName(tok->str());
        if (isUnsigned)
            tok->isUnsigned(true);

        switch (type) {
        case isLongLong:
            tok->isLong(true);
            tok->str("long");
            break;
        case isLong:
            tok->str("long");
            break;
        case isInt:
            tok->str("int");
            break;
        }
    }

    const std::string platform_type(mSettings->platformString());

    for (Token *tok = front(); tok; tok = tok->next()) {
        if (tok->tokType() != Token::eType && tok->tokType() != Token::eName)
            continue;

        const Library::PlatformType * const platformtype = mSettings->library.platform_type(tok->str(), platform_type);

        if (platformtype) {
            // check for namespace
            if (tok->strAt(-1) == MatchCompiler::makeConstString("::")) {
                const Token * tok1 = tok->tokAt(-2);
                // skip when non-global namespace defined
                if (tok1 && tok1->tokType() == Token::eName)
                    continue;
                tok = tok->previous();
                tok->deleteThis();
            }
            Token *typeToken;
            if (platformtype->mConstPtr) {
                tok->str("const");
                tok->insertToken("*");
                tok->insertToken(platformtype->mType);
                typeToken = tok;
            } else if (platformtype->mPointer) {
                tok->str(platformtype->mType);
                typeToken = tok;
                tok->insertToken("*");
            } else if (platformtype->mPtrPtr) {
                tok->str(platformtype->mType);
                typeToken = tok;
                tok->insertToken("*");
                tok->insertToken("*");
            } else {
                tok->originalName(tok->str());
                tok->str(platformtype->mType);
                typeToken = tok;
            }
            if (platformtype->mSigned)
                typeToken->isSigned(true);
            if (platformtype->mUnsigned)
                typeToken->isUnsigned(true);
            if (platformtype->mLong)
                typeToken->isLong(true);
        }
    }
}

void TokenList::simplifyStdType()
{
    for (Token *tok = front(); tok; tok = tok->next()) {

        if (match149(tok) && (!tok->previous() || match150(tok->previous()))) {
            if (match151(tok->next()))
                continue;

            tok->insertToken("int");
            tok->next()->isImplicitInt(true);
            continue;
        }

        if (match152(tok) || (mSettings->standards.c >= Standards::C99 && match153(tok))) {
            bool isFloat= false;
            bool isSigned = false;
            bool isUnsigned = false;
            bool isComplex = false;
            int countLong = 0;
            Token* typeSpec = nullptr;

            Token* tok2 = tok;
            for (; tok2->next(); tok2 = tok2->next()) {
                if (tok2->str() == MatchCompiler::makeConstString("long")) {
                    countLong++;
                    if (!isFloat)
                        typeSpec = tok2;
                } else if (tok2->str() == MatchCompiler::makeConstString("short")) {
                    typeSpec = tok2;
                } else if (tok2->str() == MatchCompiler::makeConstString("unsigned"))
                    isUnsigned = true;
                else if (tok2->str() == MatchCompiler::makeConstString("signed"))
                    isSigned = true;
                else if (match154(tok2)) {
                    isFloat = true;
                    typeSpec = tok2;
                } else if (mSettings->standards.c >= Standards::C99 && match153(tok2))
                    isComplex = !isFloat || tok2->str() == MatchCompiler::makeConstString("_Complex") || match155(tok2->next()); // Ensure that "complex" is not the variables name
                else if (match156(tok2)) {
                    if (!typeSpec)
                        typeSpec = tok2;
                } else
                    break;
            }

            if (!typeSpec) { // unsigned i; or similar declaration
                if (!isComplex) { // Ensure that "complex" is not the variables name
                    tok->str("int");
                    tok->isSigned(isSigned);
                    tok->isUnsigned(isUnsigned);
                    tok->isImplicitInt(true);
                }
            } else {
                typeSpec->isLong(typeSpec->isLong() || (isFloat && countLong == 1) || countLong > 1);
                typeSpec->isComplex(typeSpec->isComplex() || (isFloat && isComplex));
                typeSpec->isSigned(typeSpec->isSigned() || isSigned);
                typeSpec->isUnsigned(typeSpec->isUnsigned() || isUnsigned);

                // Remove specifiers
                const Token* tok3 = tok->previous();
                tok2 = tok2->previous();
                while (tok3 != tok2) {
                    if (tok2 != typeSpec &&
                        (isComplex || !match153(tok2)))  // Ensure that "complex" is not the variables name
                        tok2->deleteThis();
                    tok2 = tok2->previous();
                }
            }
        }
    }
}

bool TokenList::isKeyword(const std::string &str) const
{
    return mKeywords.find(str) != mKeywords.end();
}
