From 0b83a7f154dd462300bec448089541d0b1b6521a Mon Sep 17 00:00:00 2001 From: Salvador Abreu Date: Thu, 2 Jul 2015 17:26:48 +0900 Subject: [PATCH] First stab at semantic analysis (names & types). New Prolog files for semantic analysis (semantic.pl), symbol table (stable.pl) and known types (types.pl). Lots of changes in grammar. fznslurp is now fzsem; new "name" action. --- fzn-parser/Makefile | 11 ++++++++--- fzn-parser/TODO | 3 +++ fzn-parser/examples/aust.ast | 76 ++++++++++++++++++++++++++++++++++++++++++++-------------------------------- fzn-parser/examples/aust.ast.old | 23 +++++++++++++++++++++++ fzn-parser/flatzinc.y | 68 ++++++++++++++++++++++++++++++++++++++++++++------------------------ fzn-parser/fznslurp.pl | 11 ++++++++--- fzn-parser/semantic.pl | 32 ++++++++++++++++++++++++++++++++ fzn-parser/stable.pl | 10 ++++++++++ fzn-parser/types.pl | 6 ++++++ 9 files changed, 178 insertions(+), 62 deletions(-) create mode 100644 fzn-parser/TODO create mode 100644 fzn-parser/semantic.pl create mode 100644 fzn-parser/stable.pl create mode 100644 fzn-parser/types.pl diff --git a/fzn-parser/Makefile b/fzn-parser/Makefile index 7488d16..5a69d99 100644 --- a/fzn-parser/Makefile +++ b/fzn-parser/Makefile @@ -3,6 +3,8 @@ OBJ = flatzinc.tab.o GENCFILES = flatzinc.tab.c lex.yy.c OTHER = flatzinc.output +PLFILES = $(wildcard *.pl) + # NOTE: we need to pass the `-l' flag to ensure the scanner internal # variable `yylineno' is available. # @@ -20,13 +22,16 @@ GPLC = gplc RM = /bin/rm -f -all: fzp fznslurp +%.ast:: %.fzn + fzp < $< > $@ + +all: fzp fzsem fzp: $(OBJ) $(CC) $(CFLAGS) -o $@ $(OBJ) $(LEXLIB) -fznslurp: fznslurp.pl - $(GPLC) -o $@ $< +fzsem: $(PLFILES) + $(GPLC) -o $@ $(PLFILES) flatzinc.tab.c: flatzinc.y lex.yy.c $(YACC) $(YACCFLAGS) flatzinc.y diff --git a/fzn-parser/TODO b/fzn-parser/TODO new file mode 100644 index 0000000..059b254 --- /dev/null +++ b/fzn-parser/TODO @@ -0,0 +1,3 @@ +- define AST syntax +- define type system +- \ No newline at end of file diff --git a/fzn-parser/examples/aust.ast b/fzn-parser/examples/aust.ast index bcea9bc..6f8f443 100644 --- a/fzn-parser/examples/aust.ast +++ b/fzn-parser/examples/aust.ast @@ -3,69 +3,69 @@ _T > [[]|_T]. [X|_T] > [preds(X)|_T]. _T > [[]|_T]. _T > [int|_T]. -_T > [id('X_INTRODUCED_0')|_T]. +_T > ['X_INTRODUCED_0'|_T]. _T > [[]|_T]. _T > [int:lit(1)|_T]. _T > [int:lit(-1)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [Es|_T] > [array(_):alit(Es)|_T]. -[VAL,AN,T|_T] > [var(array(T,1,2), VAL, AN)|_T]. +[VAL,AN,ID,T|_T] > [var(ID, array(T,1,2), VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. -_T > [id('wa')|_T]. +_T > ['wa'|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. -[H,T|_T] > [[H|T]|_T]. +[As, E|_T] > [[E|As]|_T]. _T > [[]|_T]. -[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. +[VAL,AN,ID,T|_T] > [var(ID, T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. -_T > [id('nt')|_T]. +_T > ['nt'|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. -[H,T|_T] > [[H|T]|_T]. +[As, E|_T] > [[E|As]|_T]. _T > [[]|_T]. -[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. +[VAL,AN,ID,T|_T] > [var(ID, T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. -_T > [id('sa')|_T]. +_T > ['sa'|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. -[H,T|_T] > [[H|T]|_T]. +[As, E|_T] > [[E|As]|_T]. _T > [[]|_T]. -[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. +[VAL,AN,ID,T|_T] > [var(ID, T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. -_T > [id('q')|_T]. +_T > ['q'|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. -[H,T|_T] > [[H|T]|_T]. +[As, E|_T] > [[E|As]|_T]. _T > [[]|_T]. -[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. +[VAL,AN,ID,T|_T] > [var(ID, T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. -_T > [id('nsw')|_T]. +_T > ['nsw'|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. -[H,T|_T] > [[H|T]|_T]. +[As, E|_T] > [[E|As]|_T]. _T > [[]|_T]. -[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. +[VAL,AN,ID,T|_T] > [var(ID, T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. -_T > [id('v')|_T]. +_T > ['v'|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. -[H,T|_T] > [[H|T]|_T]. +[As, E|_T] > [[E|As]|_T]. _T > [[]|_T]. -[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. +[VAL,AN,ID,T|_T] > [var(ID, T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. -_T > [id('t')|_T]. +_T > ['t'|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. -[H,T|_T] > [[H|T]|_T]. +[As, E|_T] > [[E|As]|_T]. _T > [[]|_T]. -[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. +[VAL,AN,ID,T|_T] > [var(ID, T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. [X|_T] > [vars(X)|_T]. _T > [[]|_T]. @@ -77,8 +77,9 @@ _T > [_:id('nt')|_T]. _T > [int:lit(0)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. +[AL|_T] > [C|_T] :- C =.. ['int_lin_ne'|AL]. _T > [[]|_T]. -[A, C|_T] > [constraint(C, A)|_T]. +[A,C,E|_T] > [constraint(C,E,A)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [_:id('X_INTRODUCED_0')|_T]. _T > [_:id('wa')|_T]. @@ -88,8 +89,9 @@ _T > [_:id('sa')|_T]. _T > [int:lit(0)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. +[AL|_T] > [C|_T] :- C =.. ['int_lin_ne'|AL]. _T > [[]|_T]. -[A, C|_T] > [constraint(C, A)|_T]. +[A,C,E|_T] > [constraint(C,E,A)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [_:id('X_INTRODUCED_0')|_T]. _T > [_:id('nt')|_T]. @@ -99,8 +101,9 @@ _T > [_:id('sa')|_T]. _T > [int:lit(0)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. +[AL|_T] > [C|_T] :- C =.. ['int_lin_ne'|AL]. _T > [[]|_T]. -[A, C|_T] > [constraint(C, A)|_T]. +[A,C,E|_T] > [constraint(C,E,A)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [_:id('X_INTRODUCED_0')|_T]. _T > [_:id('nt')|_T]. @@ -110,8 +113,9 @@ _T > [_:id('q')|_T]. _T > [int:lit(0)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. +[AL|_T] > [C|_T] :- C =.. ['int_lin_ne'|AL]. _T > [[]|_T]. -[A, C|_T] > [constraint(C, A)|_T]. +[A,C,E|_T] > [constraint(C,E,A)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [_:id('X_INTRODUCED_0')|_T]. _T > [_:id('sa')|_T]. @@ -121,8 +125,9 @@ _T > [_:id('q')|_T]. _T > [int:lit(0)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. +[AL|_T] > [C|_T] :- C =.. ['int_lin_ne'|AL]. _T > [[]|_T]. -[A, C|_T] > [constraint(C, A)|_T]. +[A,C,E|_T] > [constraint(C,E,A)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [_:id('X_INTRODUCED_0')|_T]. _T > [_:id('sa')|_T]. @@ -132,8 +137,9 @@ _T > [_:id('nsw')|_T]. _T > [int:lit(0)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. +[AL|_T] > [C|_T] :- C =.. ['int_lin_ne'|AL]. _T > [[]|_T]. -[A, C|_T] > [constraint(C, A)|_T]. +[A,C,E|_T] > [constraint(C,E,A)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [_:id('X_INTRODUCED_0')|_T]. _T > [_:id('sa')|_T]. @@ -143,8 +149,9 @@ _T > [_:id('v')|_T]. _T > [int:lit(0)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. +[AL|_T] > [C|_T] :- C =.. ['int_lin_ne'|AL]. _T > [[]|_T]. -[A, C|_T] > [constraint(C, A)|_T]. +[A,C,E|_T] > [constraint(C,E,A)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [_:id('X_INTRODUCED_0')|_T]. _T > [_:id('q')|_T]. @@ -154,8 +161,9 @@ _T > [_:id('nsw')|_T]. _T > [int:lit(0)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. +[AL|_T] > [C|_T] :- C =.. ['int_lin_ne'|AL]. _T > [[]|_T]. -[A, C|_T] > [constraint(C, A)|_T]. +[A,C,E|_T] > [constraint(C,E,A)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [_:id('X_INTRODUCED_0')|_T]. _T > [_:id('nsw')|_T]. @@ -165,8 +173,12 @@ _T > [_:id('v')|_T]. _T > [int:lit(0)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. +[AL|_T] > [C|_T] :- C =.. ['int_lin_ne'|AL]. _T > [[]|_T]. -[A, C|_T] > [constraint(C, A)|_T]. +[A,C,E|_T] > [constraint(C,E,A)|_T]. [H,T|_T] > [[H|T]|_T]. [X|_T] > [constrs(X)|_T]. _T > [[]|_T]. +_T > [satisfy|_T]. +[S,A|_T] > [solve(S, A)|_T]. +[S,C,V,P|_T] > [fzn(P, V, C, S)|_T]. diff --git a/fzn-parser/examples/aust.ast.old b/fzn-parser/examples/aust.ast.old index eb5aeb1..bcea9bc 100644 --- a/fzn-parser/examples/aust.ast.old +++ b/fzn-parser/examples/aust.ast.old @@ -3,46 +3,69 @@ _T > [[]|_T]. [X|_T] > [preds(X)|_T]. _T > [[]|_T]. _T > [int|_T]. +_T > [id('X_INTRODUCED_0')|_T]. _T > [[]|_T]. _T > [int:lit(1)|_T]. _T > [int:lit(-1)|_T]. [T2:E2,T1:E1|_T] > [(T1,T2):(E1,E2)|_T]. [Es|_T] > [array(_):alit(Es)|_T]. +[VAL,AN,T|_T] > [var(array(T,1,2), VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. +_T > [id('wa')|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. [H,T|_T] > [[H|T]|_T]. +_T > [[]|_T]. +[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. +_T > [id('nt')|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. [H,T|_T] > [[H|T]|_T]. +_T > [[]|_T]. +[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. +_T > [id('sa')|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. [H,T|_T] > [[H|T]|_T]. +_T > [[]|_T]. +[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. +_T > [id('q')|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. [H,T|_T] > [[H|T]|_T]. +_T > [[]|_T]. +[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. +_T > [id('nsw')|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. [H,T|_T] > [[H|T]|_T]. +_T > [[]|_T]. +[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. +_T > [id('v')|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. [H,T|_T] > [[H|T]|_T]. +_T > [[]|_T]. +[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. _T > [int(1,3)|_T]. +_T > [id('t')|_T]. _T > [_:id('output_var')|_T]. _T > [[]|_T]. [H,T|_T] > [[H|T]|_T]. +_T > [[]|_T]. +[VAL,AN,T|_T] > [var(T, VAL, AN)|_T]. [H,T|_T] > [[H|T]|_T]. [X|_T] > [vars(X)|_T]. _T > [[]|_T]. diff --git a/fzn-parser/flatzinc.y b/fzn-parser/flatzinc.y index 842f3f4..512faf6 100644 --- a/fzn-parser/flatzinc.y +++ b/fzn-parser/flatzinc.y @@ -19,6 +19,14 @@ #include "types.h" +// -- AST stack macros: ------------------------------------------------------- +// AST (POP, (PUSH)) +// ASTT (POP, (PUSH), TRANS) +// INIT (STACK) +// PUSH (ITEM) +// CONS () +// NIL () + #define AST(pop, push) \ { \ printf ("[%s|_T] > [", pop); \ @@ -26,6 +34,15 @@ printf ("|_T].\n"); \ } +#define ASTT(pop, push, trans) \ +{ \ + printf ("[%s|_T] > [", pop); \ + printf push; \ + printf ("|_T] :- "); \ + printf trans; \ + printf (".\n"); \ +} + #define INIT(x) \ { \ printf ("_ > %s.\n", x); \ @@ -51,6 +68,9 @@ // pop an item and a list, push new list (CONS) #define CONS() AST ("H,T", ("[H|T]")) + // pop a list and an item, push new list (RCONS) +#define RCONS() AST ("T,H", ("[H|T]")) + // push the empty list #define NIL() PUSH (("[]")) @@ -67,7 +87,9 @@ IDENT UNDERSCORE_IDENT ARRAY BOOL CONSTRAINT FALSE FLOAT INT MAXIMIZE MINIMIZE OF PREDICATE SATISFY SET SOLVE TRUE VAR DOTDOT COLONCOLON - + +%right ',' + %% //--------------------------------------------------------------------------- @@ -132,10 +154,10 @@ ident_anns: /* -> [ ANNOT,ID | _ ] */ constraint_item: /* -> [ constraint(...) | ] */ CONSTRAINT constraint_elem annotations - { AST ("A,C,E", ("constraint(C,E,A)")); } + { AST ("A,C", ("constraint(C,A)")); } constraint_elem: /* -> [ CONSTR_ID, EXPRLIST | _ ] */ - IDENT '(' exprs ')' { PUSH (("'%s'", $1)); } + IDENT '(' exprs ')' { ASTT ("AL", ("C"), ("C =.. ['%s'|AL]", $1)); } solve_item: /* -> [ solve(S,A) | _ ] */ SOLVE annotations solve_kind { AST ("S,A", ("solve(S, A)")); } @@ -191,7 +213,7 @@ int_ti_expr_tail: | '{' int_literals '}' { AST ("Ls", ("int(Ls)")); } int_literals: - INT_LITERAL ',' int_literals { AST ("Ls, L", ("[L|Ls]")); } + INT_LITERAL ',' int_literals { AST ("Ls", ("[%d|Ls]", $1)); } | INT_LITERAL { PUSH (("[%d]", $1)); } float_ti_expr_tail: @@ -206,46 +228,44 @@ set_ti_expr_tail: //--------------------------------------------------------------------------- exprs: - expr ',' exprs { AST ("T2:E2,T1:E1", ("(T1,T2):(E1,E2)")); } - | expr + exprs ',' exprs { CONS (); } + | expr { AST ("E", ("[E]")); } expr: bool_literal - | INT_LITERAL { PUSH (("int:lit(%d)", $1.ival)); } - | FLOAT_LITERAL { PUSH (("float:lit(%g)", $1.rval)); } - | STRING_LITERAL { PUSH (("string:lit(\"%s\")", $1.sval)); } + | INT_LITERAL { PUSH (("lit(%d,int)", $1.ival)); } + | FLOAT_LITERAL { PUSH (("lit(%g,float)", $1.rval)); } + | STRING_LITERAL { PUSH (("lit(\"%s\",string)", $1.sval)); } | set_literal | array_literal | array_access_expr - | IDENT { PUSH (("_:id('%s')", $1)); } - | UNDERSCORE_IDENT { PUSH (("_:uid('%s')", $1)); } + | IDENT { PUSH (("id('%s')", $1)); } + | UNDERSCORE_IDENT { PUSH (("id('%s')", $1)); } | IDENT '(' exprs ')' /* An annotation value with > 0 arguments. */ bool_literal: - FALSE { PUSH (("bool:lit(false)")); } - | TRUE { PUSH (("bool:lit(true)")); } + FALSE { PUSH (("lit(false,bool)")); } + | TRUE { PUSH (("lit(true,bool)")); } set_literal: - '{' exprs '}' { AST ("Ts:Es", ("set(Ts):lit(Es)")); } - | '{' '}' { PUSH (("set(_):lit([])")); } + '{' exprs '}' { AST ("Es", ("lit(Es,set(_))")); } + | '{' '}' { PUSH (("lit([],set(_))")); } | INT_LITERAL DOTDOT INT_LITERAL { int i; PRE(); - printf ("set(int):lit("); + printf ("lit(["); for (i=$1.ival; i<$3.ival; ++i) printf ("%d, ", i); - printf ("%d)", $3.ival); + printf ("%d], set(int))", $3.ival); POST(); } array_literal: - '[' exprs ']' { AST ("Es", ("array(_):alit(Es)")); } - | '[' ']' { PUSH (("array(_):alit([])")); } + '[' exprs ']' { AST ("Es", ("lit(Es,array(_))")); } + | '[' ']' { PUSH (("lit([],array(_))")); } -array_access_expr: IDENT '[' INT_LITERAL ']' - { AST ("int:EI,array(T):ID", - ("T:aref(array(T):ID,int:EI)")); } +array_access_expr: + IDENT '[' INT_LITERAL ']' { PUSH (("aref('%s',lit(%d,int),_)",$1,$3)); } | UNDERSCORE_IDENT '[' INT_LITERAL ']' - { AST ("int:EI,array(T):ID", - ("T:aref(array(T):ID,int:EI)")); } + { PUSH (("aref('%s',lit(%d,int),_)",$1,$3)); } //--------------------------------------------------------------------------- // Annotations diff --git a/fzn-parser/fznslurp.pl b/fzn-parser/fznslurp.pl index bfaffe4..62d9d0a 100644 --- a/fzn-parser/fznslurp.pl +++ b/fzn-parser/fznslurp.pl @@ -11,9 +11,13 @@ main([]). action(load) :- !, load_ast(AST), g_assign(ast, AST). action(dump) :- !, g_read(ast, AST), dump_ast(AST). +action(name) :- !, + g_read(ast, AST), + sa_names(AST, NAST), + g_assign(ast, NAST). action(halt) :- !, halt. -action(debug) :- g_read(ast_debug, true), !, g_write(ast_debug, false). -action(debug) :- !, g_write(ast_debug, true). +action(debug) :- g_read(ast_debug, true), !, g_assign(ast_debug, false). +action(debug) :- !, g_assign(ast_debug, true). action(ACTION) :- format("%w: unknown action.\n", [ACTION]). @@ -35,7 +39,8 @@ load_ast((IN > INT), IN, OUT) :- load_ast_deb(end_of_file, AST, AST). load_ast_deb(IN > INT, IN, OUT) :- read(OP), !, - write(OP), nl, + writeq(IN), write('.'), nl, + writeq(OP), nl, load_ast_deb(OP, INT, OUT). % ----------------------------------------------------------------------------- diff --git a/fzn-parser/semantic.pl b/fzn-parser/semantic.pl new file mode 100644 index 0000000..278f5e8 --- /dev/null +++ b/fzn-parser/semantic.pl @@ -0,0 +1,32 @@ +% == No, Emacs this is -*-Prolog-*- code, not what you thought... ============= + +sa_names(fzn(preds(IP), vars(IV), constrs(IC), SOLVE), + fzn(preds(OP), vars(OV), constrs(OC), SOLVE, ST)) :- + sa_n_traverse(IP, OP, [], ST1), % predicates + sa_n_traverse(IV, OV, ST1, ST2), % variables + sa_n_traverse(IC, OC, ST2, ST). % constraints + +% ----------------------------------------------------------------------------- + +sa_n_traverse([], [], ST, ST). +sa_n_traverse([N|Ns], [NN|NNs], IST, OST) :- + sa_n(N, NN, IST, MST), + sa_n_traverse(Ns, NNs, MST, OST). + + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +% +% sa_n(AST_N_IN, AST_N_OUT, ST_IN, ST_OUT) + +sa_n(var(N,T,I,A), var(N,T), IST, OST) :- + sa_attribs(A, AX, IST, ST1), + st_insert(ST1, N, var(N,T,I,AX), OST). + +sa_n(constraint(_C)). + +% - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +sa_attribs(A, NA, IST, OST) :- + true. + +% ----------------------------------------------------------------------------- diff --git a/fzn-parser/stable.pl b/fzn-parser/stable.pl new file mode 100644 index 0000000..0f79695 --- /dev/null +++ b/fzn-parser/stable.pl @@ -0,0 +1,10 @@ +% == No, Emacs this is -*-Prolog-*- code, not what you thought... ============= + +% -- Symbol table ------------------------------------------------------------- + +st_lookup([K=V|_], K, V). +st_lookup([_|ST], K, V) :- st_lookup(ST, K, V). + +st_insert([], K, V, [K=V]) :- !. +st_insert([K=_|_], K, _, _) :- !, throw(duplicate(K)). +st_insert([KV0|ST], K, V, [KV0|STx]) :- st_insert(ST, K, V, STx). diff --git a/fzn-parser/types.pl b/fzn-parser/types.pl new file mode 100644 index 0000000..bac9eca --- /dev/null +++ b/fzn-parser/types.pl @@ -0,0 +1,6 @@ +% == No, Emacs this is -*-Prolog-*- code, not what you thought... ============= + +% sa_type/2 - locate the TYPE field + +sa_type(var(_NAME,TYPE,_INIT,_ANNOT), TYPE). +sa_type(constraint(_NAME)). -- libgit2 0.21.2