20230322
[shlib.git] / sample / lxgr / lxr.l
blob37b0d6f831d7b74bec48cbc900510dde7bb3fcee
1 /*
2 ##############################################################################
3 # lxr.l
4 #    this file list token (rsv-word/signature), normal word, quated string, and
5 # append processing code after it if it needed.
6 #    generally, those content should be defined:
7 # charset: fundamental char set name.
8 # blank/newline: ignore blank, or recognized in other defination. record 
9 #    newline.
10 # comment:
11 # maskchar: char of "\". some will process it in quated string, but some will
12 #    process it in code as a mask char.
13 # word: general word.
14 # symbol: it can be used for variable name.
15 # rsv-word(token): some fixed word defined as token.
16 # signature(token): punct char set.
17 # quatedstr: quated string with ", ', `.
18 # specialchar: such as $ in shell.
19 # EOF: file terminator processing.
20 # <some-others>: some particular content.
21 #    rsv-word/signature/specialchar can be defined in other place. in code, or
22 # another lxr define file.
23 #    lexer processing variables define.
24 # yytext, yyleng: current matching string pointer
25 #     and length.
26 # yylval: 
27 # unput(yytext[0]): put a char back to original processing content.
28 # BEGIN(COMMAND): entering state. INITIAL is the default state.
29 ##############################################################################
32 // define T_WORD, T_TOKEN
35 // [lxr-charset]
36 t       [[:graph:]]
37 a       [[:alpha:]_]
38 n       [A-Za-z0-9_]
39 s       [[:punct:]]
41 // [lxr-token]
43 \\.                     {
44         // mask char
48  * blank & newline
49  */
50 [[:blank:]]*
51 [[:blank:]]*\n  {
52         return T_EOL;
56  * comment, sh-lang and c style.
57  */
58 [ \t]*#.*
59 [[:blank:]]*#.*\n       {
60         return T_EOL;
62 [[:blank:]]*//.*\n      {
63         return T_EOL;
65 [[:blank:]]*/\* {
66         BEGIN(COMMENT)
67         cmnt_flag=0;
69 /* C89 style comment */
70 <COMMENT>{
71         [^*/]*  {
72                 //append_string(yytext, yyleng);
73                 if (strstr(yytext, "\n") == 0)
74                 {
75                         cmnt_flag=1
76                 }
77         }
78         \*/     {
79                         BEGIN(INITIAL);
80                         last="T_COMMENT";
81                         //return T_COMMENT;
82                         if (cmnt_flag == 1)
83                         {
84                                 /* if comment is multi line, return as a T_EOL. */
85                                 return T_EOL;
86                         }
87         }
88         \*      {
89                 // append_string("*", 1);
90                 ;
91         }
92         /       {
93                 // append_string("*", 1);
94                 ;
95         }
96         <<EOF>> {
97                 ; // err
98         }
102  * signature token define.
103  */
105 "<"                     { last="<"; return T_LANGLE; }
106 ">"                     { last=">"; return T_RANGLE; }
107 "{"                     { last="{"; return T_LBRACE; }
108 "}"                     { last="}"; return T_RBRACE; }
109 "["                     { last="["; return T_LBRACKET; }
110 "]"                     { last="]"; return T_RBRACKET; }
114  * signature token define.
115  */
116 {g}+    {
117         const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
118         current_pos.file = current_file;
119         current_pos.lineno = yylineno;
120         if (id && id->flags & TF_COMMAND) {
121                 yylval.id = id;
122                 return id->token;
123         }
124         alloc_string(yytext, yyleng);
125         yylval.string = text;
126         last="T_WORD";
127         return T_WORD;
130  * symbol word or rsv-word.
131  */
132 {a}{n}+ {
133         const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
134         current_pos.file = current_file;
135         current_pos.lineno = yylineno;
136         if (id && id->flags & TF_COMMAND) {
137                 yylval.id = id;
138                 return id->token;
139         }
140         alloc_string(yytext, yyleng);
141         yylval.string = text;
142         last="T_WORD";
143         return T_WORD;
146  * normal word.
147  */
148 {n}+    {
149         const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
150         current_pos.file = current_file;
151         current_pos.lineno = yylineno;
152         if (id && id->flags & TF_COMMAND) {
153                 yylval.id = id;
154                 return id->token;
155         }
156         alloc_string(yytext, yyleng);
157         yylval.string = text;
158         last="T_WORD";
159         return T_WORD;
162  * string word.
163  * text without blanks, and include none-blank display char.
164  */
165 [[:space:]]{t}+[[:space:]]      {
166         const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
167         current_pos.file = current_file;
168         current_pos.lineno = yylineno;
169         if (id && id->flags & TF_COMMAND) {
170                 yylval.id = id;
171                 return id->token;
172         }
173         alloc_string(yytext, yyleng);
174         yylval.string = text;
175         last="T_WORD";
176         return T_WORD;
178 .       warn_ignored_character(*yytext);
179 \n      {
180         BEGIN(INITIAL);
181         return T_EOL;
186 \"|\'           {
187         str = yytext[0];
188         new_string();
189         BEGIN(STRING);
191 /* single line string just for symbol */
192 <STRING>{
193         [^'"\\]*        {
194                 append_string(yytext, yyleng);
195         }
196         \\.?    {
197                 /* '\' mask signature */
198                 append_string(yytext + 1, yyleng - 1);
199         }
200         \'|\"   {
201                 if (str == yytext[0]) {
202                         BEGIN(INITIAL);
203                         yylval.string = text;
204                         last="T_WORD_QUOTE";
205                         return T_WORD_QUOTE;
206                 } else
207                         append_string(yytext, 1);
208         }
209         <<EOF>> {
210                 ; // err
211         }
214 /* 
215  * multi-line string for code block.
216  * entering this state by function enter_state("BLOCK").
217  */
218 [[:space:]]\{[[:space:]]                {
219         if ((strcmp (last, ">") == 0)
220         {
221                 // BRACE in state define
222                 last="T_LBRACE";
223                 return T_LBRACE;
224         }
225         else
226         {
227                 // it's a response code of lex define.
228                 str = yytext[0];
229                 new_string();
230                 append_string("{\n", 2);
231                 // entering block
232                 BEGIN(BLOCK);
233         }
236  * entering from "[[:space:]]\{[[:space:]]", and end with
237  * "[[:space:]]\}[[:space:]]". append string with "[^\{\}]*".
238  * since the single "{" or "}" should be recognized, this
239  * will avoid "}" mis-matching with multi "{}" pair in block.
240  * so, the ending "}" should be matching with 
241  * "[^\{\}]*[[:space:]]\}[[:space:]]". if mathcing "[^\{\}]*"
242  * and "[[:space:]]\}[[:space:]]" seperatly, "[^\{\}]*" will
243  * matching with "[[:space:]]", which is before "}", then,
244  * "[[:space:]]\}[[:space:]]" is not matched, but "}" is matched.
245  * if put checking code in "}" process code,
246  */
247 <BLOCK>{
248         /*
249          * code block is terminated with a } and a newline, whatever
250          * there are comments between them.
251          */
252         [^\{\}]*[[:space:]]\}[[:space:]]*(\#[^\n]*)?\n          {
253                 append_string(yytext, yyleng);
254                 if (stk_empty())
255                 {
256                         zconf_endblock();
257                         BEGIN(INITIAL);
258                         return T_BLOCKTEXT;
259                 }
260                 else
261                         c=stk_pop();
262         }
263         [^\{\}]*        {
264                 append_string(yytext, yyleng);
265         }
266         \{      {
267                 append_string("{", 1);
268                 stk_push('{');
269         }
270         \}      {
271                 if (stk_empty())
272                 {
273                         /*
274                          * should not entering here.
275                          * it means there are no "[[:space:]]" char matching before "{".
276                          * or, it will matching the first item of syntax define.
277                          */
278                         //dbgout("there must be blank char before and after '}'.\n");
279                         append_string("\n}", 2);
280                         zconf_endblock();
281                         BEGIN(INITIAL);
282                         return T_BLOCKTEXT;
283                 }
284                 else
285                 {
286                         append_string("}", 1);
287                         c=stk_pop();
288                 }
289         }
292 <<EOF>> {
293         if (current_file) {
294                 zconf_endfile();
295                 return T_EOL;
296         }
297         fclose(yyin);
298         yyterminate();