Next: , Previous: Grammar format, Up: Wisent Grammar

2.2 Example

Here is an example to parse simple infix arithmetic expressions. See Infix Calc, in the Bison manual for details.

     '(
       ;; Terminals
       (NUM)
     
       ;; Terminal associativity & precedence
       ((nonassoc ?=)
        (left ?- ?+)
        (left ?* ?/)
        (left NEG)
        (right ?^))
     
       ;; Rules
       (input
        ((line))
        ((input line)
         (format "%s %s" $1 $2))
        )
     
       (line
        ((?;)
         (progn ";"))
        ((exp ?;)
         (format "%s;" $1))
        ((error ?;)
         (progn "Error;")))
        )
     
       (exp
        ((NUM)
         (string-to-number $1))
        ((exp ?= exp)
         (= $1 $3))
        ((exp ?+ exp)
         (+ $1 $3))
        ((exp ?- exp)
         (- $1 $3))
        ((exp ?* exp)
         (* $1 $3))
        ((exp ?/ exp)
         (/ $1 $3))
        ((?- exp) [NEG]
         (- $2))
        ((exp ?^ exp)
         (expt $1 $3))
        ((?\( exp ?\))
         (progn $2))
        )
       )

In the bison-like WY format (see Wisent Semantic) the grammar looks like this:

     %token <number> NUM
     
     %nonassoc '=' ;; comparison
     %left '-' '+'
     %left '*' '/'
     %left NEG     ;; negation--unary minus
     %right '^'    ;; exponentiation
     
     %%
     
     input:
         line
       | input line
         (format "%s %s" $1 $2)
       ;
     
     line:
         ';'
         {";"}
       | exp ';'
         (format "%s;" $1)
       | error ';'
         {"Error;"}
       ;
     
     exp:
         NUM
         (string-to-number $1)
       | exp '=' exp
         (= $1 $3)
       | exp '+' exp
         (+ $1 $3)
       | exp '-' exp
         (- $1 $3)
       | exp '*' exp
         (* $1 $3)
       | exp '/' exp
         (/ $1 $3)
       | '-' exp %prec NEG
         (- $2)
       | exp '^' exp
         (expt $1 $3)
       | '(' exp ')'
         {$2}
       ;
     
     %%