mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-12 20:34:19 +00:00
Estimated hours taken: 1 Branches: main extras/moose/moose.m: Fix a bug introduced by petr's last change: put back the `:- import_module list.' declaration, since it is needed for the references to `[]', `[|]', `list', and `list_skel'. But put it back in the implementation section rather than in the interface section, because it is not needed by the interface. extras/moose/tests/Mmakefile: extras/moose/tests/array_based.moo: Add a regression test.
82 lines
1.6 KiB
Plaintext
82 lines
1.6 KiB
Plaintext
% 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).
|