Lex and Yacc

Lex and Yacc

Lex and Yacc A Quick Tour Lex (& Flex): A Lexical Analyzer Generator Input: Regular exprs defining "tokens" my.l Fragments of C decls & code Output: A C program "lex.yy.c" lex Use: lex.yy.c Compile & link with your main() Calls to yylex() return successive tokens. Yacc (& Bison & Byacc…): A Parser Generator Input: A context-free grammar Fragments of C declarations & code my.y Output: A C program & some header files yacc Use: y.tab.h y.tab.c Compile & link it with your main() Call yyparse() to parse the entire input file yyparse() calls yylex() to get successive tokens Lex Input: "mylexer.l" %{ #include … Declarations: int myglobal; To front of C … program Token %} code %% Rules [a-zA-Z]+ {handleit(); return 42; } and [ \t\n] {; /* skip whitespace */} Actions … %% Subroutines: void handleit() {…} To end of C … program S → E E → E+n | E-n | n Yacc Input: “expr.y” %{ C Decls #include … y.tab.c %} Yacc %token NUM VAR y.tab.h Decls %% stmt: exp { printf(”%d\n”,$1);} ; Rules exp : exp ’+’ NUM { $$ = $1 + $3; } and | exp ’-’ NUM { $$ = $1 - $3; } Actions | NUM { $$ = $1; } ; %% Subrs … y.tab.c Expression lexer: “expr.l” %{ y.tab.h: #include "y.tab.h" #define NUM 258 #define VAR 259 #define YYSTYPE int %} extern YYSTYPE yylval; %% [0-9]+ { yylval = atoi(yytext); return NUM;} [ \t] { /* ignore whitespace */ } \n { return 0; /* logical EOF */ } . { return yytext[0]; /* +-*, etc. */ } %% yyerror(char *msg){printf("%s,%s\n",msg,yytext);} int yywrap(){return 1;} Lex/Yacc Interface: Compile Time my.y my.l my.c yacc y.tab.h lex y.tab.c lex.yy.c gcc myprog Lex/Yacc Interface: Run Time main() yyparse() e d o yylex() yylval c n e k Myaction: o T ... Token value yylval = ... ... return(code) Some C Tidbits Enums Malloc enum kind { root.rchild = (node_t*) title_kind,center_kind}; malloc(sizeof(node_t)); typedef struct node_s{ enum kind k; Unions struct node_s typedef union { *lchild,*rchild; double d; char *text; int i; } YYSTYPE; } node_t; extern YYSTYPE yylval; node_t root; yylval.d = 3.14; root.k = title_kind; yylval.i = 3; if(root.k==title_kind){…} More Yacc Declarations %union { Type of yylval node_t *node; char *str; } Token %token <str> BHTML BHEAD BTITLE BBODY BCENTER names & %token <str> EHTML EHEAD ETITLE EBODY ECENTER types %token <str> P BR LI TEXT Nonterm names & %type <node> page head title words body types %type <node> heading list center item items Start sym %start page Yacc In Action PDA stack: alternates between "states" and symbols from (V ∪ Σ). initially, push state 0 while not done { let S be the state on top of the stack; let i be the next input symbol (i in Σ); look at the the action defined in S for i: if "accept", halt and accept; if "error", halt and signal a syntax error; if "shift to state T", push i then T onto the stack; if "reduce via rule r (A → α )", then: pop exactly 2*|α| symbols (the 1st, 3rd, ... will be states, and the 2nd, 4th, ... will be the letters of α); let T = the state now exposed on top of the stack; T's action for A is "goto state U" for some U; push A, then U onto the stack. } Implementation note: given the tables, it's deterministic, and fast -- just table lookups, push/pop..

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    11 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us