Build Lex and Yacc¶
lex_yacc_library¶
Used to describe a lex yacc target, generate a scanner and a grammer for a compiler.
Lex and yacc are often be used together. when we compile a lex file, yy.tab.h is needed which is
generated by yacc. but when we compile yy.tab.cc which is generated from the yacc file. it call
the parse function which is generated by lex.
If we saparate them into 2 libraries, there will depends on each other, there is a loop dependency.
So we build the in one rule, the srcs must be a tuple of 2 elements, which are the lex and yacc file.
the suffix should be l and y for C code, and should be ll and yy for c++ result.
This rule will generate a library and a header file.
Attributes:
recursive=True— generate a reentrant C scanner.prefix='xxx'— rename theyysymbol prefix (passed as flex-P/ bison-p), so several parsers can coexist in one binary without theiryyparse/yylval/ ... globals colliding.lexflags=[...]/yaccflags=[...]— extra flags passed straight through to flex / bison. Note that flags which change the names of the generated files are not supported: blade derives those names by its own rule and will not see the override.
lex_yacc_library also support most cc_library attributes.
Example:
lex_yacc_library(
name = 'parser',
srcs = [
'line_parser.ll',
'line_parser.yy'
],
deps = [
":xcubetools",
],
recursive = True
)
The generated header¶
The header bison -d emits is named after the yacc source: <yacc_file>.hh
for a C++ grammar (.yy), or <yacc_file>.h for a C grammar (.y). For the
example above it is line_parser.yy.hh, and it declares the tokens and
yyparse.
A target that uses the parser includes it by its workspace-relative path, the same as any other generated header:
Including it is also what lets the header dependency check see that your target
genuinely uses the lex_yacc_library; relying only on the symbols (via your
own forward declarations) without including this header would make the
dependency look unused.