better noise at runtime
[feisty_meow.git] / infobase / examples / cpp_grammar_code / CxxLexing.cxx
1 #ifdef FLEX_PP_CLASS
2 FLEX_PP_CLASS theLexer;
3 #define LEX_DOT theLexer .
4 #else
5 #define LEX_DOT
6 #endif
7
8 bool c_keywords = false;
9 bool echo_line_numbers = false;
10 bool echo_line_text = false;
11 size_t line_number = 0;
12
13 #ifdef NEEDS_YYWRAP
14 int yywrap() { return 1; }
15 #endif
16
17 CxxToken *yylex_token()
18 {
19         if (!LEX_DOT yylex())
20                 return 0;
21         return yyToken;
22 }
23
24 //
25 //      Configure the lexer to reflect successful parsing of a character value, assigning it to yylval.
26 //
27 //      The source someText[aLength] should correspond to the parsed text including any L or ' prefix
28 //      but excluding any ' suffix. In this way the return can indicate whether a wide character has
29 //      been detected and the routine can accommodate a variety of erroneous terminations.
30 //
31 CxxToken *make_character(const char *someText, size_t aLength)
32 {
33         bool isWide = false;
34         if (someText && aLength)
35         {
36                 if (*someText == 'L')
37                 {
38                         isWide = true;
39                         someText++;
40                         aLength--;
41                 }
42                 if (!aLength || (*someText != '\''))
43                         ERRMSG("BUG - bad start of character literal.");
44                 if (aLength)
45                 {
46                         someText++;
47                         aLength--;
48                 }
49         }
50         if (isWide)
51                 return make_wide_character(someText, aLength);
52         else
53                 return make_narrow_character(someText, aLength);
54 }
55
56 CxxToken *make_identifier(const char *someText, size_t aLength)
57 {
58         return new CxxNaffToken(PARSE_TOKEN(Identifier), someText, aLength);
59 }
60
61 //
62 //      Buffer the incoming line, before any characters are analysed.
63 //
64 void make_line(const char *yyText, size_t yyLeng)
65 {
66         if (echo_line_text)
67                 cout << tokenMarkDepth << ": "  << line_number << ": " << yyText << flush; 
68         else if (echo_line_numbers)
69                 cout << line_number << endl; 
70         line_number++ ; 
71 }
72
73 CxxToken *make_literal_character(const char *someText, size_t aLength)
74 {
75         return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
76 }
77
78 CxxToken *make_narrow_character(const char *someText, size_t aLength)
79 {
80         return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
81 }
82
83 CxxToken *make_narrow_string(const char *someText, size_t aLength)
84 {
85         return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
86 }
87
88 CxxToken *make_number(const char *someText, size_t aLength)
89 {
90         return new CxxNaffToken(PARSE_TOKEN(IntegerLiteral), someText, aLength);
91 }
92
93 //
94 //      Configure the lexer to reflect successful parsing of a categorised string.
95 //
96 //      The source someText[aLength] should correspond to the parsed text including any
97 //      L or " prefix but excluding any " suffix. In this way the return can indicate whether a wide
98 //      character has been detected and the routine can accommodate a variety of erroneous terminations.
99 //
100 CxxToken *make_string(const char *someText, size_t aLength)
101 {
102         bool isWide = false;
103         if (someText && aLength)
104         {
105                 if (*someText == 'L')
106                 {
107                         isWide = true;
108                         someText++;
109                         aLength--;
110                 }
111                 if (!aLength || (*someText != '"'))
112                         ERRMSG("BUG - bad start of string literal.");
113                 if (aLength)
114                 {
115                         someText++;
116                         aLength--;
117                 }
118         }
119         if (isWide)
120                 return make_wide_string(someText, aLength);
121         else
122                 return make_narrow_string(someText, aLength);
123 }
124
125 //
126 //      Return the appropriate 1 of 256 flyweight tokens for the ASCII characters.
127 //
128 CxxToken *make_token(size_t tokenValue)
129 {
130         static CxxToken *asciiTokens[256];
131         if (tokenValue >= (sizeof(asciiTokens)/sizeof(asciiTokens[0])))
132         {
133                 ERRMSG("Cannot make_token for " << tokenValue);
134                 return 0;
135         }
136         CxxToken **p = &asciiTokens[tokenValue];
137         CxxToken *theToken = *p;
138         if (!theToken)
139                 *p = theToken = new CxxToken(tokenValue);
140         return theToken;
141 }
142
143 CxxToken *make_wide_character(const char *someText, size_t aLength)
144 {
145         return new CxxNaffToken(PARSE_TOKEN(CharacterLiteral), someText, aLength);
146 }
147
148 CxxToken *make_wide_string(const char *someText, size_t aLength)
149 {
150         return new CxxNaffToken(PARSE_TOKEN(StringLiteral), someText, aLength);
151 }
152