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.



Example 2:  ucExpand


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