diff --git a/extras/moose/moose.m b/extras/moose/moose.m index f86b94ce8..327877b1e 100644 --- a/extras/moose/moose.m +++ b/extras/moose/moose.m @@ -1,5 +1,5 @@ %----------------------------------------------------------------------------% -% Copyright (C) 1998-2003 The University of Melbourne. +% Copyright (C) 1998-2004 The University of Melbourne. % This file may only be copied under the terms of the GNU General % Public License - see the file COPYING in the Mercury Distribution. % @@ -657,6 +657,8 @@ write_parser(Where, NT, Decl, _TT, InAtom, OutAtom, !IO) :- true ), io__format("\ +:- import_module list. + parse(Result, Toks0, Toks) :- parse(Toks0, Toks, [0], [], Result). diff --git a/extras/moose/tests/Mmakefile b/extras/moose/tests/Mmakefile new file mode 100644 index 000000000..238f45b9d --- /dev/null +++ b/extras/moose/tests/Mmakefile @@ -0,0 +1,17 @@ + +.SUFFIXES: .m .moo + +default_target : all + +depend : array_based.depend + +array_based.depend: array_based.m + +all: array_based.c + +.moo.m: + ../moose $< + +realclean: + rm -f array_based.m + diff --git a/extras/moose/tests/array_based.moo b/extras/moose/tests/array_based.moo new file mode 100644 index 000000000..01105b030 --- /dev/null +++ b/extras/moose/tests/array_based.moo @@ -0,0 +1,81 @@ +% This is a regression test. It tests that Moo supports parsers that do not +% use lists. + +:- module array_based. + +:- interface. + +:- import_module char, int, array. + +:- type token + ---> ('+') + ; num(int) + ; ('(') + ; (')') + ; eof + . + +:- parse(exprn/1, token, eof, xx, in, out). + +:- pred scan(array(char), array(token)). +:- mode scan(in, out) is det. + +:- implementation. + +:- import_module string, require. + +:- rule exprn(int). +exprn(Num) ---> exprn(A), [+], term(B), { Num = A + B }. +exprn(Term) ---> term(Term). + +:- rule term(int). +term(Num) ---> factor(Num). + +:- rule factor(int). +factor(Num) ---> ['('], exprn(Num), [')']. +factor(Num) ---> [num(Num)]. + +scan(Chars, Toks) :- + scan(Chars, array__make_empty_array, Toks0), + Toks = array_reverse(Toks0). + +:- pred scan(array(char), array(token), array(token)). +:- mode scan(in, in, out) is det. + +scan(Cs0, Toks0, Toks) :- + ( array__size(Cs0) = 0 -> + Toks = array_cons(eof, Toks0) + ; + C = Cs0^elem(0), + Cs = array_tail(Cs0), + (if + char__is_whitespace(C) + then + scan(Cs, Toks0, Toks) + else if + char__digit_to_int(C, Num) + then + scan(Cs, array_cons(num(Num), Toks0), Toks) + else if + C = ('+') + then + scan(Cs, array_cons('+', Toks0), Toks) + else if + C = ('(') + then + scan(Cs, array_cons('(', Toks0), Toks) + else if + C = (')') + then + scan(Cs, array_cons(')', Toks0), Toks) + else + error("expr: syntax error in input") + ) + ). + +:- func array_cons(T, array(T)) = array(T). +:- external(array_cons/2). +:- func array_reverse(array(T)) = array(T). +:- external(array_reverse/1). +:- func array_tail(array(T)) = array(T). +:- external(array_tail/1).