blob: 9101af143a33308161d4774120b46d9ef7d8e894 [file] [log] [blame]
def genlex(name, src, out, includes = []):
"""Generate a C++ lexer from a lex file using Flex.
Args:
name: The name of the rule.
src: The .lex source file.
out: The generated source file.
includes: A list of headers included by the .lex file.
"""
cmd = "$(LEX) -o $(@D)/%s $(location %s)" % (out, src)
native.genrule(
name = name,
outs = [out],
srcs = [src] + includes,
cmd = cmd,
toolchains = ["@io_kythe//tools/build_rules/lexyacc:current_lexyacc_toolchain"],
)
def genyacc(name, src, header_out, source_out, extra_outs = []):
"""Generate a C++ parser from a Yacc file using Bison.
Args:
name: The name of the rule.
src: The input grammar file.
header_out: The generated header file.
source_out: The generated source file.
extra_outs: Additional generated outputs.
"""
cmd = "$(YACC) -o $(@D)/%s $(location %s)" % (source_out, src)
native.genrule(
name = name,
outs = [source_out, header_out] + extra_outs,
srcs = [src],
cmd = cmd,
toolchains = ["@io_kythe//tools/build_rules/lexyacc:current_lexyacc_toolchain"],
)
LexYaccInfo = provider(
doc = "Paths to lex and yacc binaries.",
fields = ["lex", "yacc"],
)
def _lexyacc_variables(ctx):
lyinfo = ctx.toolchains["@io_kythe//tools/build_rules/lexyacc:toolchain_type"].lexyaccinfo
return [
platform_common.TemplateVariableInfo({
"LEX": lyinfo.lex,
"YACC": lyinfo.yacc,
}),
]
lexyacc_variables = rule(
implementation = _lexyacc_variables,
toolchains = ["@io_kythe//tools/build_rules/lexyacc:toolchain_type"],
)
def _lexyacc_toolchain_impl(ctx):
return [
platform_common.ToolchainInfo(
lexyaccinfo = LexYaccInfo(
lex = ctx.attr.lex,
yacc = ctx.attr.yacc,
),
),
]
_lexyacc_toolchain = rule(
implementation = _lexyacc_toolchain_impl,
attrs = {
"lex": attr.string(),
"yacc": attr.string(),
},
provides = [
platform_common.ToolchainInfo,
],
)
def lexyacc_toolchain(name, lex, yacc):
_lexyacc_toolchain(name = name, lex = lex, yacc = yacc)
native.toolchain(
name = name + "_toolchain",
toolchain = ":" + name,
toolchain_type = "@io_kythe//tools/build_rules/lexyacc:toolchain_type",
)
def _local_lexyacc(repository_ctx):
flex = repository_ctx.which("flex")
if flex == None:
fail("Unable to find flex binary")
bison = repository_ctx.os.environ.get("BISON", repository_ctx.which("bison"))
if not bison:
fail("Unable to find bison binary")
repository_ctx.file(
"WORKSPACE",
content = "workspace(name=\"%s\")" % (repository_ctx.name,),
executable = False,
)
repository_ctx.file(
"BUILD.bazel",
content = "\n".join([
"load(\"@io_kythe//tools/build_rules/lexyacc:lexyacc.bzl\", \"lexyacc_toolchain\")",
"package(default_visibility=[\"//visibility:public\"])",
"lexyacc_toolchain(",
" name = \"lexyacc_local\",",
" lex = \"%s\"," % flex,
" yacc = \"%s\"," % bison,
")",
]),
)
local_lexyacc_repository = repository_rule(
implementation = _local_lexyacc,
local = True,
environ = ["PATH", "BISON"],
)
def lexyacc_configure():
local_lexyacc_repository(name = "local_config_lexyacc")
native.register_toolchains(
"@local_config_lexyacc//:lexyacc_local_toolchain",
)