yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
cf8e75fae
master
1#ifndef SLANG_LEXER_H 2#define SLANG_LEXER_H 3 4#include "../core/slang-basic.h" 5#include "slang-diagnostic-sink.h" 6 7namespace Slang 8{ 9struct NamePool ; 10 11// 12 13struct TokenList 14{ 15const Token * begin ()const ; 16const Token * end ()const ; 17 18SLANG_FORCE_INLINE void add (const Token & token ) {m_tokens .add (token ); } 19 20List < Token > m_tokens ; 21}; 22 23struct TokenSpan 24{ 25TokenSpan (); 26TokenSpan (TokenList const & tokenList ) 27: m_begin ( tokenList . begin ()), m_end( tokenList . end ()) 28{ 29} 30 31const Token * begin() const { return m_begin ; } 32const Token * end () const { return m_end ; } 33 34int getCount () { return ( int )( m_end - m_begin ); } 35 36const Token * m_begin ; 37const Token * m_end ; 38}; 39 40struct TokenReader 41{ 42Token m_nextToken; 43TokenReader ( ); 44explicit TokenReader (TokenSpan const & tokens ) 45: m_cursor ( tokens . begin ()), m_end (tokens. end ()) 46{ 47_updateLookaheadToken (); 48} 49explicit TokenReader (TokenList const & tokens ) 50: m_cursor ( tokens . begin ()), m_end (tokens. end ()) 51{ 52_updateLookaheadToken (); 53} 54explicit TokenReader (Token const * begin , Token const * end ) 55: m_cursor ( begin ), m_end (end) 56{ 57_updateLookaheadToken (); 58} 59struct ParsingCursor 60{ 61bool operator == ( const ParsingCursor & rhs ) const 62{ 63return tokenReaderCursor == rhs . tokenReaderCursor ; 64} 65bool operator != ( const ParsingCursor & rhs ) const { return !( * this == rhs ); } 66 67bool isValid () const { return tokenReaderCursor != nullptr ; } 68 69Token nextToken ; 70const Token * tokenReaderCursor = nullptr ; 71}; 72ParsingCursor getCursor () 73{ 74ParsingCursor rs ; 75rs . nextToken = m_nextToken ; 76rs . tokenReaderCursor = m_cursor ; 77return rs ; 78} 79void setCursor (ParsingCursor cursor ) 80{ 81m_cursor = cursor . tokenReaderCursor ; 82m_nextToken = cursor . nextToken ; 83} 84bool isAtCursor ( const ParsingCursor & cursor ) const 85{ 86return cursor . tokenReaderCursor == m_cursor ; 87} 88bool isAtEnd () const { return m_cursor == m_end ; } 89Token & peekToken (); 90TokenType peekTokenType () const ; 91SourceLoc peekLoc () const ; 92 93Token advanceToken (); 94 95int getCount () { return (int)( m_end - m_cursor ); } 96 97const Token * m_cursor ; 98const Token * m_end ; 99static Token getEndOfFileToken (); 100 101private : 102/// Update the lookahead token in `m_nextToken` to reflect the cursor state 103void _updateLookaheadToken (); 104}; 105 106typedef unsigned int LexerFlags; 107enum 108{ 109kLexerFlag_SuppressDiagnostics = 1 110<< 2 , ///< Suppress errors about invalid/unsupported characters 111}; 112 113struct Lexer 114{ 115void initialize ( 116SourceView * sourceView , 117DiagnosticSink * sink , 118NamePool * namePool , 119MemoryArena * memoryArena ); 120 121~ Lexer (); 122 123/// Runs the lexer to try and extract a single token, which is returned. 124/// This can be used by the DiagnosticSink to be able to display more appropriate 125/// information when displaying a source location - such as underscoring the 126/// token at that location. 127/// 128/// NOTE! This function is relatively slow, and is designed for use around this specific 129/// purpose. It does not return a token or a token type, because that information is 130/// not needed by the DiagnosticSink. 131static UnownedStringSlice sourceLocationLexer ( const UnownedStringSlice & in ); 132 133/// Lex the next token in the input stream, returning an EOF token if at end. 134Token lexToken (); 135 136/// Lex all tokens (up to the end of the stream) that are semantically relevant 137TokenList lexAllSemanticTokens (); 138 139/// Lex all tokens (up to the end of the stream) that are relevant to things like markup 140TokenList lexAllMarkupTokens (); 141 142/// Lex all tokens (up to the end of the stream) whether relevant or not. 143TokenList lexAllTokens (); 144 145/// Get the diagnostic sink, taking into account flags. Will return null if suppressing 146/// diagnostics. 147DiagnosticSink * getDiagnosticSink () 148{ 149return ((m_lexerFlags & kLexerFlag_SuppressDiagnostics ) == 0 ) ? m_sink : nullptr ; 150} 151 152SourceLoc findNextLineEnd (SourceLoc from , UInt & lineCount ) const ; 153 154SourceView * m_sourceView ; 155DiagnosticSink * m_sink ; 156NamePool * m_namePool ; 157 158char const * m_cursor ; 159 160char const * m_begin ; 161char const * m_end ; 162 163/// The starting sourceLoc (same as first location of SourceView) 164SourceLoc m_startLoc ; 165 166TokenFlags m_tokenFlags ; 167LexerFlags m_lexerFlags ; 168 169MemoryArena * m_memoryArena ; 170}; 171 172 173// Helper routines for extracting values from tokens 174String getStringLiteralTokenValue (Token const & token ); 175String getFileNameTokenValue (Token const & token ); 176 177typedef int64_t IntegerLiteralValue; 178typedef double FloatingPointLiteralValue; 179 180IntegerLiteralValue getIntegerLiteralValue ( 181Token const & token , 182UnownedStringSlice * outSuffix = 0 , 183bool * outIsDecimalBase = 0 ); 184FloatingPointLiteralValue getFloatingPointLiteralValue ( 185Token const & token , 186UnownedStringSlice * outSuffix = 0 ); 187 188IntegerLiteralValue getCharLiteralValue (Token const & token ); 189} // namespace Slang 190 191#endif