&term
  EOL,PLUS,MINUS,TIMES,DIVIDE,UMINUS,DIGIT,LPR,RPR,ERROR
&right UMINUS
&left TIMES,DIVIDE
&left PLUS,MINUS
&left EOL
&gram
l  = e				&(writeln('= ',$1); readln(input))&
  | l EOL l
  .
e = e PLUS e 			&($$ := $1 + $3)&
  | e MINUS e 			&($$ := $1 - $3)&
  | e TIMES e 			&($$ := $1 * $3)&
  | e DIVIDE e 			&($$ := $1 / $3)&
  | LPR e RPR 			&($$ := $2)&
  | MINUS e &prec UMINUS 	&($$ := -$2)&
  | number
  | llerror 			&(
				  write(' ? ');
				  $$ := 0;
				)&
  .
number = DIGIT
  | number DIGIT 		&($$ := 10*$1 + $2)&.
&prog
program calc1(input,output);
&type
  llvaltype = real;
&proc
procedure llexan;
begin
  while (input^ in [' ','	']) and not eoln(input) do
    begin
      write(input^);
      get(input)
    end;
  write(input^);
  if eof 
  then llnextsymbol := llEND
  else if eoln
  then llnextsymbol := EOL
  else
    begin
      if input^ in ['+','-','*','/','(',')','0'..'9']
      then case input^ of
             '0','1','2','3','4','5','6','7','8','9':
               begin
                 llnextsymbol := DIGIT;
                 llexval := ord(input^) - ord('0')
               end;
             '+': llnextsymbol := PLUS;
             '-': llnextsymbol := MINUS;
             '*': llnextsymbol := TIMES;
             '/': llnextsymbol := DIVIDE;
             '(': llnextsymbol := LPR;
             ')': llnextsymbol := RPR
           end
      else llnextsymbol := ERROR;
      get(input)
    end
end;
&main
begin llparser end.

