I have a game engine and a shader parser. The engine has an API for reading from a virtual file system. I would like to be able to load shaders through this API. I was thinking about implementing my own std::ifstream but I don't like it, my api is very simple and I don't want to do a lot of unnecessary work. I just need to be able to read N bytes from the VFS. I used a C mod for more convenience, but in the end I can not find a solution to this problem, since there is very little official information about this. Everything is there for the C API, at least I can call the scan_string function, I did not find such a function in the yyFlexParser interface.
To be honest, I wanted to abandon the std::ifstream in the parser, and return only the C api . The only thing I used the Flex C mode for is to interact with the Bison C API and so that the parser can be used in a multi-threaded environment, but this can also be achieved with the C API. I just couldn't compile the C parser with the C compiler.
- I would be happy if there is a way to add such functionality through some kind of macro.
- I wouldn't mind if there was a way to return the yy_scan_string function, I could read the whole file myself and provide just a string.
CodePudding user response:
The simple solution, if you just want to provide a string input, is to make the string into a std::istringstream
, which is a valid std::istream
. The simplicity of this solution reduces the need for an equivalent to yy_scan_string
.
On the other hand, if you have a data source you want to read from which is not derived from std::istream
, you can easily create a lexical scanner which does whatever is necessary. Just subclass yyFlexLexer
, add whatever private data members you will need and a constructor which initialises them, and override int LexerInput(char* buffer, size_t maxsize);
to read at least one and no more than maxsize
bytes into buffer
, returning the number of characters read. (YY_INPUT
also works in the C interface, but subclassing is more convenient precisely because it lets you maintain your own reader state.)
Notes:
If you decide to subclass and override
LexerInput
, you need to be aware that "interactive" mode is actually implemented inLexerInput
. So if you want your lexer to have an interactive mode, you'll have to implement it in your override, too. In interactive mode,LexerInput
always reads exactly one character (unless, of course, it's at the end of the file).As you can see in the Flex code repository, a future version of Flex will use refactored versions of these functions, so you might need to be prepared to modify your code in the future, although Flex generally maintains backwards compatibility for a long time.