added negation and cleaned up/fixed parsing
This commit is contained in:
parent
607b9f1d7d
commit
68de6a806b
3 changed files with 63 additions and 39 deletions
|
|
@ -23,36 +23,34 @@ struct
|
||||||
open Formula
|
open Formula
|
||||||
open Scanner
|
open Scanner
|
||||||
|
|
||||||
val prec =
|
exception NotOperator of token
|
||||||
fn AND => (7, 6)
|
|
||||||
| OR => (5, 4)
|
val infix_table =
|
||||||
| RARROW => (2, 3)
|
fn AND => (40, 41, Conj)
|
||||||
| LRARROW => (1, 1)
|
| OR => (30, 31, Disj)
|
||||||
| _ => (~1, ~1)
|
| RARROW => (21, 20, Impl)
|
||||||
|
| LRARROW => (10, 10, Iff)
|
||||||
|
| t => (100, 100, fn _ => raise NotOperator t)
|
||||||
|
|
||||||
|
val prefix_table =
|
||||||
|
fn NEG => ((), 50, Neg) | t => ((), 100, fn _ => raise NotOperator t)
|
||||||
|
|
||||||
exception NotOperator
|
exception NotOperator
|
||||||
|
|
||||||
val comb_func =
|
|
||||||
fn AND => Conj
|
|
||||||
| OR => Disj
|
|
||||||
| RARROW => Impl
|
|
||||||
| LRARROW => Iff
|
|
||||||
| _ => fn (_, _) => raise NotOperator
|
|
||||||
|
|
||||||
fun parse
|
fun parse
|
||||||
(state as
|
(state as
|
||||||
{ binders = binders
|
{ binders = binders
|
||||||
, constants = constants
|
, constants = constants
|
||||||
, functions = functions
|
, functions = functions
|
||||||
, relations = relations
|
, relations = relations
|
||||||
}) =
|
}) ts =
|
||||||
let
|
let
|
||||||
val termState =
|
val termState =
|
||||||
{binders = binders, constants = constants, functions = functions}
|
{binders = binders, constants = constants, functions = functions}
|
||||||
|
|
||||||
val term_p = TermParser.parse termState
|
val term_p = TermParser.parse termState
|
||||||
|
|
||||||
fun formula_p ts = parse state ts
|
fun parse_full ts = parse state ts
|
||||||
|
|
||||||
fun equal_p ts =
|
fun equal_p ts =
|
||||||
((term_p >>- eat EQ >>> term_p) oo Equal) ts
|
((term_p >>- eat EQ >>> term_p) oo Equal) ts
|
||||||
|
|
@ -107,30 +105,49 @@ struct
|
||||||
NO (Region.botloc, fn () =>
|
NO (Region.botloc, fn () =>
|
||||||
"expecting identifier but reached the end")
|
"expecting identifier but reached the end")
|
||||||
|
|
||||||
val atomic_p =
|
exception ParseError of locerr
|
||||||
bottom_p || equal_p || forall_p || exists_p || relation_p
|
|
||||||
|| (eat LPAREN ->> formula_p >>- eat RPAREN)
|
|
||||||
|
|
||||||
fun comb_p mprec [] =
|
fun unwrap (OK c) = c
|
||||||
|
| unwrap (NO l) = raise ParseError l
|
||||||
|
|
||||||
|
fun atomic_p ts =
|
||||||
|
(equal_p || bottom_p || relation_p || forall_p || exists_p
|
||||||
|
|| (eat LPAREN ->> formula_p 0 >>- eat RPAREN)) ts
|
||||||
|
|
||||||
|
and formula_p mprec [] =
|
||||||
NO (Region.botloc, fn () => "expecting formula but reached the end")
|
NO (Region.botloc, fn () => "expecting formula but reached the end")
|
||||||
| comb_p mprec ts =
|
| formula_p mp (ts as ((t, r) :: rest)) =
|
||||||
case atomic_p ts of
|
|
||||||
NO e => NO e
|
|
||||||
| OK (v, r, []) => OK (v, r, [])
|
|
||||||
| OK (v, r1, ts as (t, r) :: rest) =>
|
|
||||||
let
|
let
|
||||||
val (lprec, rprec) = prec t
|
(* get first term atomic or prefix *)
|
||||||
val comb = comb_func t
|
val (lhs, r, rest') = unwrap
|
||||||
|
(if prefix_connective t then
|
||||||
|
let val ((), rp, comb) = prefix_table t
|
||||||
|
in (formula_p rp oo comb) rest
|
||||||
|
end
|
||||||
|
else
|
||||||
|
atomic_p ts)
|
||||||
|
|
||||||
|
(* loop through the rest while the precedence is high enough *)
|
||||||
|
fun loop (lhs, r, []) = OK (lhs, r, [])
|
||||||
|
| loop (lhs, r, ts as (t, _) :: rest) =
|
||||||
|
if infix_connective t then
|
||||||
|
let
|
||||||
|
val (lp, rp, comb) = infix_table t
|
||||||
in
|
in
|
||||||
if lprec < mprec then
|
if lp < mp then
|
||||||
if connective t then
|
OK (lhs, r, ts)
|
||||||
((comb_p 0) oo (fn res => comb (v, res))) rest
|
|
||||||
else
|
else
|
||||||
OK (v, r1, ts)
|
let val (rhs, r'', rest') = unwrap (formula_p rp rest)
|
||||||
|
in loop (comb (lhs, rhs), r'', rest')
|
||||||
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
((comb_p rprec) oo (fn res => comb (v, res))) rest
|
OK (lhs, r, ts)
|
||||||
|
in
|
||||||
|
loop (lhs, r, rest')
|
||||||
end
|
end
|
||||||
in
|
in
|
||||||
comb_p 0
|
formula_p 0 ts
|
||||||
|
handle ParseError l => NO l
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ sig
|
||||||
datatype token =
|
datatype token =
|
||||||
LPAREN
|
LPAREN
|
||||||
| RPAREN
|
| RPAREN
|
||||||
|
| NEG
|
||||||
| AND
|
| AND
|
||||||
| OR
|
| OR
|
||||||
| EQ
|
| EQ
|
||||||
|
|
@ -19,5 +20,6 @@ sig
|
||||||
val scan: {srcname: string, input: string} -> (token * Region.reg) list
|
val scan: {srcname: string, input: string} -> (token * Region.reg) list
|
||||||
val pp_token: token -> string
|
val pp_token: token -> string
|
||||||
|
|
||||||
val connective: token -> bool
|
val infix_connective: token -> bool
|
||||||
|
val prefix_connective: token -> bool
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ struct
|
||||||
datatype token =
|
datatype token =
|
||||||
LPAREN
|
LPAREN
|
||||||
| RPAREN
|
| RPAREN
|
||||||
|
| NEG
|
||||||
| AND
|
| AND
|
||||||
| OR
|
| OR
|
||||||
| EQ
|
| EQ
|
||||||
|
|
@ -23,6 +24,7 @@ struct
|
||||||
| map_token (Symb ".") = DOT
|
| map_token (Symb ".") = DOT
|
||||||
| map_token (Symb ",") = COMMA
|
| map_token (Symb ",") = COMMA
|
||||||
| map_token (Symb "#") = HASH
|
| map_token (Symb "#") = HASH
|
||||||
|
| map_token (Symb "~") = NEG
|
||||||
| map_token (Symb "&") = AND
|
| map_token (Symb "&") = AND
|
||||||
| map_token (Symb "|") = OR
|
| map_token (Symb "|") = OR
|
||||||
| map_token (Symb "=") = EQ
|
| map_token (Symb "=") = EQ
|
||||||
|
|
@ -40,7 +42,7 @@ struct
|
||||||
map (fn (t, r) => (map_token t, r))
|
map (fn (t, r) => (map_token t, r))
|
||||||
o
|
o
|
||||||
tokenise
|
tokenise
|
||||||
{ sep_chars = "(),&|.#"
|
{ sep_chars = "(),&|.#~"
|
||||||
, symb_chars = "<=>"
|
, symb_chars = "<=>"
|
||||||
, is_id = (List.all Char.isAlphaNum) o String.explode
|
, is_id = (List.all Char.isAlphaNum) o String.explode
|
||||||
, is_num = const false
|
, is_num = const false
|
||||||
|
|
@ -49,6 +51,7 @@ struct
|
||||||
val pp_token =
|
val pp_token =
|
||||||
fn LPAREN => "("
|
fn LPAREN => "("
|
||||||
| RPAREN => ")"
|
| RPAREN => ")"
|
||||||
|
| NEG => "~"
|
||||||
| AND => "&"
|
| AND => "&"
|
||||||
| OR => "|"
|
| OR => "|"
|
||||||
| EQ => "="
|
| EQ => "="
|
||||||
|
|
@ -62,6 +65,8 @@ struct
|
||||||
| HASH => "#"
|
| HASH => "#"
|
||||||
| IDENT s => s
|
| IDENT s => s
|
||||||
|
|
||||||
val connective =
|
val infix_connective =
|
||||||
fn AND => true | OR => true | RARROW => true | LRARROW => true | _ => false
|
fn AND => true | OR => true | RARROW => true | LRARROW => true | _ => false
|
||||||
|
|
||||||
|
val prefix_connective = fn NEG => true | _ => false
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue