mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 01:43:35 +00:00
extras/moose/moose.m:
Fix an invalid conversion specifier in a call to string.format
in the generated code.
extras/moose/samples/alpha.moo:
extras/moose/samples/cgram.moo:
extras/moose/samples/expr.moo:
extras/moose/samples/small.moo:
Fix compilation problems.
Clean-up and update syntax.
71 lines
1.8 KiB
Plaintext
71 lines
1.8 KiB
Plaintext
:- module expr.
|
|
:- interface.
|
|
|
|
:- import_module char.
|
|
:- import_module int.
|
|
:- import_module list.
|
|
|
|
:- type token
|
|
---> ('+')
|
|
; ('-')
|
|
; ('*')
|
|
; ('/')
|
|
; num(int)
|
|
; ('(')
|
|
; (')')
|
|
; eof.
|
|
|
|
:- parse(exprn/1, token, eof, xx, in, out).
|
|
|
|
:- pred scan(list(char)::in, list(token)::out) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module require.
|
|
:- import_module string.
|
|
|
|
:- rule exprn(int).
|
|
exprn(Num) ---> exprn(A), [+], term(B), { Num = A + B }.
|
|
exprn(Num) ---> exprn(A), [-], term(B), { Num = A - B }.
|
|
exprn(Num) ---> term(Num).
|
|
|
|
:- rule term(int).
|
|
term(Num) ---> term(A), [*], factor(B), { Num = A * B }.
|
|
term(Num) ---> term(A), [/], factor(B), { Num = A // B }.
|
|
term(Num) ---> factor(Num).
|
|
|
|
:- rule factor(int).
|
|
factor(Num) ---> ['('], exprn(Num), [')'].
|
|
factor(Num) ---> [num(Num)].
|
|
|
|
scan(Chars, Toks) :-
|
|
scan(Chars, [], Toks0),
|
|
list.reverse(Toks0, Toks).
|
|
|
|
:- pred scan(list(char)::in, list(token)::in, list(token)::out) is det.
|
|
|
|
scan([], Toks, [eof | Toks]).
|
|
scan([C | Cs], Toks0, Toks) :-
|
|
( if char.is_whitespace(C) then
|
|
scan(Cs, Toks0, Toks)
|
|
else if char.is_digit(C) then
|
|
take_while(char.is_digit, [C | Cs], Digits, Rest),
|
|
string.from_char_list(Digits, NumStr),
|
|
Num = string.det_to_int(NumStr),
|
|
scan(Rest, [num(Num) | Toks0], Toks)
|
|
else if C = ('+') then
|
|
scan(Cs, ['+' | Toks0], Toks)
|
|
else if C = ('-') then
|
|
scan(Cs, ['-' | Toks0], Toks)
|
|
else if C = ('*') then
|
|
scan(Cs, ['*' | Toks0], Toks)
|
|
else if C = ('/') then
|
|
scan(Cs, ['/' | Toks0], Toks)
|
|
else if C = ('(') then
|
|
scan(Cs, ['(' | Toks0], Toks)
|
|
else if C = (')') then
|
|
scan(Cs, [')' | Toks0], Toks)
|
|
else
|
|
error("expr: syntax error in input")
|
|
).
|