use std::path::PathBuf;
use clap::{ArgAction, Parser};
use rustemo::WARN;
use rustemo_compiler::{
BuilderType, GeneratorTableType, LexerType, ParserAlgo, Settings, TableType,
};
use yansi::Paint;
#[derive(Parser)]
#[cfg_attr(feature="bootstrap",
clap(version = concat!(concat!(env!("CARGO_PKG_VERSION"),
env!("GIT_HASH")), "-bootstrap")))]
#[cfg_attr(not(feature="bootstrap"),
clap(version = concat!(env!("CARGO_PKG_VERSION"), env!("GIT_HASH"))))]
#[clap(author, about, long_about = None)]
struct Cli {
#[clap(short, long, action)]
force: bool,
#[clap(long, action)]
dot: bool,
#[clap(short, long, action)]
noactions: bool,
#[clap(long, action)]
trace: bool,
#[clap(value_parser, value_name="GRAMMAR FILE/DIR", value_hint = clap::ValueHint::AnyPath)]
grammar_file_or_dir: PathBuf,
#[clap(short, long, value_name="OUT DIR ROOT", value_hint = clap::ValueHint::DirPath)]
outdir_root: Option<PathBuf>,
#[clap(short='a', long, value_name="OUT DIR ACTIONS ROOT", value_hint = clap::ValueHint::DirPath)]
outdir_actions_root: Option<PathBuf>,
#[clap(long)]
prefer_shifts: bool,
#[clap(long)]
no_shifts_over_empty: bool,
#[clap(short, long, value_enum, default_value_t)]
table_type: TableType,
#[clap(short, long, value_enum, default_value_t)]
parser_algo: ParserAlgo,
#[clap(short, long, value_enum, default_value_t)]
generator_table_type: GeneratorTableType,
#[clap(short, long, value_enum, default_value_t)]
lexer_type: LexerType,
#[clap(short, long, default_value = "str")]
input_type: String,
#[clap(short, long, value_enum, default_value_t)]
builder_type: BuilderType,
#[clap(long)]
builder_loc_info: bool,
#[clap(long, default_missing_value = "true", require_equals = true)]
lexical_disamb_most_specific: Option<bool>,
#[clap(long, default_missing_value = "true", require_equals = true)]
lexical_disamb_longest_match: Option<bool>,
#[clap(long, default_missing_value = "true", require_equals = true)]
lexical_disamb_grammar_order: Option<bool>,
#[clap(long)]
fancy_regex: bool,
#[clap(long)]
partial_parse: bool,
#[clap(long)]
no_skip_ws: bool,
#[clap(long)]
print_table: bool,
#[clap(short, long, value_parser)]
exclude: Vec<String>,
#[clap(short, long, action = ArgAction::Count)]
verbosity: u8,
}
fn main() {
let cli = Cli::parse();
let mut settings = Settings::new()
.force(cli.force)
.dot(cli.dot)
.actions(!cli.noactions)
.trace(cli.trace)
.exclude(cli.exclude)
.prefer_shifts(cli.prefer_shifts)
.prefer_shifts_over_empty(!cli.no_shifts_over_empty)
.fancy_regex(cli.fancy_regex)
.partial_parse(cli.partial_parse)
.skip_ws(!cli.no_skip_ws)
.table_type(cli.table_type)
.print_table(cli.print_table)
.parser_algo(cli.parser_algo)
.generator_table_type(cli.generator_table_type)
.lexer_type(cli.lexer_type)
.builder_type(cli.builder_type)
.builder_loc_info(cli.builder_loc_info)
.input_type(cli.input_type);
if let Some(most_specific) = cli.lexical_disamb_most_specific {
settings = settings.lexical_disamb_most_specific(most_specific)
}
if let Some(longest_match) = cli.lexical_disamb_longest_match {
settings = settings.lexical_disamb_longest_match(longest_match)
}
if let Some(grammar_order) = cli.lexical_disamb_grammar_order {
settings = settings.lexical_disamb_grammar_order(grammar_order)
}
if let Some(outdir_root) = cli.outdir_root {
settings = settings.out_dir_root(outdir_root);
}
if let Some(outdir_actions_root) = cli.outdir_actions_root {
settings = settings.out_dir_actions_root(outdir_actions_root);
}
let result = if cli.grammar_file_or_dir.is_file() {
settings.process_grammar(&cli.grammar_file_or_dir)
} else {
settings.root_dir(cli.grammar_file_or_dir).process_dir()
};
if let Err(e) = result {
println!("{e}");
println!("{}", "Parser(s) not generated.".paint(WARN));
}
}