You've already forked ScriptPreprocessor
mirror of
https://github.com/AxioDL/ScriptPreprocessor.git
synced 2026-07-10 21:18:40 -07:00
* Fix line comments
* Add preprocessor hooks
This commit is contained in:
+4
-3
@@ -33,8 +33,8 @@ int CLexer::lex(char* start, char* end, TokenList& tokens)
|
||||
{
|
||||
CLexer::Token currentToken;
|
||||
start = _parseToken(start, end, currentToken);
|
||||
if (currentToken.type != CLexer::COMMENT)
|
||||
tokens.push_back(currentToken);
|
||||
//if (currentToken.type != CLexer::COMMENT)
|
||||
tokens.push_back(currentToken);
|
||||
if (start == end)
|
||||
return 0;
|
||||
}
|
||||
@@ -128,7 +128,7 @@ char* CLexer::_parseLineComment(char* start, char* end, CLexer::Token& out)
|
||||
++start;
|
||||
if (start == end)
|
||||
return start;
|
||||
out.value += start;
|
||||
out.value += *start;
|
||||
if (*start == '\n')
|
||||
return start;
|
||||
}
|
||||
@@ -154,6 +154,7 @@ char* CLexer::_parseBlockComment(char* start, char* end, CLexer::Token& out)
|
||||
if (*start == '/')
|
||||
{
|
||||
out.value += *start;
|
||||
++start;
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
||||
+31
-15
@@ -72,6 +72,16 @@ void CPreprocessor::registerPragma(const std::string& name, std::function<void (
|
||||
m_registeredPragmas[name] = cb;
|
||||
}
|
||||
|
||||
void CPreprocessor::registerHook(const std::string& name, std::function<void (CLexer::TokenList&, CPreprocessor::DefineTable&)> cb)
|
||||
{
|
||||
std::string pre = "#" + name;
|
||||
HookIterator iter = m_registeredHooks.find(pre);
|
||||
if (iter != m_registeredHooks.end())
|
||||
m_registeredHooks.erase(iter);
|
||||
|
||||
m_registeredHooks[pre] = cb;
|
||||
}
|
||||
|
||||
std::string CPreprocessor::finalizedSource()
|
||||
{
|
||||
std::string ret;
|
||||
@@ -126,7 +136,7 @@ std::string CPreprocessor::_loadSource(const std::string& filename)
|
||||
return code;
|
||||
}
|
||||
|
||||
void CPreprocessor::_advanceList(CLexer::TokenList& tokens)
|
||||
void CPreprocessor::advanceList(CLexer::TokenList& tokens)
|
||||
{
|
||||
tokens.pop_front();
|
||||
while(true)
|
||||
@@ -243,6 +253,12 @@ void CPreprocessor::preprocessRecursive(const std::string& filename, const std::
|
||||
_parseWarning(directive, defineTable);
|
||||
else if (value == "#error")
|
||||
_parseError(directive, defineTable);
|
||||
else
|
||||
{
|
||||
HookIterator iter = m_registeredHooks.find(value);
|
||||
if (iter != m_registeredHooks.end() && m_registeredHooks[value])
|
||||
m_registeredHooks[value](directive, defineTable);
|
||||
}
|
||||
}
|
||||
else if (begin->type == CLexer::IDENTIFIER)
|
||||
{
|
||||
@@ -390,7 +406,7 @@ CLexer::TokenIterator CPreprocessor::_expandDefine(CLexer::TokenIterator begin,
|
||||
|
||||
void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer::TokenList& tokens)
|
||||
{
|
||||
_advanceList(tokens);
|
||||
advanceList(tokens);
|
||||
if (tokens.empty())
|
||||
{
|
||||
printErrorMessage("Define directive without arguments");
|
||||
@@ -408,7 +424,7 @@ void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer
|
||||
printErrorMessage(name.value + " already defined.");
|
||||
return;
|
||||
}
|
||||
_advanceList(tokens);
|
||||
advanceList(tokens);
|
||||
|
||||
DefineEntry def;
|
||||
|
||||
@@ -417,14 +433,14 @@ void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer
|
||||
if (tokens.begin()->type == CLexer::PREPROCESSOR && tokens.begin()->value == "#")
|
||||
{
|
||||
// macro has arguments
|
||||
_advanceList(tokens);
|
||||
advanceList(tokens);
|
||||
|
||||
if (tokens.empty() || tokens.begin()->value != "(")
|
||||
{
|
||||
printErrorMessage("Expected arguments");
|
||||
return;
|
||||
}
|
||||
_advanceList(tokens);
|
||||
advanceList(tokens);
|
||||
|
||||
int argCount = 0;
|
||||
while (!tokens.empty() && tokens.begin()->value != ")")
|
||||
@@ -436,9 +452,9 @@ void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer
|
||||
}
|
||||
|
||||
def.arguments[tokens.begin()->value] = argCount;
|
||||
_advanceList(tokens);
|
||||
advanceList(tokens);
|
||||
if (!tokens.empty() && tokens.begin()->value == ",")
|
||||
_advanceList(tokens);
|
||||
advanceList(tokens);
|
||||
argCount++;
|
||||
}
|
||||
|
||||
@@ -449,7 +465,7 @@ void CPreprocessor::_parseDefine(CPreprocessor::DefineTable& defineTable, CLexer
|
||||
printErrorMessage("Expected closing parentheses");
|
||||
return;
|
||||
}
|
||||
_advanceList(tokens);
|
||||
advanceList(tokens);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -500,7 +516,7 @@ CLexer::TokenIterator CPreprocessor::_parseIfDef(CLexer::TokenIterator begin, CL
|
||||
|
||||
void CPreprocessor::_parseIf(CLexer::TokenList& directive, std::string& nameOut)
|
||||
{
|
||||
_advanceList(directive);
|
||||
advanceList(directive);
|
||||
if (directive.empty())
|
||||
{
|
||||
printErrorMessage("Expected argument.");
|
||||
@@ -508,14 +524,14 @@ void CPreprocessor::_parseIf(CLexer::TokenList& directive, std::string& nameOut)
|
||||
}
|
||||
|
||||
nameOut = directive.begin()->value;
|
||||
_advanceList(directive);
|
||||
advanceList(directive);
|
||||
if (!directive.empty())
|
||||
printErrorMessage("Too many arguments.");
|
||||
}
|
||||
|
||||
void CPreprocessor::_parsePragma(CLexer::TokenList& args)
|
||||
{
|
||||
_advanceList(args);
|
||||
advanceList(args);
|
||||
if (args.empty())
|
||||
{
|
||||
printErrorMessage("Pragmas need arguments.");
|
||||
@@ -523,7 +539,7 @@ void CPreprocessor::_parsePragma(CLexer::TokenList& args)
|
||||
}
|
||||
std::string pragmaName = args.begin()->value;
|
||||
|
||||
_advanceList(args);
|
||||
advanceList(args);
|
||||
|
||||
std::string pragmaArgs;
|
||||
if (!args.empty())
|
||||
@@ -531,7 +547,7 @@ void CPreprocessor::_parsePragma(CLexer::TokenList& args)
|
||||
if (args.begin()->type != CLexer::STRING)
|
||||
printErrorMessage("Pragma parameter should be a string literal");
|
||||
pragmaArgs = removeQuotes(args.begin()->value);
|
||||
_advanceList(args);
|
||||
advanceList(args);
|
||||
}
|
||||
if (!args.empty())
|
||||
printErrorMessage("Too many paremeters for pragma.");
|
||||
@@ -573,7 +589,7 @@ std::string CPreprocessor::_expandMessage(DefineTable& defineTable, CLexer::Toke
|
||||
|
||||
void CPreprocessor::_parseWarning(CLexer::TokenList& args, DefineTable& defineTable)
|
||||
{
|
||||
_advanceList(args);
|
||||
advanceList(args);
|
||||
if (args.empty())
|
||||
{
|
||||
printErrorMessage("Warnings need messages.");
|
||||
@@ -586,7 +602,7 @@ void CPreprocessor::_parseWarning(CLexer::TokenList& args, DefineTable& defineTa
|
||||
|
||||
void CPreprocessor::_parseError(CLexer::TokenList& args, CPreprocessor::DefineTable& defineTable)
|
||||
{
|
||||
_advanceList(args);
|
||||
advanceList(args);
|
||||
if (args.empty())
|
||||
{
|
||||
printErrorMessage("Errors need messages.");
|
||||
|
||||
+6
-1
@@ -32,14 +32,19 @@ public:
|
||||
typedef DefineTable::iterator DefineIterator;
|
||||
typedef std::map<std::string, std::function<void(PragmaInstance)> > PragmaMap;
|
||||
typedef PragmaMap::iterator PragmaIterator;
|
||||
typedef std::map<std::string, std::function<void(CLexer::TokenList&, DefineTable&)> > HookMap;
|
||||
typedef HookMap::iterator HookIterator;
|
||||
|
||||
void define(const std::string& def);
|
||||
void undefine(const std::string& def);
|
||||
void registerPragma(const std::string& name, std::function<void(PragmaInstance)> cb);
|
||||
void registerHook(const std::string& name, std::function<void(CLexer::TokenList&, DefineTable&)> cb);
|
||||
|
||||
std::string finalizedSource();
|
||||
int preprocessFile(const std::string& filename);
|
||||
int preprocessCode(const std::string& filename, const std::string& code);
|
||||
|
||||
static void advanceList(CLexer::TokenList& tokens);
|
||||
private:
|
||||
std::string _loadSource(const std::string& filename);
|
||||
void printErrorMessage(const std::string& errMsg);
|
||||
@@ -48,7 +53,6 @@ private:
|
||||
void preprocessRecursive(const std::string& filename, const std::string& code, CLexer::TokenList& tokens, DefineTable& defineTable);
|
||||
|
||||
void callPragma(const std::string& name, const PragmaInstance& parms);
|
||||
void _advanceList(CLexer::TokenList& tokens);
|
||||
CLexer::TokenIterator _findToken(CLexer::TokenIterator begin, CLexer::TokenIterator end, CLexer::TokenType type);
|
||||
CLexer::TokenIterator _parseStatement(CLexer::TokenIterator begin, CLexer::TokenIterator end, CLexer::TokenList& dest);
|
||||
CLexer::TokenIterator _parseDefineArguments(CLexer::TokenIterator begin, CLexer::TokenIterator end, CLexer::TokenList& tokens, std::vector<CLexer::TokenList>& args);
|
||||
@@ -63,6 +67,7 @@ private:
|
||||
|
||||
DefineTable m_applicationDefined;
|
||||
PragmaMap m_registeredPragmas;
|
||||
HookMap m_registeredHooks;
|
||||
CLineTranslator m_lineTranslator;
|
||||
CLexer::TokenList m_tokens;
|
||||
|
||||
|
||||
@@ -12,9 +12,21 @@ void printTokenList(CLexer::TokenList& out)
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
||||
void linkInstancePreprocessor(CLexer::TokenList& tokens, CPreprocessor::DefineTable& defineTable)
|
||||
{
|
||||
(void)(defineTable);
|
||||
CPreprocessor::advanceList(tokens);
|
||||
if (tokens.size() == 0)
|
||||
return;
|
||||
|
||||
std::cout << tokens.begin()->value << std::endl;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
CPreprocessor preprocessor;
|
||||
preprocessor.registerHook("link_instance", linkInstancePreprocessor);
|
||||
preprocessor.preprocessFile("main.as");
|
||||
std::cout << preprocessor.finalizedSource() << std::endl;
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user