ucDefineSyntax
See Also: ucDefine
Defines a syntax construct.
ucDefineSyntax(Definition [, Rank, [, tHandle]])
Most of what ucDefineSyntax can do falls beyond the scope of uCalc Fast Math Parser. Visit www.ucalc.com for further documentation. Here are a few simple examples, some of which may have some relevance to math parsing.
Example 1: Miscellaneous syntax constructs
This multi-part example shows a series of simple syntax constructs, along with printouts showing what effect they have.
Visual Basic
ucDefineSyntax
"This sentence ::= 'Something Else'" Print ucEvalStr("This
sentence") ' Returns
"Something Else" ucDefineSyntax
"{'&b'}{Number:'[0-1]+'} ::= BaseConvert('{Number}',
2)" Print ucEvalStr("&b101") ' Returns 5 ucDefineSyntax
"Reverse({first}) ::= '{first}'" ucDefineSyntax
"Reverse({first}, {rest}) ::= Reverse({rest}) + ', {first}'" Print ucEvalStr("Reverse(1,
2, 3, 4, 5)") ' Returns
"5, 4, 3, 2, 1" ucDefineSyntax
"MySum({x}) ::= {x}" ucDefineSyntax
"MySum({x}, {y}) ::= ({x} + MySum({y}))" Print ucEvalStr("MySum(10, 20, 30, 40, 50)") ' Returns 150 ucDefineSyntax
"CountArgs({x}) ::= 1" ucDefineSyntax
"CountArgs({x}, {y}) ::= ~Eval(1
+ CountArgs({y}))" Print ucEvalStr("CountArgs(a+b, 'Hello', -5,
1)") ' Returns 4 ucDefineSyntax
"Average({args}) ::= MySum({args}) / CountArgs({args})" Print ucEvalStr("Average(3,
4, 5, 6)") ' Returns 4.5 ucDefineSyntax
"{a} & {b} ::= '{a}s and {b}s are different'" ucDefineSyntax
"{a} & {a} ::= 'Two {a}s'" Print ucEvalStr("Orange
& Orange") ' Returns
"Two Oranges" Print ucEvalStr("Orange
& Apple") ' Returns
"Oranges and Apples are different" ucDefineSyntax
"{a} & {a} ::= 'Two {a}s are better than one {a}'" Print ucEvalStr("orange
& orange") ' Returns
"Two oranges are better than one orange" |
Note: The order of multiple definitions that are related to each other (such as {a} & {b} and {a} & {a}, or the two definitions for Reverse, etc) is very important.
Note: As of version 3.0. ucExpand() is no longer part of uCalc Fast Math Parser, but part of a more general uCalc parser.
In Example 1, we defined syntax constructs and tested them using ucEvalStr. Using the same MySum definition from Example 1, we will now highlight the effect of expanding an expression instead. ucEvalStr expands an expression, and then proceeds to evaluate it. ucExpand expands the expression (by performing text substitutions based on the defined syntax constructs), and stops there and returns the expanded result.
Visual Basic
ucDefineSyntax
"MySum({x}) ::= {x}" ucDefineSyntax
"MySum({x}, {y}) ::= ({x} + MySum({y}))" Print ucEvalStr("MySum(10, 20, 30, 40, 50)") ' Returns 150 Print ucExpand("MySum(10,
20, 30, 40, 50)") ' Returns (10
+ (20 + (30 + (40 + 50)))) |
The example below returns the nth argument in a list. Here we use ~Eval which evaluates part of an expression in place during the expansion stage, and immediately replaces ~Eval(...) with the result. Similarly, ~Expand expands an expression in place, and also immediately substitutes the result. The final result of ucExpand is as a string, which is not parsed as an expression. If we used ucEvalStr in this example, then once expanded the two lines with the Print statement would then attempt to evaluate the words Second and Fourth, which would raise an error because such words weren't defined. With ucExpand, it doesn't matter much what kind of text the nth argument contains.
Visual Basic
ucDefineSyntax
"First([{x}[, {y}]]) ::= {x}" ucDefineSyntax
"Rest([{x} [, {y}]]) ::= {y}" ucDefineSyntax
"nthArg({n}, {list}) ::= nthArg(~Eval({n}-1), ~Expand(Rest({list})))" ucDefineSyntax
"nthArg(1,
{list}) ::= First({list})" Print ucExpand("nthArg(2,
First, Second, Third, Fourth)") ' Returns "Second" Print ucExpand("nthArg(4,
First, Second, Third, Fourth)") ' Returns "Fourth" |
Example 3: Creating an RPN calculator
This example creates a simple RPN (reverse polish notation) calculator.
Visual Basic
ucDefineVariable
"Left" ucDefineVariable
"Right" ucDefineVariable
"uc_Stack As Stack" ucDefineFunction
"Native: uc_Push(StackName
As Stack, ByHandle Data As AnyType,
Index As Long = 0) As Long", ucAddr(uc_Func_PushData_Stack) ucDefineFunction
"Native: uc_PopNum(StackName
As Stack, Index As Long = 0) As Extended", ucAddr(uc_Func_PopNum_Stack) ucDefineSyntax
"pop ::= uc_PopNum(uc_Stack)" ucDefineSyntax
"push({Num}) ::= uc_Push(uc_Stack, {Num})" ucDefineSyntax
"GetOperands ::= SetVar(Right,
pop); SetVar(Left, pop)" ucDefineSyntax
"RPN {op} ::= GetOperands; push(Left {op}
Right); pop" ucDefineSyntax
"RPN {op} {' '} {other} ::= GetOperands;
push(Left {op} Right); RPN {other}" ucDefineSyntax
"RPN {'[ ]+'} {num:_Number} {other} ::= push({num}); RPN {other}" Print ucEval("RPN 3
4 5 + *") ' Returns 27 Print ucEval("RPN
10 1 - 2 /") ' Returns 4.5 |