X-Git-Url: https://feistymeow.org/gitweb/?a=blobdiff_plain;f=infobase%2Fexamples%2Fcpp_grammar_code%2FCxxLexing.cxx;fp=infobase%2Fexamples%2Fcpp_grammar_code%2FCxxLexing.cxx;h=d57b0f1001a21033ae985f3df52c8494de5ff2d2;hb=c589a3686d4508c9c5ea7841deb9be251460ddc3;hp=0000000000000000000000000000000000000000;hpb=4c595ba63a6c5203e104fe83fee43d69d3ff7aef;p=feisty_meow.git diff --git a/infobase/examples/cpp_grammar_code/CxxLexing.cxx b/infobase/examples/cpp_grammar_code/CxxLexing.cxx new file mode 100644 index 00000000..d57b0f10 --- /dev/null +++ b/infobase/examples/cpp_grammar_code/CxxLexing.cxx @@ -0,0 +1,152 @@ +#ifdef FLEX_PP_CLASS +FLEX_PP_CLASS theLexer; +#define LEX_DOT theLexer . +#else +#define LEX_DOT +#endif + +bool c_keywords = false; +bool echo_line_numbers = false; +bool echo_line_text = false; +size_t line_number = 0; + +#ifdef NEEDS_YYWRAP +int yywrap() { return 1; } +#endif + +CxxToken *yylex_token() +{ + if (!LEX_DOT yylex()) + return 0; + return yyToken; +} + +// +// Configure the lexer to reflect successful parsing of a character value, assigning it to yylval. +// +// The source someText[aLength] should correspond to the parsed text including any L or ' prefix +// but excluding any ' suffix. In this way the return can indicate whether a wide character has +// been detected and the routine can accommodate a variety of erroneous terminations. +// +CxxToken *make_character(const char *someText, size_t aLength) +{ + bool isWide = false; + if (someText && aLength) + { + if (*someText == 'L') + { + isWide = true; + someText++; + aLength--; + } + if (!aLength || (*someText != '\'')) + ERRMSG("BUG - bad start of character literal."); + if (aLength) + { + someText++; + aLength--; + } + } + if (isWide) + return make_wide_character(someText, aLength); + else + return make_narrow_character(someText, aLength); +} + +CxxToken *make_identifier(const char *someText, size_t aLength) +{ + return new CxxNaffToken(PARSE_TOKEN(Identifier), someText, aLength); +} + +// +// Buffer the incoming line, before any characters are analysed. +// +void make_line(const char *yyText, size_t yyLeng) +{ + if (echo_line_text) + cout << tokenMarkDepth << ": " << line_number << ": " << yyText << flush; + else if (echo_line_numbers) + cout << line_number << endl; + line_number++ ; +} + +CxxToken *make_literal_character(const char *someText, size_t aLength) +{ + return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength); +} + +CxxToken *make_narrow_character(const char *someText, size_t aLength) +{ + return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength); +} + +CxxToken *make_narrow_string(const char *someText, size_t aLength) +{ + return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength); +} + +CxxToken *make_number(const char *someText, size_t aLength) +{ + return new CxxNaffToken(PARSE_TOKEN(IntegerLiteral), someText, aLength); +} + +// +// Configure the lexer to reflect successful parsing of a categorised string. +// +// The source someText[aLength] should correspond to the parsed text including any +// L or " prefix but excluding any " suffix. In this way the return can indicate whether a wide +// character has been detected and the routine can accommodate a variety of erroneous terminations. +// +CxxToken *make_string(const char *someText, size_t aLength) +{ + bool isWide = false; + if (someText && aLength) + { + if (*someText == 'L') + { + isWide = true; + someText++; + aLength--; + } + if (!aLength || (*someText != '"')) + ERRMSG("BUG - bad start of string literal."); + if (aLength) + { + someText++; + aLength--; + } + } + if (isWide) + return make_wide_string(someText, aLength); + else + return make_narrow_string(someText, aLength); +} + +// +// Return the appropriate 1 of 256 flyweight tokens for the ASCII characters. +// +CxxToken *make_token(size_t tokenValue) +{ + static CxxToken *asciiTokens[256]; + if (tokenValue >= (sizeof(asciiTokens)/sizeof(asciiTokens[0]))) + { + ERRMSG("Cannot make_token for " << tokenValue); + return 0; + } + CxxToken **p = &asciiTokens[tokenValue]; + CxxToken *theToken = *p; + if (!theToken) + *p = theToken = new CxxToken(tokenValue); + return theToken; +} + +CxxToken *make_wide_character(const char *someText, size_t aLength) +{ + return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength); +} + +CxxToken *make_wide_string(const char *someText, size_t aLength) +{ + return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength); +} +