ActionsAndRules.h
#ifndef ACTIONSANDRULES_H
#define ACTIONSANDRULES_H
#include <queue>
#include <string>
#include <sstream>
#include <iomanip>
#include "Parser.h"
#include "../GrammarHelpers/GrammarHelpers.h"
#include "../SemiExpression/ITokenCollection.h"
#include "../ScopeStack/ScopeStack.h"
#include "../Tokenizer/Toker.h"
#include "../SemiExpression/Semi.h"
#include "../AbstractSyntaxTree/AbstrSynTree.h"
#include "../Logger/Logger.h"
#include "../FileSystem/FileSystem.h"
namespace CodeAnalysis
{
enum Language { C , Cpp, CSharp };
class Repository {
public:
using Rslt = Logging::StaticLogger<0>; using Package = std::string;
using Path = std::string;
private:
Language language_ = Language::Cpp;
Path path_;
ScopeStack<ASTNode*> stack;
AbstrSynTree ast;
ASTNode* pGlobalScope;
Package package_;
Lexer::Toker* p_Toker;
Access currentAccess_ = Access::publ;
static Repository* instance;
public:
Repository(Lexer::Toker* pToker) : ast(stack)
{
p_Toker = pToker;
pGlobalScope = stack.top(); instance = this;
}
~Repository()
{
Dbug::write("\n deleting repository");
}
Language& language() { return language_; }
Package& package() { return package_; }
Path& currentPath() { return path_; }
Access& currentAccess() { return currentAccess_; }
static Repository* getInstance() { return instance; }
ScopeStack<ASTNode*>& scopeStack() { return stack; }
AbstrSynTree& AST() { return ast; }
ASTNode* getGlobalScope() { return pGlobalScope; }
Lexer::Toker* Toker() { return p_Toker; }
size_t lineCount()
{
return (size_t)(p_Toker->lineCount());
}
};
class BeginScope : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Test begin scope", *pTc);
if (pTc->size() == 1 && (*pTc)[0] == ";")
return IRule::Stop;
if (pTc->contains("{"))
{
doActions(pTc);
}
return IRule::Continue;
}
};
class HandleBeginScope : public IAction
{
Repository* p_Repos;
public:
HandleBeginScope(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("handle begin scope", *pTc);
ASTNode* pElem = new ASTNode;
pElem->type_ = "anonymous";
pElem->name_ = "none";
pElem->package_ = p_Repos->package();
pElem->startLineCount_ = p_Repos->lineCount();
pElem->endLineCount_ = 1;
pElem->path_ = p_Repos->currentPath();
p_Repos->AST().add(pElem);
}
};
class EndScope : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Test end scope", *pTc);
size_t posCloseBrace;
pTc->find("}", posCloseBrace);
if (posCloseBrace < pTc->size())
{
doActions(pTc);
return IRule::Stop;
}
return IRule::Continue;
}
};
class HandleEndScope : public IAction
{
Repository* p_Repos;
public:
using Dbug = Logging::StaticLogger<2>;
HandleEndScope(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle end scope", *pTc);
if (p_Repos->scopeStack().size() == 0)
return;
ASTNode* pElem = p_Repos->AST().pop();
if (pElem == nullptr)
return;
pElem->endLineCount_ = p_Repos->lineCount();
if (pElem->type_ == "class" || pElem->type_ == "struct")
(pElem->endLineCount_)++;
p_Repos->currentAccess() = Access::priv;
}
};
class DetectAccessSpecifier : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Test access spec", *pTc);
Repository* pRepo = Repository::getInstance();
if (pRepo->language() != Language::Cpp)
return IRule::Continue;
size_t pos;
pTc->find(":", pos);
if (0 < pos && pos < pTc->size())
{
const std::string tok = (*pTc)[pos - 1];
if (tok == "public" || tok == "protected" || tok == "private")
{
doActions(pTc);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleAccessSpecifier : public IAction
{
Repository* p_Repos;
public:
HandleAccessSpecifier(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle access spec: ", *pTc);
std::string tok = (*pTc)[pTc->size() - 2];
Access& access = p_Repos->currentAccess();
if (tok == "public")
access = Access::publ;
else if (tok == "protected")
access = Access::prot;
else
access = Access::priv;
}
};
class PreprocStatement : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Test preproc statement: ", *pTc);
size_t pPos;
pTc->find("#", pPos);
if (pPos < pTc->size())
{
doActions(pTc);
return IRule::Stop;
}
return IRule::Continue;
}
};
class HandlePreprocStatement : public IAction
{
Repository* p_Repos;
public:
HandlePreprocStatement(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle preproc statement: ", *pTc);
Lexer::ITokenCollection* pClone = pTc->clone();
if (p_Repos->scopeStack().size() == 0)
return;
ASTNode* pElem = p_Repos->scopeStack().top();
pElem->statements_.push_back(pClone);
GrammarHelper::showParse("Preproc Stmt", *pTc);
}
};
class NamespaceDefinition : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Test namespace definition: ", *pTc);
const Lexer::ITokenCollection& tc = *pTc;
if (tc[tc.size() - 1] == "{")
{
size_t len;
tc.find("namespace", len);
if (len < tc.size())
{
doActions(pTc);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleNamespaceDefinition : public IAction
{
Repository* p_Repos;
public:
HandleNamespaceDefinition(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle namespace definition: ", *pTc);
if (p_Repos->scopeStack().size() == 0)
return;
ASTNode* top = p_Repos->scopeStack().top();
size_t pos;
pTc->find("namespace", pos);
std::string name = (*pTc)[pos + 1];
top->type_ = "namespace";
top->name_ = name;
top->package_ = p_Repos->package();
GrammarHelper::showParse("namespace def", *pTc);
}
};
class ClassDefinition : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Test class definition: ", *pTc);
const Lexer::ITokenCollection& tc = *pTc;
if (tc[tc.size() - 1] == "{")
{
size_t len;
tc.find("class", len);
if (len < tc.size())
{
doActions(pTc);
return IRule::Stop;
}
if (tc.contains("interface"))
{
doActions(pTc);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleClassDefinition : public IAction
{
Repository* p_Repos;
public:
HandleClassDefinition(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle class definition: ", *pTc);
p_Repos->currentAccess() = Access::priv;
if (p_Repos->scopeStack().size() == 0)
return;
ASTNode* top = p_Repos->scopeStack().top();
size_t typeIndex;
pTc->find("class", typeIndex);
if (typeIndex < pTc->size())
{
size_t nameIndex = typeIndex + 1;
std::string name = (*pTc)[nameIndex];
top->type_ = "class";
top->name_ = name;
top->package_ = p_Repos->package();
p_Repos->AST().typeMap()[name] = top;
GrammarHelper::showParse("class def", *pTc);
}
else {
pTc->find("interface", typeIndex);
size_t nameIndex = typeIndex + 1;
std::string name = (*pTc)[nameIndex];
top->type_ = "interface";
top->name_ = name;
top->package_ = p_Repos->package();
p_Repos->AST().typeMap()[name] = top;
GrammarHelper::showParse("interface def", *pTc);
}
}
};
class StructDefinition : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Test struct definition: ", *pTc);
const Lexer::ITokenCollection& tc = *pTc;
if (tc[tc.size() - 1] == "{")
{
size_t len;
tc.find("struct", len);
if (len < tc.size())
{
doActions(pTc);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleStructDefinition : public IAction
{
Repository* p_Repos;
public:
HandleStructDefinition(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle struct definition: ", *pTc);
p_Repos->currentAccess() = Access::publ;
if (p_Repos->scopeStack().size() == 0)
return;
ASTNode* top = p_Repos->scopeStack().top();
size_t pos;
pTc->find("struct", pos);
std::string name = (*pTc)[pos + 1];
top->type_ = "struct";
top->name_ = name;
top->package_ = p_Repos->package();
p_Repos->AST().typeMap()[name] = top;
GrammarHelper::showParse("struct def", *pTc);
}
};
class CppFunctionDefinition : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
Repository* pRepo = Repository::getInstance();
if (pRepo->language() != Language::Cpp)
return IRule::Continue;
GrammarHelper::showParseDemo("Test C++ function definition: ", *pTc);
ScopeStack<ASTNode*>& stack = pRepo->scopeStack();
if (stack.size() < 2)
return IRule::Continue;
std::string parentType = stack.predOfTop()->type_;
if (parentType != "namespace" && parentType != "class" && parentType != "struct")
return IRule::Continue;
const Lexer::ITokenCollection& tc = *pTc;
if (tc[tc.size() - 1] == "{")
{
if (GrammarHelper::isFunction(*pTc))
{
doActions(pTc);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleCppFunctionDefinition : public IAction
{
Repository* p_Repos;
public:
HandleCppFunctionDefinition(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle C++ function definition: ", *pTc);
ScopeStack<ASTNode*>& stack = p_Repos->scopeStack();
if (stack.size() == 0)
return;
ASTNode* top = stack.top();
size_t nameIndex;
if(pTc->find("(", nameIndex))
--nameIndex;
else return;
std::string name = (*pTc)[nameIndex];
if (nameIndex > 0 && (*pTc)[nameIndex - 1] == "~")
{
--nameIndex;
name = "~" + name;
}
top->type_ = "function";
top->name_ = name;
top->package_ = p_Repos->package();
GrammarHelper::showParse("function def", *pTc);
size_t operIndex;
pTc->find("operator", operIndex);
if (operIndex < pTc->size())
{
name = "operator" + (*pTc)[operIndex + 1]; if ((*pTc)[operIndex + 2] != "(")
name += (*pTc)[operIndex + 2];
top->name_ = name;
nameIndex = operIndex;
}
if (nameIndex > 1 && (*pTc)[nameIndex - 1] == "::")
{
std::string className = (*pTc)[nameIndex - 2];
if (className == ">")
{
size_t startParam = GrammarHelper::findLast(*pTc, "<");
if (0 < startParam && startParam < pTc->size())
className = (*pTc)[startParam - 1];
}
ASTNode* pClassNode = p_Repos->AST().find(className);
if (pClassNode == nullptr)
return;
if (p_Repos->scopeStack().size() < 2)
return;
ASTNode* pFunctNode = p_Repos->scopeStack().top();
ASTNode* pParentNode = p_Repos->scopeStack().predOfTop();
if(pParentNode->children_.size() > 0)
pParentNode->children_.pop_back(); pFunctNode->parentType_ = pClassNode->type_;
pClassNode->children_.push_back(pFunctNode); return;
}
std::string packageName = p_Repos->package();
std::string ext = FileSystem::Path::getExt(packageName);
size_t posOpenBracket;
pTc->find("[", posOpenBracket);
size_t posCloseBracket;
pTc->find("]", posCloseBracket);
size_t posBrace;
pTc->find("{", posBrace);
size_t posOpenParen;
pTc->find("(", posOpenParen);
if (posCloseBracket != posBrace + 1 && posCloseBracket != posOpenParen + 1) return;
if (posOpenBracket < posCloseBracket && posBrace == (posCloseBracket + 1) && posBrace < pTc->size())
{
std::string name;
for (size_t i = posOpenBracket; i < posBrace; ++i)
name += (*pTc)[i];
top->name_ = name;
top->type_ = "lambda";
}
}
};
class CSharpFunctionDefinition : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
Repository* pRepo = Repository::getInstance();
if (pRepo->language() != Language::CSharp)
return IRule::Continue;
GrammarHelper::showParseDemo("Test C# function definition: ", *pTc);
const Lexer::ITokenCollection& tc = *pTc;
if (tc[tc.size() - 1] == "{")
{
Lexer::Semi se;
for (size_t i = 0; i < tc.size(); ++i)
se.add(tc[i]);
if (GrammarHelper::isFunction(se))
{
doActions(&se);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleCSharpFunctionDefinition : public IAction
{
Repository* p_Repos;
public:
HandleCSharpFunctionDefinition(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle C# function definition: ", *pTc);
if (p_Repos->scopeStack().size() == 0)
return;
ASTNode* top = p_Repos->scopeStack().top();
size_t nameIndex;
if (pTc->find("(", nameIndex))
--nameIndex;
else
return;
std::string name = (*pTc)[nameIndex];
if (nameIndex > 0 && (*pTc)[nameIndex - 1] == "~")
{
--nameIndex;
name = "~" + name;
}
top->type_ = "function";
top->name_ = name;
top->package_ = p_Repos->package();
GrammarHelper::showParse("function def", *pTc);
size_t operIndex;
pTc->find("operator", operIndex);
if (operIndex < pTc->size())
{
name = "operator" + (*pTc)[operIndex + 1] + (*pTc)[operIndex + 2];
top->name_ = name;
nameIndex = operIndex;
}
size_t posParen;
pTc->find("(", posParen);
size_t posBrace;
pTc->find("{", posBrace);
size_t posEqual;
pTc->find("=", posEqual);
if (posParen < posBrace && posBrace < pTc->size())
{
if (posEqual < pTc->size() - 1 && (*pTc)[posEqual + 1] == ">")
{
std::string name;
for (size_t i = posParen; i <= posBrace; ++i)
name += (*pTc)[i];
top->name_ = name;
top->type_ = "lambda";
}
}
}
};
class ControlDefinition : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Test control definition: ", *pTc);
const Lexer::ITokenCollection& tc = *pTc;
if (tc[tc.size() - 1] == "{")
{
size_t len;
tc.find("(", len);
if (len < tc.size() && GrammarHelper::isControlKeyWord(tc[len - 1]))
{
doActions(pTc);
return IRule::Stop;
}
else if (tc.size() > 1 && GrammarHelper::isControlKeyWord(tc[tc.size() - 2]))
{
doActions(pTc);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleControlDefinition : public IAction
{
Repository* p_Repos;
public:
HandleControlDefinition(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle control definition: ", *pTc);
if (p_Repos->scopeStack().size() == 0)
return;
ASTNode* top;
if ((p_Repos->scopeStack()).size() > 0)
top = p_Repos->scopeStack().top();
else
return;
size_t nameIndex;
if(pTc->find("(", nameIndex)) --nameIndex;
else
nameIndex = pTc->size() - 2;
std::string name = (*pTc)[nameIndex];
top->type_ = "control";
top->name_ = name;
GrammarHelper::showParse("control def", *pTc);
}
};
class PrintFunction : public IAction
{
Repository* p_Repos;
public:
using Rslt = Logging::StaticLogger<0>;
PrintFunction(Repository* pRepos)
{
p_Repos = pRepos;
}
void doAction(const Lexer::ITokenCollection* pTc) override
{
std::ostringstream out;
Rslt::write(out.str());
}
};
class PrettyPrintFunction : public IAction
{
Repository* p_Repos;
public:
using Rslt = Logging::StaticLogger<0>;
PrettyPrintFunction(Repository* pRepos) : p_Repos(pRepos) {}
void doAction(const Lexer::ITokenCollection* pTc) override
{
size_t len;
pTc->find(")", len);
std::ostringstream out;
out << "\n\n Pretty Stmt: ";
for (size_t i = 0; i < len + 1; ++i)
out << (*pTc)[i] << " ";
out << "\n";
Rslt::write(out.str());
}
};
class CppDeclaration : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
Repository* pRepo = Repository::getInstance();
if (pRepo->language() != Language::Cpp)
return IRule::Continue;
GrammarHelper::showParseDemo("Test C++ declaration: ", *pTc);
Lexer::Semi tc;
tc.clone(*pTc);
Access access = pRepo->currentAccess();
bool isPublic = false;
if (pRepo->scopeStack().size() == 0)
return false;
std::string parentType = pRepo->scopeStack().top()->type_;
size_t posPrivate;
pTc->find("private", posPrivate);
if (posPrivate < pTc->size())
{
isPublic = false;
pRepo->currentAccess() = Access::priv;
}
size_t posProtected;
pTc->find("protected", posProtected);
if (posProtected < pTc->size())
{
isPublic = false;
pRepo->currentAccess() = Access::prot;
}
size_t posPublic;
pTc->find("public", posPublic);
if (posPublic < pTc->size() && parentType != "function")
{
isPublic = true;
pRepo->currentAccess() = Access::publ;
}
if (tc.size() > 0 && tc[0] == "using")
{
doActions(pTc);
return IRule::Stop;
}
if (tc[tc.size() - 1] == ";" && tc.size() > 2)
{
std::string nextToLast = tc[tc.size() - 2];
if (nextToLast == "delete" || nextToLast == "default" || nextToLast == "const")
{
{
doActions(pTc);
return IRule::Stop;
}
}
std::string parentType = pRepo->scopeStack().top()->type_;
if (GrammarHelper::isDataDeclaration(tc) || GrammarHelper::isFunctionDeclaration(tc, parentType))
{
doActions(pTc);
return IRule::Stop;
}
if (parentType != "function")
{
doActions(pTc);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleCppDeclaration : public IAction
{
Repository* p_Repos;
public:
HandleCppDeclaration(Repository* pRepos) : p_Repos(pRepos) {}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle C++ declaration: ", *pTc);
if (p_Repos->scopeStack().size() == 0)
return;
ASTNode* pCurrNode = p_Repos->scopeStack().top();
DeclarationNode declNode;
declNode.access_ = p_Repos->currentAccess();
declNode.pTc = pTc->clone();
declNode.package_ = p_Repos->package();
declNode.line_ = p_Repos->lineCount();
Lexer::Semi se;
se.clone(*pTc);
GrammarHelper::removeComments(se);
if (se[0] == "using")
{
declNode.declType_ = DeclType::usingDecl;
pCurrNode->decl_.push_back(declNode);
GrammarHelper::showParse("using declar", *pTc);
return;
}
if (GrammarHelper::isFunctionDeclaration(se,"parentNotFunction"))
{
return;
}
if (GrammarHelper::isDataDeclaration(se))
{
declNode.declType_ = DeclType::dataDecl;
pCurrNode->decl_.push_back(declNode);
GrammarHelper::showParse("data declar", *pTc);
}
}
};
class CSharpDeclaration : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
Repository* pRepo = Repository::getInstance();
if (pRepo->language() != Language::CSharp)
return IRule::Continue;
GrammarHelper::showParseDemo("Test C# declaration: ", *pTc);
Access access = pRepo->currentAccess();
bool isPublic = false;
if (pRepo->scopeStack().size() == 0)
return false;
std::string parentType = pRepo->scopeStack().top()->type_;
size_t posPublic;
pTc->find("public", posPublic);
if (posPublic < pTc->size() && parentType != "function")
{
isPublic = true;
pRepo->currentAccess() = Access::publ;
}
const Lexer::ITokenCollection& tc = *pTc;
if (tc.size() > 0 && tc[0] == "using")
{
doActions(pTc);
pRepo->currentAccess() = access;
return IRule::Stop;
}
Lexer::Semi se;
se.clone(*pTc);
if (GrammarHelper::isDataDeclaration(se))
{
doActions(pTc);
pRepo->currentAccess() = access;
return IRule::Stop;
}
if (GrammarHelper::isFunctionDeclaration(se, parentType))
{
doActions(pTc);
pRepo->currentAccess() = access;
return IRule::Stop;
}
return IRule::Continue;
}
};
class HandleCSharpDeclaration : public IAction
{
Repository* p_Repos;
public:
HandleCSharpDeclaration(Repository* pRepos) : p_Repos(pRepos) {}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle C# declaration: ", *pTc);
if (p_Repos->scopeStack().size() == 0)
return;
ASTNode* pCurrNode = p_Repos->scopeStack().top();
DeclarationNode declNode;
declNode.access_ = p_Repos->currentAccess();
declNode.pTc = pTc->clone();
declNode.package_ = p_Repos->package();
declNode.line_ = p_Repos->lineCount();
Lexer::Semi se;
se.clone(*pTc);
GrammarHelper::removeComments(se);
if (se[0] == "using")
{
declNode.declType_ = DeclType::usingDecl;
pCurrNode->decl_.push_back(declNode);
GrammarHelper::showParse("using declar", *pTc);
return;
}
std::string parentType = p_Repos->scopeStack().top()->type_;
if (GrammarHelper::isFunctionDeclaration(se, parentType))
{
Access adebug = declNode.access_;
declNode.declType_ = DeclType::functionDecl;
pCurrNode->decl_.push_back(declNode);
GrammarHelper::showParse("function declar", *pTc);
}
else
{
Access adebug = declNode.access_;
declNode.declType_ = DeclType::dataDecl;
pCurrNode->decl_.push_back(declNode);
GrammarHelper::showParse("data declar", *pTc);
}
}
};
class CppExecutable : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
Repository* pRepo = Repository::getInstance();
if (pRepo->language() != Language::Cpp)
return IRule::Continue;
GrammarHelper::showParseDemo("Test C++ executable: ", *pTc);
Lexer::Semi tc;
tc.clone(*pTc);
if (tc[tc.size() - 1] == ";" && tc.size() > 2)
{
GrammarHelper::removeFunctionArgs(tc);
GrammarHelper::condenseTemplateTypes(tc);
Lexer::Semi se;
for (size_t i = 0; i < tc.size(); ++i)
{
if (GrammarHelper::isQualifierKeyWord(tc[i]))
continue;
if (se.isComment(tc[i]) || tc[i] == "\n" || tc[i] == "return")
continue;
if (tc[i] == "=" || tc[i] == ";")
{
se.add(";");
break;
}
else
se.add(tc[i]);
}
if (se.size() != 3) {
doActions(pTc);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleCppExecutable : public IAction
{
Repository* p_Repo;
public:
HandleCppExecutable(Repository* pRepo) : p_Repo(pRepo) {}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle C++ executable: ", *pTc);
GrammarHelper::showParse("executable", *pTc);
}
};
class CSharpExecutable : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
Repository* pRepo = Repository::getInstance();
if (pRepo->language() != Language::CSharp)
return IRule::Continue;
GrammarHelper::showParseDemo("Test C# executable: ", *pTc);
const Lexer::ITokenCollection& in = *pTc;
Lexer::Semi tc;
for (size_t i = 0; i < in.size(); ++i)
tc.add(in[i]);
if (tc[tc.size() - 1] == ";" && tc.size() > 2)
{
GrammarHelper::removeFunctionArgs(tc);
GrammarHelper::condenseTemplateTypes(tc);
Lexer::Semi se;
for (size_t i = 0; i < tc.size(); ++i)
{
if (GrammarHelper::isQualifierKeyWord(tc[i]))
continue;
if (se.isComment(tc[i]) || tc[i] == "\n" || tc[i] == "return")
continue;
if (tc[i] == "=" || tc[i] == ";")
{
se.add(";");
break;
}
else
se.add(tc[i]);
}
if (se.size() != 3) {
doActions(pTc);
return IRule::Stop;
}
}
return IRule::Continue;
}
};
class HandleCSharpExecutable : public IAction
{
Repository* p_Repo;
public:
HandleCSharpExecutable(Repository* pRepo) : p_Repo(pRepo) {}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle C# executable: ", *pTc);
Lexer::Semi se;
se.clone(*pTc);
GrammarHelper::removeComments(se);
GrammarHelper::showParse("executable", se);
}
};
class Default : public IRule
{
public:
bool doTest(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Test default: ", *pTc);
doActions(pTc); return IRule::Stop;
}
};
class HandleDefault : public IAction
{
Repository* p_Repo;
public:
HandleDefault(Repository* pRepo) : p_Repo(pRepo) {}
void doAction(const Lexer::ITokenCollection* pTc) override
{
GrammarHelper::showParseDemo("Handle default: ", *pTc);
GrammarHelper::showParse("default: ", *pTc);
}
};
}
#endif