(* HCoop Domtool (http://hcoop.sourceforge.net/)
* Copyright (c) 2006, Adam Chlipala
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*)
(* Parser for Domtool configuration files *)
open Ast
%%
%header (functor DomtoolLrValsFn(structure Token : TOKEN))
%term
EOF
| SYMBOL of string | CSYMBOL of string
| STRING of string
| INT of int
| ARROW | DARROW | COLON
| LPAREN | RPAREN | LBRACK | RBRACK | LBRACE | RBRACE
| EQ | COMMA | BSLASH | SEMI | LET | IN | END
%nonterm
file of exp
| exp of exp
| apps of exp
| term of exp
| elist of exp list
| elistNe of exp list
| clist of exp list
| typ of typ
%verbose (* print summary of errors *)
%pos int (* positions *)
%start file
%pure
%eop EOF
%noshift EOF
%name Domtool
%right SEMI
%nonassoc IN
%right ARROW
%right COMMA
%nonassoc EQ
%%
file : exp (exp)
exp : apps (apps)
| BSLASH SYMBOL COLON typ ARROW exp (ELam (SYMBOL, typ, exp), (BSLASHleft, expright))
| CSYMBOL EQ exp (ESet (CSYMBOL, exp), (CSYMBOLleft, expright))
| exp SEMI exp (let
val ls = case #1 exp2 of
ESeq ls => exp :: ls
| _ => [exp1, exp2]
in
(ESeq ls, (exp1left, exp2right))
end)
apps : term (term)
| apps term (EApp (apps, term), (appsleft, termright))
term : LPAREN exp RPAREN (exp)
| INT (EInt INT, (INTleft, INTright))
| STRING (EString STRING, (STRINGleft, STRINGright))
| LBRACK elist RBRACK (EList elist, (LBRACKleft, RBRACKright))
| LET exp IN exp END (let
val ls = case (#1 exp1, #1 exp2) of
(ESeq ls1, ESeq ls2) => ls1 @ ls2
| (ESeq ls, _) => ls @ [exp2]
| (_, ESeq ls) => exp1 :: ls
| _ => [exp1, exp2]
in
(ESeq ls, (exp1left, exp2right))
end)
elist : ([])
| elistNe (elistNe)
elistNe: exp ([exp])
| exp COMMA elistNe (exp :: elistNe)
typ : SYMBOL (TBase SYMBOL, (SYMBOLleft, SYMBOLright))