Parenthesized expressions question

SyntaxEditor for WPF Forum

Posted 3 years ago by Laif Harwood
Version: 17.2.0
Avatar

Below is a code snippet from the grammar in your sample application that shows how to define an expression. It is a pattern we've followed for other types of expression in our language.

expression.Production = equalityExpression["exp"] > AstFrom("exp");

// Outputs the resulting node from the AdditiveExpression; or if an equality operator is found, 
//   outputs a '==' or '!=' node whose children are the left and right child expressions of the operator
equalityExpression.Production = additiveExpression["leftexp"] + (
	(
		@equality > Ast(OperatorKind.Equality.ToString()) 
		| @inequality > Ast(OperatorKind.Inequality.ToString())
	).SetLabel("op") + equalityExpression["rightexp"].OnErrorContinue()).Optional()
	> AstLeftAssociativity<Expression, BinaryOperatorExpression>(
		AstConditional<BinaryOperatorExpression>(AstFrom("leftexp"), AstFrom("rightexp"))
			.SetProperty(e => e.Operator, AstFrom("op"))
			.SetProperty(e => e.LeftExpression, AstFrom("leftexp"))
			.SetProperty(e => e.RightExpression, AstFrom("rightexp")),
		n => n.LeftExpression,
		n => n.RightExpression, 
		(n1, n2) => BinaryOperatorKindCheck(n1, n2, OperatorKind.Equality, OperatorKind.Inequality));

// Outputs the resulting node from the MultiplicativeExpression; or if an additive operator is found, 
//   outputs a '+' or '-' node whose children are the left and right child expressions of the operator
additiveExpression.Production = multiplicativeExpression["leftexp"] + (
	(
		@addition > Ast(OperatorKind.Addition.ToString()) 
		| @subtraction > Ast(OperatorKind.Subtraction.ToString())
	).SetLabel("op") + additiveExpression["rightexp"].OnErrorContinue()).Optional()
	> AstLeftAssociativity<Expression, BinaryOperatorExpression>(
		AstConditional<BinaryOperatorExpression>(AstFrom("leftexp"), AstFrom("rightexp"))
			.SetProperty(e => e.Operator, AstFrom("op"))
			.SetProperty(e => e.LeftExpression, AstFrom("leftexp"))
			.SetProperty(e => e.RightExpression, AstFrom("rightexp")),
		n => n.LeftExpression,
		n => n.RightExpression, 
		(n1, n2) => BinaryOperatorKindCheck(n1, n2, OperatorKind.Addition, OperatorKind.Subtraction));

// Outputs the resulting node from the PrimaryExpression; or if an multiplicative operator is found, 
//   outputs a '*' or '/' node whose children are the left and right child expressions of the operator
multiplicativeExpression.Production = primaryExpression["leftexp"] + (
	(
		@multiplication > Ast(OperatorKind.Multiplication.ToString()) 
		| @division > Ast(OperatorKind.Division.ToString())
	).SetLabel("op") + multiplicativeExpression["rightexp"].OnErrorContinue()).Optional()
	> AstLeftAssociativity<Expression, BinaryOperatorExpression>(
		AstConditional<BinaryOperatorExpression>(AstFrom("leftexp"), AstFrom("rightexp"))
			.SetProperty(e => e.Operator, AstFrom("op"))
			.SetProperty(e => e.LeftExpression, AstFrom("leftexp"))
			.SetProperty(e => e.RightExpression, AstFrom("rightexp")),
		n => n.LeftExpression, 
		n => n.RightExpression, 
		(n1, n2) => BinaryOperatorKindCheck(n1, n2, OperatorKind.Multiplication, OperatorKind.Division));

primaryExpression.Production = numberExpression["exp"] > AstFrom("exp")
	| functionAccessExpression["exp"] > AstFrom("exp")
	| simpleName["exp"] > AstFrom("exp")
	| parenthesizedExpression["exp"] > AstFrom("exp");


parenthesizedExpression.Production = @openParenthesis + expression["exp"] + @closeParenthesis.OnErrorContinue()
	> Ast<ParenthesizedExpression>().SetProperty(e => e.ChildExpression, AstFrom("exp"));

In one of our expressions we have the equivalent of something like this for our primaryExpression production:

primaryExpression.Production = (numberExpression["exp"] > AstFrom("exp")
	| functionAccessExpression["exp"] > AstFrom("exp")
	| simpleName["exp"] > AstFrom("exp")
	| parenthesizedExpression["exp"] > AstFrom("exp")).SetLabel("exp") + @num;

The problem is the @num can't exist outside a parenthesizedExpression, but the numberExpression, functionAccessExpression, and simpleName can all be parenthesized.

So this works:

var a = 1 num

But this expression doesn't, and requires an additional @num:

var d = (1 num)

Do you have any suggestions?

Comments (1)

Posted 3 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Laif,

Based on what you describe above, it seems like @num is a keyword in the language?  What does it do? 

If I understand correctly, I believe you are saying @num has to be the last part of every primaryExpression, unless the primaryExpression ends up being a parenthesizedExpression?

If so, couldn't you split primaryExpression up into two non-terminals.  Perhaps a primaryExpressionCore would be the alternation of the non-parenthesizedExpression options, followed by @num.  Basically what you have now for primaryExpression, but without the parenthesizedExpression option.  Then the main primaryExpression would be more like:

primaryExpression.Production = (
		primaryExpressionCore["exp"] > AstFrom("exp")
		| parenthesizedExpression["exp"] > AstFrom("exp")
	).SetLabel("exp");


Actipro Software Support

The latest build of this product (v24.1.3) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.