summaryrefslogtreecommitdiffstats
path: root/source/core/token-reader.h
diff options
context:
space:
mode:
authorYONGH\yongh <yonghe@outlook.com>2017-10-20 18:24:30 -0400
committerYONGH\yongh <yonghe@outlook.com>2017-10-20 18:24:30 -0400
commit0ee4d4b54732239b946bae7fde32bb21aa5a3ec3 (patch)
tree0c5f4a7f6f43e60802d354aa98a3983994f4f4bd /source/core/token-reader.h
parent5a18dc704a2f5eecebcbdd77682a40ba8316d253 (diff)
in-progress work: allow render-test to generate and bind various resource inputs for running test shaders with arbitrary parameter definitions.
This commit contains the parser of the resource input definition.
Diffstat (limited to 'source/core/token-reader.h')
-rw-r--r--source/core/token-reader.h258
1 files changed, 258 insertions, 0 deletions
diff --git a/source/core/token-reader.h b/source/core/token-reader.h
new file mode 100644
index 000000000..aaebad756
--- /dev/null
+++ b/source/core/token-reader.h
@@ -0,0 +1,258 @@
+#ifndef CORE_TOKEN_READER_H
+#define CORE_TOKEN_READER_H
+
+#include "basic.h"
+
+namespace Slang
+{
+ enum class TokenType
+ {
+ EndOfFile = -1,
+ // illegal
+ Unknown,
+ // identifier
+ Identifier,
+ // constant
+ IntLiteral, DoubleLiteral, StringLiteral, CharLiteral,
+ // operators
+ Semicolon, Comma, Dot, LBrace, RBrace, LBracket, RBracket, LParent, RParent,
+ OpAssign, OpAdd, OpSub, OpMul, OpDiv, OpMod, OpNot, OpBitNot, OpLsh, OpRsh,
+ OpEql, OpNeq, OpGreater, OpLess, OpGeq, OpLeq,
+ OpAnd, OpOr, OpBitXor, OpBitAnd, OpBitOr,
+ OpInc, OpDec, OpAddAssign, OpSubAssign, OpMulAssign, OpDivAssign, OpModAssign,
+ OpShlAssign, OpShrAssign, OpOrAssign, OpAndAssign, OpXorAssign,
+
+ QuestionMark, Colon, RightArrow, At, Pound, PoundPound,
+ };
+
+ class CodePosition
+ {
+ public:
+ int Line = -1, Col = -1, Pos = -1;
+ String FileName;
+ String ToString()
+ {
+ StringBuilder sb(100);
+ sb << FileName;
+ if (Line != -1)
+ sb << "(" << Line << ")";
+ return sb.ProduceString();
+ }
+ CodePosition() = default;
+ CodePosition(int line, int col, int pos, String fileName)
+ {
+ Line = line;
+ Col = col;
+ Pos = pos;
+ this->FileName = fileName;
+ }
+ bool operator < (const CodePosition & pos) const
+ {
+ return FileName < pos.FileName || (FileName == pos.FileName && Line < pos.Line) ||
+ (FileName == pos.FileName && Line == pos.Line && Col < pos.Col);
+ }
+ bool operator == (const CodePosition & pos) const
+ {
+ return FileName == pos.FileName && Line == pos.Line && Col == pos.Col;
+ }
+ };
+
+ enum TokenFlag : unsigned int
+ {
+ AtStartOfLine = 1 << 0,
+ AfterWhitespace = 1 << 1,
+ };
+ typedef unsigned int TokenFlags;
+
+ class Token
+ {
+ public:
+ TokenType Type = TokenType::Unknown;
+ String Content;
+ CodePosition Position;
+ TokenFlags flags;
+ Token() = default;
+ Token(TokenType type, const String & content, int line, int col, int pos, String fileName, TokenFlags flags = 0)
+ : flags(flags)
+ {
+ Type = type;
+ Content = content;
+ Position = CodePosition(line, col, pos, fileName);
+ }
+ };
+
+ class TextFormatException : public Exception
+ {
+ public:
+ TextFormatException(String message)
+ : Exception(message)
+ {}
+ };
+
+ class TokenReader
+ {
+ private:
+ bool legal;
+ List<Token> tokens;
+ int tokenPtr;
+ public:
+ TokenReader(String text);
+ int ReadInt()
+ {
+ auto token = ReadToken();
+ bool neg = false;
+ if (token.Content == '-')
+ {
+ neg = true;
+ token = ReadToken();
+ }
+ if (token.Type == TokenType::IntLiteral)
+ {
+ if (neg)
+ return -StringToInt(token.Content);
+ else
+ return StringToInt(token.Content);
+ }
+ throw TextFormatException("Text parsing error: int expected.");
+ }
+ unsigned int ReadUInt()
+ {
+ auto token = ReadToken();
+ if (token.Type == TokenType::IntLiteral)
+ {
+ return StringToUInt(token.Content);
+ }
+ throw TextFormatException("Text parsing error: int expected.");
+ }
+ double ReadDouble()
+ {
+ auto token = ReadToken();
+ bool neg = false;
+ if (token.Content == '-')
+ {
+ neg = true;
+ token = ReadToken();
+ }
+ if (token.Type == TokenType::DoubleLiteral || token.Type == TokenType::IntLiteral)
+ {
+ if (neg)
+ return -StringToDouble(token.Content);
+ else
+ return StringToDouble(token.Content);
+ }
+ throw TextFormatException("Text parsing error: floating point value expected.");
+ }
+ float ReadFloat()
+ {
+ return (float)ReadDouble();
+ }
+ String ReadWord()
+ {
+ auto token = ReadToken();
+ if (token.Type == TokenType::Identifier)
+ {
+ return token.Content;
+ }
+ throw TextFormatException("Text parsing error: identifier expected.");
+ }
+ String Read(const char * expectedStr)
+ {
+ auto token = ReadToken();
+ if (token.Content == expectedStr)
+ {
+ return token.Content;
+ }
+ throw TextFormatException("Text parsing error: \'" + String(expectedStr) + "\' expected.");
+ }
+ String Read(String expectedStr)
+ {
+ auto token = ReadToken();
+ if (token.Content == expectedStr)
+ {
+ return token.Content;
+ }
+ throw TextFormatException("Text parsing error: \'" + expectedStr + "\' expected.");
+ }
+
+ String ReadStringLiteral()
+ {
+ auto token = ReadToken();
+ if (token.Type == TokenType::StringLiteral)
+ {
+ return token.Content;
+ }
+ throw TextFormatException("Text parsing error: string literal expected.");
+ }
+ void Back(int count)
+ {
+ tokenPtr -= count;
+ }
+ Token ReadToken()
+ {
+ if (tokenPtr < (int)tokens.Count())
+ {
+ auto &rs = tokens[tokenPtr];
+ tokenPtr++;
+ return rs;
+ }
+ throw TextFormatException("Unexpected ending.");
+ }
+ Token NextToken(int offset = 0)
+ {
+ if (tokenPtr + offset < (int)tokens.Count())
+ return tokens[tokenPtr + offset];
+ else
+ {
+ Token rs;
+ rs.Type = TokenType::Unknown;
+ return rs;
+ }
+ }
+ bool LookAhead(String token)
+ {
+ if (tokenPtr < (int)tokens.Count())
+ {
+ auto next = NextToken();
+ return next.Content == token;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ bool IsEnd()
+ {
+ return tokenPtr == (int)tokens.Count();
+ }
+ public:
+ bool IsLegalText()
+ {
+ return legal;
+ }
+ };
+
+ inline List<String> Split(String text, char c)
+ {
+ List<String> result;
+ StringBuilder sb;
+ for (int i = 0; i < (int)text.Length(); i++)
+ {
+ if (text[i] == c)
+ {
+ auto str = sb.ToString();
+ if (str.Length() != 0)
+ result.Add(str);
+ sb.Clear();
+ }
+ else
+ sb << text[i];
+ }
+ auto lastStr = sb.ToString();
+ if (lastStr.Length())
+ result.Add(lastStr);
+ return result;
+ }
+}
+
+
+#endif \ No newline at end of file