Path: blob/master/thirdparty/embree/common/lexers/tokenstream.h
9913 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "stream.h"6#include <string>7#include <vector>89namespace embree10{11/*! token class */12class Token13{14public:1516enum Type { TY_EOF, TY_CHAR, TY_INT, TY_FLOAT, TY_IDENTIFIER, TY_STRING, TY_SYMBOL };1718Token ( const ParseLocation& loc = ParseLocation()) : ty(TY_EOF ), loc(loc) {}19Token (char c, const ParseLocation& loc = ParseLocation()) : ty(TY_CHAR ), c(c), loc(loc) {}20Token (int i, const ParseLocation& loc = ParseLocation()) : ty(TY_INT ), i(i), loc(loc) {}21Token (float f,const ParseLocation& loc = ParseLocation()) : ty(TY_FLOAT), f(f), loc(loc) {}22Token (std::string str, Type ty, const ParseLocation& loc = ParseLocation()) : ty(ty), str(str), loc(loc) {}2324static Token Eof() { return Token(); }25static Token Sym(std::string str) { return Token(str,TY_SYMBOL); }26static Token Str(std::string str) { return Token(str,TY_STRING); }27static Token Id (std::string str) { return Token(str,TY_IDENTIFIER); }2829char Char() const {30if (ty == TY_CHAR) return c;31THROW_RUNTIME_ERROR(loc.str()+": character expected");32}3334int Int() const {35if (ty == TY_INT) return i;36THROW_RUNTIME_ERROR(loc.str()+": integer expected");37}3839float Float(bool cast = true) const {40if (ty == TY_FLOAT) return f;41if (ty == TY_INT && cast) return (float)i;42THROW_RUNTIME_ERROR(loc.str()+": float expected");43}4445std::string Identifier() const {46if (ty == TY_IDENTIFIER) return str;47THROW_RUNTIME_ERROR(loc.str()+": identifier expected");48}4950std::string String() const {51if (ty == TY_STRING) return str;52THROW_RUNTIME_ERROR(loc.str()+": string expected");53}5455std::string Symbol() const {56if (ty == TY_SYMBOL) return str;57THROW_RUNTIME_ERROR(loc.str()+": symbol expected");58}5960const ParseLocation& Location() const { return loc; }6162friend bool operator==(const Token& a, const Token& b)63{64if (a.ty != b.ty) return false;65if (a.ty == TY_CHAR) return a.c == b.c;66if (a.ty == TY_INT) return a.i == b.i;67if (a.ty == TY_FLOAT) return a.f == b.f;68if (a.ty == TY_IDENTIFIER) return a.str == b.str;69if (a.ty == TY_STRING) return a.str == b.str;70if (a.ty == TY_SYMBOL) return a.str == b.str;71return true;72}7374friend bool operator!=(const Token& a, const Token& b) {75return !(a == b);76}7778friend bool operator <( const Token& a, const Token& b ) {79if (a.ty != b.ty) return (int)a.ty < (int)b.ty;80if (a.ty == TY_CHAR) return a.c < b.c;81if (a.ty == TY_INT) return a.i < b.i;82if (a.ty == TY_FLOAT) return a.f < b.f;83if (a.ty == TY_IDENTIFIER) return a.str < b.str;84if (a.ty == TY_STRING) return a.str < b.str;85if (a.ty == TY_SYMBOL) return a.str < b.str;86return false;87}8889friend std::ostream& operator<<(std::ostream& cout, const Token& t)90{91if (t.ty == TY_EOF) return cout << "eof";92if (t.ty == TY_CHAR) return cout << "Char(" << t.c << ")";93if (t.ty == TY_INT) return cout << "Int(" << t.i << ")";94if (t.ty == TY_FLOAT) return cout << "Float(" << t.f << ")";95if (t.ty == TY_IDENTIFIER) return cout << "Id(" << t.str << ")";96if (t.ty == TY_STRING) return cout << "String(" << t.str << ")";97if (t.ty == TY_SYMBOL) return cout << "Symbol(" << t.str << ")";98return cout << "unknown";99}100101private:102Type ty; //< the type of the token103union {104char c; //< data for char tokens105int i; //< data for int tokens106float f; //< data for float tokens107};108std::string str; //< data for string and identifier tokens109ParseLocation loc; //< the location the token is from110};111112/*! build full tokenizer that takes list of valid characters and keywords */113class TokenStream : public Stream<Token>114{115public:116117/*! shorthands for common sets of characters */118static const std::string alpha;119static const std::string ALPHA;120static const std::string numbers;121static const std::string separators;122static const std::string stringChars;123124public:125TokenStream(const Ref<Stream<int> >& cin,126const std::string& alpha, //< valid characters for identifiers127const std::string& seps, //< characters that act as separators128const std::vector<std::string>& symbols = std::vector<std::string>()); //< symbols129public:130ParseLocation location() { return cin->loc(); }131Token next();132bool trySymbol(const std::string& symbol);133134private:135void skipSeparators();136bool decDigits(std::string& str);137bool decDigits1(std::string& str);138bool trySymbols(Token& token, const ParseLocation& loc);139bool tryFloat(Token& token, const ParseLocation& loc);140bool tryInt(Token& token, const ParseLocation& loc);141bool tryString(Token& token, const ParseLocation& loc);142bool tryIdentifier(Token& token, const ParseLocation& loc);143144Ref<Stream<int> > cin;145bool isSepMap[256];146bool isAlphaMap[256];147bool isStringCharMap[256];148std::vector<std::string> symbols;149150/*! checks if a character is a separator */151__forceinline bool isSeparator(unsigned int c) const { return c<256 && isSepMap[c]; }152153/*! checks if a character is a number */154__forceinline bool isDigit(unsigned int c) const { return c >= '0' && c <= '9'; }155156/*! checks if a character is valid inside a string */157__forceinline bool isStringChar(unsigned int c) const { return c<256 && isStringCharMap[c]; }158159/*! checks if a character is legal for an identifier */160__forceinline bool isAlpha(unsigned int c) const { return c<256 && isAlphaMap[c]; }161__forceinline bool isAlphaNum(unsigned int c) const { return isAlpha(c) || isDigit(c); }162};163}164165166