Lex & YACC
Ref: Lex与YACC详解
1. Lex
Lex is a computer program that generates lexical analyzers.
e.g.1
%{
#include <stdio.h>
%}
%%
[0123456789]+ printf("NUMBER\n");
[a-zA-Z][a-zA-Z0-9]* printf("WORD\n");
lex eg.l
cc lex.yy.c –o test –ll
./test
e.g.2
%{
#include <stdio.h>
%}
%%
[a-zA-Z][a-zA-Z0-9]* printf("WORD ");
[a-zA-Z0-9\/.-]+ printf("FILENAME ");
\" printf("QUOTE ");
\{ printf("OBRACE ");
\} printf("EBRACE ");
; printf("SEMICOLON ");
\n printf("\n");
[ \t]+ /* ignore whitespace */;
%%
File to parse:
logging{
category lame-servers { null; };
category cname { null; };
};
zone "." {
type hint;
file "/etc/bind/db.root";
}
2. YACC
Yet Another Compiler-Compiler is a Look Ahead Left-to-Right (LALR) parser generator, generating a LALR parser (the part of a compiler that tries to make syntactic sense of the source code) based on a formal grammar.
// temp.l
%{
#include <stdio.h>
#include "y.tab.h"
%}
%%
[0-9]+ yylval = atoi(yytext); return NUMBER;
heat return TOKHEAT;
on|off yylval = !strcmp(yytext, "on"); return STATE;
target return TOKTARGET;
temperature return TOKTEMPERATURE;
\n /* ignore end of line */
[ \t]+ /* ignore whitespace */
%%
// temp.y
%{
#include <stdio.h>
#include <string.h>
//在lex.yy.c里定义,会被yyparse()调用。在此声明消除编译和链接错误。
extern int yylex(void);
// 在此声明,消除yacc生成代码时的告警
extern int yyparse(void);
int yywrap()
{
return 1;
}
// 该函数在y.tab.c里会被调用,需要在此定义
void yyerror(const char *s)
{
printf("[error] %s\n", s);
}
int main()
{
yyparse();
return 0;
}
%}
%token NUMBER TOKHEAT STATE TOKTARGET TOKTEMPERATURE
%%
commands: /* empty */
| commands command
;
command: heat_switch | target_set ;
heat_switch:
TOKHEAT STATE
{
if ($2)
printf("\tHeat turned on\n");
else
printf("\tHeat turned off\n");
}
target_set:
TOKTARGET TOKTEMPERATURE NUMBER
{
printf("\tTemperature set to %d\n", $3);
};
%%
Commands:
❯ ./a.out
heat on
Heat turned on
target temperature 10
Temperature set to 10
Last update:
September 22, 2021
Authors: