2.2 Example

Here is an example to parse simple infix arithmetic expressions. See (bison)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 How to use Wisent with 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}
  ;

%%