Skip to content

Commit

Permalink
Upgrade grammar to support actions and convert to array format.
Browse files Browse the repository at this point in the history
  • Loading branch information
skaller committed Dec 3, 2023
1 parent 69eb260 commit ea59616
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 18 deletions.
83 changes: 66 additions & 17 deletions gtest.flx
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
// GRAMMAR TREE SYNTAX using polymorphic variants
SCHEME """(define (mklist es)`(ast_apply ,_sr (,(nos "list") (ast_tuple ,_sr ,es))))""";

syntax grammar {
x[let_pri]:= "grammar" xproduction* "endgrammar" =>#
"""`(ast_variant ("grammar" ,(mklist _2)))"""
;

xproduction := sname ":=" (xnonterminal | xterminal)* ";" =>#
xproduction := sname ":=" (xnonterminal | xterminal)* "=>#" sstring ";" =>#
"""
(let*
(
(cast (lambda (sym)`(ast_coercion ,_sr (,sym ,(nos "sym_t")))))
(mapcast (map cast _3))
)
`(ast_variant ("production" (ast_tuple ,_sr (,(stringof _1) ,(mklist mapcast)))))
`(ast_variant ("production" (ast_tuple ,_sr (,(stringof _1) ,(mklist mapcast) ,(stringof _5)))))
)
"""
;
Expand All @@ -24,51 +25,99 @@ xnonterminal := sname =>#
xterminal := sstring =># // a string, to be interpreted as a regexp
"""`(ast_variant ("terminal" ,(stringof _1))))""";
}

open syntax grammar;
println$ "Grammar test";
var s = grammar
start := x y;
x := "Jello";
y := "world";
endgrammar;
println$ "Grammar spec parsed";
//----------------------------------------------------------
// TREE TYPES
typedef gram_t = (
| `grammar of list[prod_t]
);
typedef prod_t = (
| `production of string * list[sym_t]
| `production of string * list[sym_t] * string
);
typedef sym_t = (
| `terminal of string
| `nonterminal of string
);

//----------------------------------------------------------
// TREE PRETTY PRINTS
instance Str[sym_t] {
fun str(x:sym_t):string =>
match x with
| `terminal s => "(terminal " + s + ")"
| `nonterminal s => "(nonterminal " + s + ")"
| `terminal s => s.repr
| `nonterminal s => s
endmatch
;
}
instance Str[prod_t] {
fun str(x:prod_t):string =>
match x with
| `production (name, ls) => " production " name + " := " + List::cat "," (List::map (str of sym_t) ls) + ";"
| `production (name, symbols, action) =>
" " + name + " := " + List::cat "," (List::map (str of sym_t) symbols) +" =># " + action.repr + ";"
endmatch
;
}
instance Str[gram_t] {
fun str(x:gram_t):string =>
match x with
| `grammar ls => "grammar" + List::cat "\n" (List::map (str of prod_t) ls) +"\nendgrammar\n"
| `grammar ls => "grammar\n" + List::cat "\n" (List::map (str of prod_t) ls) +"\nendgrammar\n"
endmatch
;
}


//----------------------------------------------------------
// ARRAY FORMAT
typedef aprod_t = (
| `aproduction of string * varray[sym_t] * string
);
typedef agram_t = (
| `agrammar of varray[aprod_t]
);

fun make_aprod: prod_t -> aprod_t =
| `production (name,symbols,action) =>
let new_symbols = varray symbols in
`aproduction(name,new_symbols,action)
;

fun make_agram: gram_t -> agram_t =
| `grammar productions =>
let new_productions = varray(List::map make_aprod productions) in
`agrammar new_productions
;

instance Str[aprod_t] {
fun str(p:aprod_t) =>
match p with
| `aproduction (name, symbols, action) =>
" " + name + " := " + List::cat "," (List::map (str of sym_t) symbols.as_list) +" =># " + action.repr + ";"
endmatch
;
}
instance Str[agram_t] {
fun str(x:agram_t):string =>
match x with
| `agrammar productions => "grammar\n" + List::cat "\n" (List::map (str of aprod_t) productions.as_list) +"\nendgrammar\n"
endmatch
;
}

//----------------------------------------------------------
// TEST CASE

open syntax grammar;
println$ "Grammar test";
var s = grammar
start := x y =># "act1";
x := "Jello" =># "act2";
y := "world" =># "act3";
endgrammar;
println$ "Grammar spec parsed";

var a = make_agram s;

println$ s.str;
println$ "tree format\n" + s.str;
println$ "array format\n" + a.str;



5 changes: 5 additions & 0 deletions src/packages/arrays.fdoc
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,11 @@ open class Varray
varray[T] (l,l,g)
;

fun as_list[T] (x:varray[T]): List::list[T] {
var y = List::Empty[T];
for elt in x perform y = List::Snoc(y,elt);
return y.rev.unbox;
}
}

instance[T with Show[T]] Str[Varray::varray[T]] {
Expand Down
2 changes: 1 addition & 1 deletion src/packages/strings.fdoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class Str [T] {
}

class Repr [T with Str[T]] {
virtual fun repr (t:T) : string => str t;
virtual fun repr: T -> string;
}

class Show [T] {
Expand Down

0 comments on commit ea59616

Please sign in to comment.