re: lex question

Sukru Cinar <scinar@ug.bcc.bilkent.edu.tr>
18 Apr 1999 02:05:44 -0400

          From comp.compilers

Related articles
lex question alinares@fivetech.com (Antonio Linares) (1999-03-23)
re: lex question scinar@ug.bcc.bilkent.edu.tr (Sukru Cinar) (1999-04-18)
| List of all articles for this month |
From: Sukru Cinar <scinar@ug.bcc.bilkent.edu.tr>
Newsgroups: comp.compilers
Date: 18 Apr 1999 02:05:44 -0400
Organization: Bilkent University
References: 99-03-077
Keywords: C, parse

>We are looking for a way to implement C language #define directive
>for >expressions:
>
> #define <idFunction>([<arg list>]) [<exp>]


There'S Some Way Of Doing It That I Can Propose: For "#Define"Ing, You Can
Use Lex'S Start Condition Rules, Or You Can Implement Them Yourself By
Means Of A Flag Which Determines If We'Re Parsing A #Define Directive Or
Text Subject To Macro-Expansion. You May Set The Flag When You Encounter
A #Define And Clear It After A Newline. You Can Add A Conditional
Statement To Actions Of All Lexemes That Can Be Included Inside A
Macro Definition Something Like


if( we_re_parsing_a_define_rule ) add_this_token_to_define_directive();


For Expanding Macros You Can Do This: When You Expand Some Macro,
You Can Feed The Resultant Text Back Into The Lexer Again. This Way You
Will Be Able To Use Other Macros Inside Macro Calls. To Recognize A Macro
Call, You Can Have A Rule In Your Lexer Such As :


[a-zA-Z]+ { if(yytext_is_in_hashtable()) start_expand_macro(); else
pass_it_through();}


Of Course, You Must Create An Entry In The Hash Table Everytime You See
A #Define Directive. Here, As You See, We Don'T Make Lex Recognize A Macro
Call And Take An Action: We'Re Doing It Ourselves By Means Of A Hash
Table. Another Solution Could Be Making Some Sort Of "Dynamic Lex" By
Using The Rx Library But It Would Be Much More Complex And Probably
Slower.


About Feeding The Expanded Text Back Into The Lexer, You May Use Lex'S
yy_read_buffer() Or yy_read_string() (I'M Not Sure Of The Names) If The
Architecture Of Your Program Suits Or You Can Define The Macro YYINPUT
(Again, Check The Name) In Your Lexer. Lex Uses This Macro To Read A
Buffer From Disk, If You Define It, You Can Get It To Read From Your
Buffer. When Doing So, You Shall Also Call The yy_create_buffer() And
yy_switch_buffer() Functions Of The Lex Library And You Shall Save The
Current State Of Buffer To A Stack. When The Current Buffer Ends, You Can
Pop The State Of The Lex Buffer And Destroy The Old Buffer. To Detect When
A Buffer Ends, You Can Have An <<EOF>> Rule In Your Lexer.(I Don'T Know If
Lex Has This But Flex Does).


About Passing Parameters To A Macro Call: You Can Use Yacc, But I Think
Writing A Small Parser By Hand Shan'T Be Too Difficult.


This Text Has Been A Bit Lengthy And Implementation-Specific But I Hope It
Helps.


Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.