trim
[build-config.git] / shlib / lxr.l
blob33f9d4a7dc13b0961a786f3982c029c7da831fac
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       [^[:space:]]
37 a       [[:alpha:]]
38 n       [A-Za-z0-9_]
39 s       [[:punct:]]
41 // [lxr-token]
44  * blank & newline
45  */
46 [[:blank:]]*
47 [[:blank:]]*\n  {
48         return T_EOL;
52  * comment, sh-lang and c style.
53  */
54 [ \t]*#.*
55 [[:blank:]]*#.*\n       {
56         return T_EOL;
58 [[:blank:]]*//.*\n      {
59         return T_EOL;
61 [[:blank:]]*/\* {
62         BEGIN(COMMENT)
63         cmnt_flag=0;
65 /* C89 style comment */
66 <COMMENT>{
67         [^*/]*  {
68                 //append_string(yytext, yyleng);
69                 if (strstr(yytext, "\n") == 0)
70                 {
71                         cmnt_flag=1
72                 }
73         }
74         \*/     {
75                         BEGIN(INITIAL);
76                         last="T_COMMENT";
77                         //return T_COMMENT;
78                         if (cmnt_flag == 1)
79                         {
80                                 /* if comment is multi line, return as a T_EOL. */
81                                 return T_EOL;
82                         }
83         }
84         \*      {
85                 // append_string("*", 1);
86                 ;
87         }
88         /       {
89                 // append_string("*", 1);
90                 ;
91         }
92         <<EOF>> {
93                 ; // err
94         }
98  * signature token define.
99  */
100 "<"                     { last="<"; return T_LANGLE; }
101 ">"                     { last=">"; return T_RANGLE; }
102 "{"                     { last="{"; return T_LBRACE; }
103 "}"                     { last="}"; return T_RBRACE; }
104 "["                     { last="["; return T_LBRACKET; }
105 "]"                     { last="]"; return T_RBRACKET; }
108  * signature token define.
109  */
110 {s}+    {
111         const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
112         current_pos.file = current_file;
113         current_pos.lineno = yylineno;
114         if (id && id->flags & TF_COMMAND) {
115                 yylval.id = id;
116                 return id->token;
117         }
118         alloc_string(yytext, yyleng);
119         yylval.string = text;
120         last="T_WORD";
121         return T_WORD;
124  * symbol word or rsv-word.
125  */
126 {a}{n}+ {
127         const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
128         current_pos.file = current_file;
129         current_pos.lineno = yylineno;
130         if (id && id->flags & TF_COMMAND) {
131                 yylval.id = id;
132                 return id->token;
133         }
134         alloc_string(yytext, yyleng);
135         yylval.string = text;
136         last="T_WORD";
137         return T_WORD;
140  * normal word.
141  */
142 {n}+    {
143         const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
144         current_pos.file = current_file;
145         current_pos.lineno = yylineno;
146         if (id && id->flags & TF_COMMAND) {
147                 yylval.id = id;
148                 return id->token;
149         }
150         alloc_string(yytext, yyleng);
151         yylval.string = text;
152         last="T_WORD";
153         return T_WORD;
156  * string word.
157  * text without blanks, and include none-blank display char.
158  */
159 [[:space:]]{t}+[[:space:]]      {
160         const struct kconf_id *id = kconf_id_lookup(yytext, yyleng);
161         current_pos.file = current_file;
162         current_pos.lineno = yylineno;
163         if (id && id->flags & TF_COMMAND) {
164                 yylval.id = id;
165                 return id->token;
166         }
167         alloc_string(yytext, yyleng);
168         yylval.string = text;
169         last="T_WORD";
170         return T_WORD;
172 .       warn_ignored_character(*yytext);
173 \n      {
174         BEGIN(INITIAL);
175         return T_EOL;
178 \\.                     {
179         // mask char
182 \"|\'           {
183         str = yytext[0];
184         new_string();
185         BEGIN(STRING);
187 /* single line string just for symbol */
188 <STRING>{
189         [^'"\\]*        {
190                 append_string(yytext, yyleng);
191         }
192         \\.?    {
193                 /* '\' mask signature */
194                 append_string(yytext + 1, yyleng - 1);
195         }
196         \'|\"   {
197                 if (str == yytext[0]) {
198                         BEGIN(INITIAL);
199                         yylval.string = text;
200                         last="T_WORD_QUOTE";
201                         return T_WORD_QUOTE;
202                 } else
203                         append_string(yytext, 1);
204         }
205         <<EOF>> {
206                 ; // err
207         }
210 /* 
211  * multi-line string for code block.
212  * entering this state by function enter_state("BLOCK").
213  */
214 [[:space:]]\{[[:space:]]                {
215         if ((strcmp (last, ">") == 0)
216         {
217                 // BRACE in state define
218                 last="T_LBRACE";
219                 return T_LBRACE;
220         }
221         else
222         {
223                 // it's a response code of lex define.
224                 str = yytext[0];
225                 new_string();
226                 append_string("{\n", 2);
227                 // entering block
228                 BEGIN(BLOCK);
229         }
232  * entering from "[[:space:]]\{[[:space:]]", and end with
233  * "[[:space:]]\}[[:space:]]". append string with "[^\{\}]*".
234  * since the single "{" or "}" should be recognized, this
235  * will avoid "}" mis-matching with multi "{}" pair in block.
236  * so, the ending "}" should be matching with 
237  * "[^\{\}]*[[:space:]]\}[[:space:]]". if mathcing "[^\{\}]*"
238  * and "[[:space:]]\}[[:space:]]" seperatly, "[^\{\}]*" will
239  * matching with "[[:space:]]", which is before "}", then,
240  * "[[:space:]]\}[[:space:]]" is not matched, but "}" is matched.
241  * if put checking code in "}" process code,
242  */
243 <BLOCK>{
244         /*
245          * code block is terminated with a } and a newline, whatever
246          * there are comments between them.
247          */
248         [^\{\}]*[[:space:]]\}[[:space:]]*(\#[^\n]*)?\n          {
249                 append_string(yytext, yyleng);
250                 if (stk_empty())
251                 {
252                         zconf_endblock();
253                         BEGIN(INITIAL);
254                         return T_BLOCKTEXT;
255                 }
256                 else
257                         c=stk_pop();
258         }
259         [^\{\}]*        {
260                 append_string(yytext, yyleng);
261         }
262         \{      {
263                 append_string("{", 1);
264                 stk_push('{');
265         }
266         \}      {
267                 if (stk_empty())
268                 {
269                         /*
270                          * should not entering here.
271                          * it means there are no "[[:space:]]" char matching before "{".
272                          * or, it will matching the first item of syntax define.
273                          */
274                         //dbgout("there must be blank char before and after '}'.\n");
275                         append_string("\n}", 2);
276                         zconf_endblock();
277                         BEGIN(INITIAL);
278                         return T_BLOCKTEXT;
279                 }
280                 else
281                 {
282                         append_string("}", 1);
283                         c=stk_pop();
284                 }
285         }
288 <<EOF>> {
289         if (current_file) {
290                 zconf_endfile();
291                 return T_EOL;
292         }
293         fclose(yyin);
294         yyterminate();