Commit 23061646 authored by Andrei Paskevich's avatar Andrei Paskevich

switch to Menhir for parsing

parent c1531cba
......@@ -158,13 +158,13 @@ pvsbin/
/src/driver/driver_lexer.ml
/src/driver/driver_parser.ml
/src/driver/driver_parser.mli
/src/driver/driver_parser.output
/src/driver/driver_parser.conflicts
# /src/parser/
/src/parser/lexer.ml
/src/parser/parser.ml
/src/parser/parser.mli
/src/parser/parser.output
/src/parser/parser.conflicts
# /src/why3doc/
/src/why3doc/doc_lexer.ml
......@@ -186,7 +186,7 @@ pvsbin/
/plugins/tptp/tptp_lexer.ml
/plugins/tptp/tptp_parser.ml
/plugins/tptp/tptp_parser.mli
/plugins/tptp/tptp_parser.output
/plugins/tptp/tptp_parser.conflicts
/plugins/parser/dimacs.ml
# /drivers
......
......@@ -50,6 +50,12 @@ COQDEP = @COQDEP@
CAMLP5O = @CAMLP5O@
FRAMAC_LIBDIR = $(DESTDIR)@FRAMAC_LIBDIR@
ifeq (@enable_menhirLib@,yes)
MENHIR = @MENHIR@ --table
else
MENHIR = @MENHIR@
endif
DEPFLAGS = -slash -I lib/why3
ifeq (@OCAMLBEST@,opt)
DEPFLAGS += -native
......@@ -63,7 +69,7 @@ EMACS = @EMACS@
#PSVIEWER = @PSVIEWER@
#PDFVIEWER = @PDFVIEWER@
INCLUDES = @ZIPINCLUDE@
INCLUDES = @ZIPINCLUDE@ @MENHIRINCLUDE@
OFLAGS = -w Aer-41-44-45 -dtypes -g -I lib/why3 $(INCLUDES)
BFLAGS = -w Aer-41-44-45 -dtypes -g -I lib/why3 $(INCLUDES)
......@@ -81,14 +87,14 @@ endif
# external libraries common to all binaries
EXTOBJS =
EXTOBJS = @MENHIRLIB@
EXTLIBS = str unix nums dynlink @ZIPLIB@
EXTCMA = $(addsuffix .cma,$(EXTLIBS)) $(addsuffix .cmo,$(EXTOBJS))
EXTCMXA = $(addsuffix .cmxa,$(EXTLIBS)) $(addsuffix .cmx,$(EXTOBJS))
INSTALLED_LIB_EXTS = a cma cmx cmi cmxa cmxs
COMPILED_LIB_EXTS = $(INSTALLED_LIB_EXTS) o cmo cmt cmti annot dep output
COMPILED_LIB_EXTS = $(INSTALLED_LIB_EXTS) o cmo cmt cmti annot dep conflicts
TARGET_EMACS = share/emacs/why3.elc
......@@ -770,13 +776,19 @@ opt: src/coq-tactic/.why3-vo-opt
src/coq-tactic/coqCompat.ml: src/coq-tactic/coqCompat@coq_compat_version@.ml
cp -f $< $@
lib/coq-tactic/why3tac.cmxs: OFLAGS += $(addsuffix .cmxa, @ZIPLIB@)
lib/coq-tactic/why3tac.cmxs: OFLAGS += $(addsuffix .cmx, @MENHIRLIB@)
lib/coq-tactic/why3tac.cma: BFLAGS += $(addsuffix .cma, @ZIPLIB@)
lib/coq-tactic/why3tac.cma: BFLAGS += $(addsuffix .cma, @MENHIRLIB@)
lib/coq-tactic/why3tac.cmxs: lib/why3/why3.cmxa $(COQPCMX)
$(if $(QUIET),@echo 'Linking $@' &&) \
$(OCAMLOPT) $(OFLAGS) -o $@ -shared $(addsuffix .cmxa, @ZIPLIB@) $^
$(OCAMLOPT) $(OFLAGS) -o $@ -shared $^
lib/coq-tactic/why3tac.cma: lib/why3/why3.cma $(COQPCMO)
$(if $(QUIET),@echo 'Linking $@' &&) \
$(OCAMLC) -a $(BFLAGS) -o $@ $(addsuffix .cma, @ZIPLIB@) $^
$(OCAMLC) -a $(BFLAGS) -o $@ $^
src/coq-tactic/g_why3tac.ml: src/coq-tactic/g_why3tac.ml4
$(if $(QUIET),@echo 'Camlp5 $<' &&) \
......@@ -1632,6 +1644,14 @@ clean::
%.cmi: %.mli
$(if $(QUIET),@echo 'Ocamlc $<' &&) $(OCAMLC) -c $(BFLAGS) $<
# supress "unused rec" warning for Menhir-produced files
%.cmo: %.ml %.mly
$(if $(QUIET),@echo 'Ocamlc $<' &&) $(OCAMLC) -c $(BFLAGS) -w -39 $<
# supress "unused rec" warning for Menhir-produced files
%.cmx: %.ml %.mly
$(if $(QUIET),@echo 'Ocamlopt $<' &&) $(OCAMLOPT) -c $(OFLAGS) -w -39 $<
%.cmo: %.ml
$(if $(QUIET),@echo 'Ocamlc $<' &&) $(OCAMLC) -c $(BFLAGS) $<
......@@ -1651,7 +1671,7 @@ clean::
$(if $(QUIET),@echo 'Ocamllex $<' &&) $(OCAMLLEX) $<
%.ml %.mli: %.mly
$(if $(QUIET),@echo 'Ocamlyacc $<' &&) $(OCAMLYACC) -v $<
$(if $(QUIET),@echo 'Menhir $<' &&) $(MENHIR) --explain --strict $<
%.dep: %.ml %.mli
$(if $(QUIET),@echo 'Ocamldep $<' &&) $(OCAMLDEP) $(DEPFLAGS) $< $<i > $@
......
......@@ -25,20 +25,6 @@
# See the GNU Library General Public License version 2 for more details
# (enclosed in the file LGPL).
# the script generated by autoconf from this input will set the following
# variables:
# OCAMLC "ocamlc" if present in the path, or a failure, or
# "ocamlc.opt" if present with same version number as ocamlc
# OCAMLOPT "ocamlopt" (or "ocamlopt.opt" if present), or "no"
# OCAMLBEST "opt" if a native compiler was found; "byte" otherwise
# OCAMLDEP "ocamldep" or "ocamldep.opt"
# OCAMLLEX "ocamllex" or "ocamllex.opt"
# OCAMLYACC "ocamlyacc"
# OCAMLDOC "ocamldoc" or "ocamldoc.opt"
# OCAMLLIB the path to the ocaml standard library
# OCAMLVERSION the ocaml version number
# OCAMLWEB "ocamlweb" (not mandatory)
AC_INIT([Why3], m4_esyscmd([. ./Version; echo -n "$VERSION"]))
# verbosemake
......@@ -78,6 +64,11 @@ AC_ARG_ENABLE(zip,
AS_HELP_STRING([--enable-zip], [use LZ compression to store session files]),,
enable_zip=yes)
# menhirLib
AC_ARG_ENABLE(menhirLib,
AS_HELP_STRING([--enable-menhirLib], [use MenhirLib parsing library]),,
enable_menhirLib=yes)
# IDE
......@@ -279,6 +270,11 @@ else
fi
fi
AC_CHECK_PROG(MENHIR,menhir,menhir,no)
if test "$MENHIR" = no ; then
AC_MSG_ERROR(Cannot find menhir.)
fi
AC_CHECK_PROG(CAMLP5O,camlp5o,camlp5o,no)
## Where are the library we need
......@@ -372,8 +368,6 @@ else
BIGINTLIB=nums
fi
# checking for camlzip
if test "$enable_zip" = yes; then
if test "$USEOCAMLFIND" = yes; then
......@@ -399,6 +393,30 @@ else
ZIPLIB=
fi
if test "$enable_menhirLib" = yes; then
if test "$USEOCAMLFIND" = yes; then
MENHIRINCLUDE=$(ocamlfind query menhirLib)
fi
if test -n "$MENHIRINCLUDE"; then
echo "ocamlfind found menhirLib in $MENHIRINCLUDE"
MENHIRINCLUDE="-I $MENHIRINCLUDE"
else
AC_CHECK_FILE($OCAMLLIB/menhirLib/menhirLib.cmx,,enable_menhirLib=no)
if test "$enable_menhirLib" = no; then
AC_MSG_WARN([Lib menhirLib not found, parser source files will be bigger.])
reason_menhirLib=" (menhirLib not found)"
else
MENHIRINCLUDE="-I +menhirLib"
fi
fi
fi
if test "$enable_menhirLib" = yes; then
MENHIRLIB=menhirLib
else
MENHIRLIB=
fi
# checking for lablgtk2
if test "$enable_ide" = yes ; then
if test "$USEOCAMLFIND" = yes; then
......@@ -697,6 +715,7 @@ dnl AC_SUBST(OCAMLV)
dnl AC_SUBST(FORPACK)
AC_SUBST(OCAMLGRAPHLIB)
dnl AC_SUBST(OCAMLWEB)
AC_SUBST(MENHIR)
AC_SUBST(enable_profiling)
AC_SUBST(enable_bin_annot)
......@@ -717,6 +736,10 @@ AC_SUBST(enable_zip)
AC_SUBST(ZIPINCLUDE)
AC_SUBST(ZIPLIB)
AC_SUBST(enable_menhirLib)
AC_SUBST(MENHIRINCLUDE)
AC_SUBST(MENHIRLIB)
AC_SUBST(enable_coq_tactic)
AC_SUBST(enable_coq_libs)
AC_SUBST(enable_coq_fp_libs)
......@@ -792,6 +815,7 @@ echo "Components"
echo " IDE command : $enable_ide$reason_ide"
echo " GMP arithmetic : $enable_zarith$reason_zarith"
echo " Compressed sessions : $enable_zip$reason_zip"
echo " MenhirLib support : $enable_menhirLib$reason_menhirLib"
echo " Hypothesis selection : $enable_hypothesis_selection$reason_hypothesis_selection"
echo " Frama-C support : $enable_frama_c$reason_frama_c"
if test "$enable_frama_c" = yes ; then
......
......@@ -5,7 +5,7 @@
# Objective Caml source
| ".*\\.ml[il4]?" -> frame width:62 open:"(*" line:"*" close:"*)"
| ".*\\.ml[il4]?\\.in" -> frame width:62 open:"(*" line:"*" close:"*)"
| ".*\\.mly" -> frame width:62 open:"/*" line:"*" close:"*/"
| ".*\\.mly" -> frame width:62 open:"(*" line:"*" close:"*)"
# C source
| ".*\\.c" -> frame width:62 open:"/*" line:"*" close:"*/"
# Misc
......
......@@ -20,19 +20,15 @@
(* lexical errors *)
exception IllegalCharacter of char
exception IllegalLexeme of string
exception UnterminatedComment
(* dead code
exception UnterminatedString
*)
exception UnknownDDW of string
exception UnknownDW of string
let () = Exn_printer.register (fun fmt e -> match e with
| IllegalCharacter c -> fprintf fmt "illegal character %c" c
| IllegalLexeme s -> fprintf fmt "illegal lexeme %s" s
| UnterminatedComment -> fprintf fmt "unterminated comment"
(* dead code
| UnterminatedString -> fprintf fmt "unterminated string"
*)
| UnknownDDW s -> fprintf fmt "unknown system_word %s" s
| UnknownDW s -> fprintf fmt "unknown defined_word %s" s
| _ -> raise e)
......@@ -86,16 +82,16 @@
let () = List.iter (fun (x,y) -> Hashtbl.add keywords x y) [
"assumption", ASSUMPTION;
"axiom", AXIOM;
"cnf", CNF;
"cnf", CNFK;
"conjecture", CONJECTURE;
"corollary", COROLLARY;
"definition", DEFINITION;
"fof", FOF;
"fof", FOFK;
"hypothesis", HYPOTHESIS;
"include", INCLUDE;
"lemma", LEMMA;
"negated_conjecture", NEGATED_CONJECTURE;
"tff", TFF;
"tff", TFFK;
"theorem", THEOREM;
"type", TYPE;
]
......@@ -164,7 +160,7 @@ rule token = parse
| '-' (natural as i) ('.' (digit+ as f))? (['e' 'E'] ('-' natural as e))?
{ REALNEGNUM (i,f,e) }
| "/*/"
{ SLASH_STAR_SLASH }
{ raise (IllegalLexeme "/*/") }
| "/*"
{ comment_start_loc := loc lexbuf; comment_block lexbuf; token lexbuf }
| "%"
......
/********************************************************************/
/* */
/* The Why3 Verification Platform / The Why3 Development Team */
/* Copyright 2010-2014 -- INRIA - CNRS - Paris-Sud University */
/* */
/* This software is distributed under the terms of the GNU Lesser */
/* General Public License version 2.1, with the special exception */
/* on linking described in file LICENSE. */
/* */
/********************************************************************/
(********************************************************************)
(* *)
(* The Why3 Verification Platform / The Why3 Development Team *)
(* Copyright 2010-2014 -- INRIA - CNRS - Paris-Sud University *)
(* *)
(* This software is distributed under the terms of the GNU Lesser *)
(* General Public License version 2.1, with the special exception *)
(* on linking described in file LICENSE. *)
(* *)
(********************************************************************)
%{
open Tptp_ast
let loc () = (symbol_start_pos (), symbol_end_pos ())
let floc () = Why3.Loc.extract (loc ())
(* dead code
let loc_i i = (rhs_start_pos i, rhs_end_pos i)
let floc_i i = Why3.Loc.extract (loc_i i)
let loc_ij i j = (rhs_start_pos i, rhs_end_pos j)
let floc_ij i j = Why3.Loc.extract (loc_ij i j)
*)
let mk_e n = { e_node = n ; e_loc = floc () }
let mk_expr n s e = { e_node = n; e_loc = Why3.Loc.extract (s,e) }
exception UnsupportedRole of string
let () = Why3.Exn_printer.register (fun fmt exn -> match exn with
| Parse_error -> Format.fprintf fmt "syntax error"
| UnsupportedRole s -> Format.fprintf fmt "unsupported role %s" s
| Error -> Format.fprintf fmt "syntax error"
| _ -> raise exn)
%}
/* tokens */
(* tokens *)
%token <string> LWORD UWORD
%token <Tptp_ast.defined_word> DWORD
......@@ -45,48 +34,39 @@ let () = Why3.Exn_printer.register (fun fmt exn -> match exn with
%token <Tptp_ast.num_real> REALPOSNUM
%token <Tptp_ast.num_real> REALNEGNUM
/* keywords */
(* keywords *)
%token ASSUMPTION AXIOM CNF CONJECTURE COROLLARY DEFINITION FOF
%token HYPOTHESIS INCLUDE LEMMA NEGATED_CONJECTURE TFF
%token ASSUMPTION AXIOM CNFK CONJECTURE COROLLARY DEFINITION FOFK
%token HYPOTHESIS INCLUDE LEMMA NEGATED_CONJECTURE TFFK
%token THEOREM TYPE
/* symbols */
(* symbols *)
%token DOT COMMA COLON LEFTPAR RIGHTPAR LEFTSQ RIGHTSQ
%token LONGARROW LARROW RARROW LRARROW NLRARROW NAMP NBAR
%token TILDE EQUAL NEQUAL STAR GT PI BANG QUES BAR AMP
%token LET_TT LET_FT LET_TF LET_FF ITE_T ITE_F
%token SLASH_STAR_SLASH EOF
%token EOF
/* entry points */
(* entry points *)
%type <Tptp_ast.tptp_file> tptp_file
%start tptp_file
%start <Tptp_ast.tptp_file> tptp_file
%%
tptp_file:
| list0_input EOF { $1 }
;
list0_input:
| /* epsilon */ { [] }
| input list0_input { $1 :: $2 }
;
| input* EOF { $1 }
input:
| kind LEFTPAR name COMMA role COMMA top_formula annotation RIGHTPAR DOT
{ Formula ($1, $3, $5, $7, floc ()) }
{ Formula ($1, $3, $5, $7, Why3.Loc.extract ($startpos, $endpos)) }
| INCLUDE LEFTPAR SINGLE_QUOTED formula_selection RIGHTPAR DOT
{ Include ($3, $4, floc ()) }
;
{ Include ($3, $4, Why3.Loc.extract ($startpos, $endpos)) }
kind:
| TFF { TFF }
| FOF { FOF }
| CNF { CNF }
;
| TFFK { TFF }
| FOFK { FOF }
| CNFK { CNF }
role:
| AXIOM { Axiom }
......@@ -100,214 +80,168 @@ role:
| NEGATED_CONJECTURE { Negated_conjecture }
| TYPE { Type }
| LWORD { raise (UnsupportedRole $1) }
;
top_formula:
| formula { LogicFormula $1 }
| typed_atom { $1 }
| sequent { $1 }
;
/* formula and term */
(* formula and term *)
expr(X):
| X { mk_expr $1 $startpos $endpos }
formula:
| nonassoc_formula { $1 }
| or_formula { $1 }
| and_formula { $1 }
| unitary_formula { $1 }
;
| expr(nonassoc_formula) { $1 }
| expr(or_formula) { $1 }
| expr(and_formula) { $1 }
| unitary_formula { $1 }
nonassoc_formula:
| unitary_formula nassoc unitary_formula { mk_e (Ebin ($2,$1,$3)) }
;
| unitary_formula nassoc unitary_formula { Ebin ($2,$1,$3) }
or_formula:
| unitary_formula BAR unitary_formula { mk_e (Ebin (BOor,$1,$3)) }
| or_formula BAR unitary_formula { mk_e (Ebin (BOor,$1,$3)) }
;
| unitary_formula BAR unitary_formula { Ebin (BOor,$1,$3) }
| expr(or_formula) BAR unitary_formula { Ebin (BOor,$1,$3) }
and_formula:
| unitary_formula AMP unitary_formula { mk_e (Ebin (BOand,$1,$3)) }
| and_formula AMP unitary_formula { mk_e (Ebin (BOand,$1,$3)) }
;
| unitary_formula AMP unitary_formula { Ebin (BOand,$1,$3) }
| expr(and_formula) AMP unitary_formula { Ebin (BOand,$1,$3) }
unitary_formula:
| expr(unitary_formula_) { $1 }
| LEFTPAR formula RIGHTPAR { $2 }
unitary_formula_:
| ITE_F LEFTPAR formula COMMA formula COMMA formula RIGHTPAR
{ mk_e (Eite ($3,$5,$7)) }
| LET_FF LEFTPAR formula_def COMMA formula RIGHTPAR
{ mk_e (Elet ($3,$5)) }
| LET_TF LEFTPAR term_def COMMA formula RIGHTPAR
{ mk_e (Elet ($3,$5)) }
{ Eite ($3,$5,$7) }
| LET_FF LEFTPAR expr(formula_def) COMMA formula RIGHTPAR
{ Elet ($3,$5) }
| LET_TF LEFTPAR expr(term_def) COMMA formula RIGHTPAR
{ Elet ($3,$5) }
| quant LEFTSQ varlist RIGHTSQ COLON unitary_formula
{ mk_e (Eqnt ($1,$3,$6)) }
{ Eqnt ($1,$3,$6) }
| TILDE unitary_formula
{ mk_e (Enot $2) }
{ Enot $2 }
| term NEQUAL term
{ mk_e (Enot (mk_e (Eequ ($1,$3)))) }
{ Enot (mk_expr (Eequ ($1,$3)) $startpos $endpos) }
| term EQUAL term
{ mk_e (Eequ ($1,$3)) }
| LEFTPAR formula RIGHTPAR
{ $2 }
{ Eequ ($1,$3) }
| plain_term
{ $1 }
;
term:
| expr(term_) { $1 }
term_:
| ITE_T LEFTPAR formula COMMA term COMMA term RIGHTPAR
{ mk_e (Eite ($3,$5,$7)) }
| LET_FT LEFTPAR formula_def COMMA term RIGHTPAR
{ mk_e (Elet ($3,$5)) }
| LET_TT LEFTPAR term_def COMMA term RIGHTPAR
{ mk_e (Elet ($3,$5)) }
{ Eite ($3,$5,$7) }
| LET_FT LEFTPAR expr(formula_def) COMMA term RIGHTPAR
{ Elet ($3,$5) }
| LET_TT LEFTPAR expr(term_def) COMMA term RIGHTPAR
{ Elet ($3,$5) }
| DISTINCT_OBJECT
{ mk_e (Edob $1) }
{ Edob $1 }
| pos_number
{ mk_e (Enum $1) }
{ Enum $1 }
| neg_number
{ mk_e (Edef (DF DFumin, [mk_e (Enum $1)])) }
{ Edef (DF DFumin, [mk_expr (Enum $1) $startpos $endpos]) }
| plain_term
{ $1 }
;
plain_term:
| DWORD { mk_e (Edef ($1,[])) }
| DWORD LEFTPAR arguments RIGHTPAR { mk_e (Edef ($1,$3)) }
| atomic_word { mk_e (Eapp ($1,[])) }
| atomic_word LEFTPAR arguments RIGHTPAR { mk_e (Eapp ($1,$3)) }
| var_term { $1 }
;
| DWORD paren_list(term) { Edef ($1,$2) }
| atomic_word paren_list(term) { Eapp ($1,$2) }
| var_term { $1 }
var_term:
| UWORD { mk_e (Evar $1) }
;
arguments:
| term { [$1] }
| term COMMA arguments { $1 :: $3 }
;
| UWORD { Evar $1 }
formula_def:
| BANG LEFTSQ varlist RIGHTSQ COLON formula_def
{ mk_e (Eqnt (Qforall,$3,$6)) }
| formula_def_inner
{ $1 }
;
| BANG LEFTSQ varlist RIGHTSQ COLON expr(formula_def) { Eqnt (Qforall,$3,$6) }
| formula_def_inner { $1 }
term_def:
| BANG LEFTSQ varlist RIGHTSQ COLON term_def
{ mk_e (Eqnt (Qforall,$3,$6)) }
| term_def_inner
{ $1 }
;
| BANG LEFTSQ varlist RIGHTSQ COLON expr(term_def) { Eqnt (Qforall,$3,$6) }
| term_def_inner { $1 }
formula_def_inner:
| def_lhs LRARROW formula { mk_e (Ebin (BOequ,$1,$3)) }
| expr(def_lhs) LRARROW formula { Ebin (BOequ,$1,$3) }
| LEFTPAR formula_def_inner RIGHTPAR { $2 }
;
term_def_inner:
| def_lhs EQUAL term { mk_e (Eequ ($1,$3)) }
| expr(def_lhs) EQUAL term { Eequ ($1,$3) }
| LEFTPAR term_def_inner RIGHTPAR { $2 }
;
def_lhs:
| atomic_word { mk_e (Eapp ($1,[])) }
| atomic_word LEFTPAR list1_var_term RIGHTPAR { mk_e (Eapp ($1,$3)) }
;
list1_var_term:
| var_term { [$1] }
| var_term COMMA list1_var_term { $1 :: $3 }
;
| atomic_word paren_list(expr(var_term)) { Eapp ($1,$2) }
varlist:
| typed_var { [$1] }
| typed_var COMMA varlist { $1 :: $3 }
;
| comma_list(typed_var) { $1 }
typed_var:
| UWORD { $1, mk_e (Edef (DT DTuniv, [])) }
| UWORD COLON atomic_type { $1, $3 }
;
| UWORD
{ $1, mk_expr (Edef (DT DTuniv, [])) $startpos $endpos }
| UWORD COLON atomic_type
{ $1, $3 }
/* typed_atom */
(* typed_atom *)
typed_atom:
| untyped_atom COLON top_type { TypedAtom ($1,$3) }
| LEFTPAR typed_atom RIGHTPAR { $2 }
;
untyped_atom:
| atomic_word { $1 }
;
| atomic_word { $1 }
top_type:
| atomic_type { [],([],$1) }
| mapping_type { [],$1 }
| quantified_type { $1 }
| LEFTPAR top_type RIGHTPAR { $2 }
;
| atomic_type { [],([],$1) }
| mapping_type { [],$1 }
| quantified_type { $1 }
| LEFTPAR top_type RIGHTPAR { $2 }
quantified_type:
| PI LEFTSQ varlist RIGHTSQ COLON monotype { $3,$6 }
;
monotype:
| atomic_type { [],$1 }
| LEFTPAR mapping_type RIGHTPAR { $2 }
;
mapping_type:
| unitary_type GT atomic_type { $1,$3 }
;
unitary_type:
| atomic_type { [$1] }
| LEFTPAR xprod_type RIGHTPAR { $2 }
;
xprod_type:
| atomic_type STAR atomic_type { [$1;$3] }
| xprod_type STAR atomic_type { $1 @ [$3] }
;
/* atomic type */
(* atomic type *)
atomic_type:
| DWORD { mk_e (Edef ($1,[])) }
| atomic_word { mk_e (Eapp ($1,[])) }
| atomic_word LEFTPAR list1_atomic_type RIGHTPAR { mk_e (Eapp ($1,$3)) }
| var_term { $1 }
;
| expr(atomic_type_) { $1 }
list1_atomic_type:
| atomic_type { [$1] }
| atomic_type COMMA list1_atomic_type { $1 :: $3 }
;
atomic_type_: