We define a simple tokenizer and a driver for our needs, and run Jacc on the term grammar:
% jacc Term *** Reading grammar in file Term.grm ... *** Starting grammar analysis ... *** Grammar analysis completed in 70 ms. *** Building parsing tables ... *** Writing parser file TermParser.java *** Parser generation completed in 100 ms. *** Total processing time: 271 ms.This generates the term parser. We then compile all the relevant java files:
% javac Term*.javaand run the Term reader:
% java TermMain *** Welcome to the dynamic operator Term Parser! *** Version of Mon Dec 20 18:49:39 PST 2004 > a+b*c-d. -(+(a,*(b,c)),d)The system read in the algebraic term "a+b*c-d" and printed it in its canonical form. With the canonical form, we can verify the effect of operator precedence and associativity. For example, the operator + was declared in the grammar to be left associative:
> a+b+c. +(+(a,b),c)We can change an operator's specification dynamically. Indeed, the term grammar defines a semantic action so that the parser interprets a term of the form "op(P,F,O)" to (re-)define the operator O to have precedence level P, and fixity F. We can use this to make the operator + become right-associative. To wit:
> op(500,xfy,+). op(500,xfy,+) > a+b+c. +(a,+(b,c))We can also define fresh operators. For example, $ is not known as an operator. Indeed:
> a $ b. *** Syntax Error: unexpected 'FUNCTOR'($) - see stdin (line 5, column 3)But now, let us define it on the fly as a binary left associative operator:
> op(400,yfx,$). op(400,yfx,$)and verify that it is now indeed understood to be so:
> a $ b $ c. $($(a,b),c)Finally, we can also verify the behavior of the if...then...else construct as an algebraic term:
> if a then b else c. then(if(a),else(b,c)) > if a<b then x+y else (if a = b then 1 else 0). then(if(<(a,b)),else(+(x,y),then(if(=(a,b)),else(1,0)))) > exit. *** Bye bye... %