-
Notifications
You must be signed in to change notification settings - Fork 19
Description
When I change my grammar so that parol detects it needs to use box-types, it appears the type casting to user defined non-terminal types isn't happening as expected:
build.rs (I'm using minimize boxed types option)
fn main() {
// CLI equivalent is:
// parol -f ./modelica.par -e ./modelica-exp.par -p ./src/modelica_parser.rs -a ./src/modelica_grammar_trait.rs -t ModelicaGrammar -m modelica_grammar -g
if let Err(err) = Builder::with_explicit_output_dir("src")
.grammar_file("modelica.par")
.expanded_grammar_output_file("../modelica-exp.par")
.parser_output_file("modelica_parser.rs")
.actions_output_file("modelica_grammar_trait.rs")
.user_type_name("ModelicaGrammar")
.user_trait_module_name("modelica_grammar")
.trim_parse_tree()
.minimize_boxed_types()
.generate_parser()
{
ParolErrorReporter::report_error(&err, "modelica.par").unwrap_or_default();
process::exit(1);
}
}
crate::ir::ComponentReference
#[derive(Default, Clone)]
#[allow(unused)]
pub struct ComponentReference {
pub name: Vec<Token>,
pub node: NodeData,
}
Excerpt of grammar
primary
: unsigned_number
| string
| false
| true
// | ( component_reference | der | initial | pure ) function_call_args
| component_reference
// | '('^ output_expression_list ')' [ ( array_subscripts | '.'^ ident ) ]
// | '['^ expression_list { ';' expression_list } ']'^
// | '{'^ array_arguments '}'^
| end
;
array_subscripts :
'['^ subscript { ','^ subscript } ']'^
;
subscript :
':' | expression
;
works:
%nt_type component_reference = crate::ir::ComponentReference
...
component_reference
: [ '.'^ ] ident
//[ array_subscripts ]
{ '.'^ ident
[ array_subscripts ]
}
;
doesn't work:
%nt_type component_reference = crate::ir::ComponentReference
...
component_reference
: [ '.'^ ] ident
[ array_subscripts ]
{ '.'^ ident
[ array_subscripts ]
}
;
I think this second grammar with array_subscript option has expression which needs to be boxed, so causes reported issue.
If I adapt my modelica_grammar.rs code to use Box, it still doesn't compile as the try_into is not called before boxing. I suspect this might be a bug, but could also be user error :-).
Generated code without array_subscripts option:
/// Semantic action for production 200:
///
/// `primary: component_reference;`
///
#[parol_runtime::function_name::named]
fn primary_4(&mut self, _component_reference: &ParseTreeType<'t>) -> Result<()> {
let context = function_name!();
trace!("{}", self.trace_item_stack(context));
let component_reference = pop_item!(self, component_reference, ComponentReference, context);
let primary_4_built = PrimaryComponentReference {
component_reference: Box::new(component_reference),
};
let primary_4_built = Primary::ComponentReference(primary_4_built);
// Calling user action here
self.user_grammar.primary(&primary_4_built)?;
self.push(ASTType::Primary(primary_4_built), context);
Ok(())
}
Generated code with array_subscripts option:
/// Semantic action for production 200:
///
/// `primary: component_reference;`
///
#[parol_runtime::function_name::named]
fn primary_4(&mut self, _component_reference: &ParseTreeType<'t>) -> Result<()> {
let context = function_name!();
trace!("{}", self.trace_item_stack(context));
let component_reference = pop_item!(self, component_reference, ComponentReference, context);
let primary_4_built = PrimaryComponentReference {
component_reference: (&component_reference)
.try_into()
.map_err(parol_runtime::ParolError::UserError)?,
};
let primary_4_built = Primary::ComponentReference(primary_4_built);
// Calling user action here
self.user_grammar.primary(&primary_4_built)?;
self.push(ASTType::Primary(primary_4_built), context);
Ok(())
}
modelica_grammar.rs
impl TryFrom<&modelica_grammar_trait::Primary> for ir::Expression {
type Error = anyhow::Error;
fn try_from(ast: &modelica_grammar_trait::Primary) -> std::result::Result<Self, Self::Error> {
match &ast {
modelica_grammar_trait::Primary::ComponentReference(comp_ref) => Ok(
ir::Expression::ComponentReference(comp_ref.component_reference.clone()),
),
...
}
}
}
Full source code is here: https://github.com/cognipilot/rumoca_parol