mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 09:53:36 +00:00
Estimated hours taken: 0.2 Branches: main Fix a bug that prevented some of the Mercury programs used for the packrat paper from compiling. This is the bug description from the new test case: % This is a regression test. In versions of the compiler before 7 Aug 2007, % it used to cause this compiler abort: % % Software Error: code_gen.m: Unexpected: nondet model in det/semidet context % % when generating code for the java_identifier predicate. % % The bug was that the follow_code pass would push a goal binding a variable % into a semidet disjunction. This would cause the disjunction to have an % output, which would cause the simplify pass to change its determinism, % and from there the determinism of the entire procedure body, to nondet. % Since java_identifier is supposed to be semidet, this causes the abort above. compiler/follow_code.m: Fix the bug. tests/valid/mercury_java_parser_follow_code_bug.m: Add the new test case. tests/valid/Mmakefile: Enable the new test case.
1999 lines
46 KiB
Mathematica
1999 lines
46 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
||
% vim: ft=mercury ts=4 sw=4 et
|
||
%-----------------------------------------------------------------------------%
|
||
%
|
||
% This is a regression test. In versions of the compiler before 7 Aug 2007,
|
||
% it used to cause this compiler abort:
|
||
%
|
||
% Software Error: code_gen.m: Unexpected: nondet model in det/semidet context
|
||
%
|
||
% when generating code for the java_identifier predicate.
|
||
%
|
||
% The bug was that the follow_code pass would push a goal binding a variable
|
||
% into a semidet disjunction. This would cause the disjunction to have an
|
||
% output, which would cause the simplify pass to change its determinism,
|
||
% and from there the determinism of the entire procedure body, to nondet.
|
||
% Since java_identifier is supposed to be semidet, this causes the abort above.
|
||
%
|
||
%-----------------------------------------------------------------------------%
|
||
% Ralph Becket <rafe@cs.mu.oz.au>
|
||
% Mon Feb 21 09:42:40 EST 2005
|
||
%
|
||
% Java grammar taken from
|
||
% http://java.sun.com/docs/books/jls/second_edition/html/syntax.doc.html
|
||
% and converted to Mercury DCGs. And then corrected because the grammar
|
||
% at the above page contains bugs...
|
||
%
|
||
% Usage: parse_java <filename> ...
|
||
%
|
||
% This implementation only recognises Java programs; it does not construct an
|
||
% ADT or perform any kind of analysis. However, it has been written in a
|
||
% style that should make it fairly easy to add construction of an ADT.
|
||
%
|
||
% To compile this as a packrat parser, uncomment all of the pragma memo
|
||
% lines.
|
||
%
|
||
% To compile this as a partial packrat parser, uncomment all of the
|
||
% pragma memo lines except those for literal/2, qualified_identifier/2, and
|
||
% punct/2.
|
||
%
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- module mercury_java_parser_follow_code_bug.
|
||
|
||
:- interface.
|
||
|
||
:- import_module io.
|
||
|
||
:- pred main(io :: di, io :: uo) is det.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- implementation.
|
||
|
||
:- import_module char.
|
||
:- import_module exception.
|
||
:- import_module int.
|
||
:- import_module list.
|
||
:- import_module std_util.
|
||
:- import_module string.
|
||
|
||
% The parser "state". This is just the offset into the input string,
|
||
% which is stored in a C global. We do this to (a) avoid memoizing the
|
||
% input string if we are memoing any rules and (b) to obtain a fair
|
||
% timing comparison with the Rats! Java parser
|
||
% (www.cs.nyu.edu/rgrimm/xtc/rats.html).
|
||
%
|
||
:- type ps == int.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
main(!IO) :-
|
||
io.command_line_arguments(Args, !IO),
|
||
list.foldl(parse_file, Args, !IO).
|
||
|
||
:- pred parse_file(string::in, io::di, io::uo) is det.
|
||
:- pragma promise_pure(parse_file/3).
|
||
|
||
parse_file(Filename, !IO) :-
|
||
io.write_string(Filename, !IO),
|
||
io.see(Filename, _, !IO),
|
||
io.read_file_as_string(Result, !IO),
|
||
( if Result = ok(Str) then
|
||
impure set_input_string(Str),
|
||
( if compilation_unit(0, _)
|
||
then io.print(" parsed successfully\n", !IO)
|
||
else io.print(" failed to parse\n", !IO)
|
||
)
|
||
else
|
||
throw(Result)
|
||
).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
%-----------------------------------------------------------------------------%
|
||
% Low-level predicates.
|
||
%-----------------------------------------------------------------------------%
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pragma foreign_decl("C", "
|
||
|
||
MR_String input_string = NULL;
|
||
MR_Word input_length = (MR_Word)0;
|
||
|
||
").
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- impure pred set_input_string(string::in) is det.
|
||
|
||
:- pragma foreign_proc("C",
|
||
set_input_string(Str::in),
|
||
[will_not_call_mercury], "
|
||
|
||
input_string = Str;
|
||
input_length = strlen(Str);
|
||
|
||
").
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- semipure pred input_string_and_length(string::out, int::out) is det.
|
||
|
||
:- pragma foreign_proc("C",
|
||
input_string_and_length(Str::out, Length::out),
|
||
[will_not_call_mercury, promise_semipure], "
|
||
|
||
Str = input_string;
|
||
Length = input_length;
|
||
|
||
").
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred current_offset(int::out, int::in, int::out) is det.
|
||
|
||
current_offset(Offset, Offset, Offset).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred eof(int::in, int::out) is semidet.
|
||
:- pragma promise_pure(eof/2).
|
||
|
||
eof(Offset, Offset) :-
|
||
semipure input_string_and_length(_Str, Length),
|
||
Offset = Length.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
% XXX These are really semipure, but I'm being naughty and promising them
|
||
% to be pure because I don't want to pollute my code with impurity
|
||
% annotations.
|
||
%
|
||
% XXX Also, I do not check for negative offsets. I probably should.
|
||
%
|
||
:- pred char(char::out, int::in, int::out) is semidet.
|
||
:- pragma promise_pure(char/3).
|
||
|
||
char(Char, Offset, Offset + 1) :-
|
||
semipure input_string_and_length(Str, Length),
|
||
Offset < Length,
|
||
Char = Str ^ unsafe_elem(Offset).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred input_substring(int::in, int::in, string::out,
|
||
int::in, int::out) is semidet.
|
||
:- pragma promise_pure(input_substring/5).
|
||
|
||
input_substring(Start, End, Substring, Offset, Offset) :-
|
||
semipure input_string_and_length(Str, Length),
|
||
End =< Length,
|
||
Substring = unsafe_substring(Str, Start, End - Start).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred match_string(string::in, int::in, int::out) is semidet.
|
||
:- pragma promise_pure(match_string/3).
|
||
|
||
match_string(MatchStr, Offset, Offset + N) :-
|
||
semipure input_string_and_length(Str, Length),
|
||
N = length(MatchStr),
|
||
Offset + N =< Length,
|
||
match_string_2(0, N, MatchStr, Offset, Str).
|
||
|
||
:- pred match_string_2(int::in, int::in, string::in, int::in, string::in)
|
||
is semidet.
|
||
|
||
match_string_2(I, N, MatchStr, Offset, Str) :-
|
||
( if I < N then
|
||
MatchStr ^ unsafe_elem(I) = Str ^ unsafe_elem(Offset + I),
|
||
match_string_2(I + 1, N, MatchStr, Offset, Str)
|
||
else
|
||
true
|
||
).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
%-----------------------------------------------------------------------------%
|
||
% Utility predicates.
|
||
%-----------------------------------------------------------------------------%
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred optional(pred(ps, ps)::in(pred(in, out) is semidet),
|
||
ps::in, ps::out) is semidet.
|
||
|
||
optional(P) -->
|
||
( if P then [] else { semidet_succeed } ).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred zero_or_more(pred(ps, ps)::in(pred(in, out) is semidet),
|
||
ps::in, ps::out) is semidet.
|
||
|
||
zero_or_more(P) -->
|
||
( if P then zero_or_more(P) else { semidet_succeed } ).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred one_or_more(pred(ps, ps)::in(pred(in, out) is semidet),
|
||
ps::in, ps::out) is semidet.
|
||
|
||
one_or_more(P) -->
|
||
P,
|
||
zero_or_more(P).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred brackets(string::in, pred(ps, ps)::in(pred(in, out) is semidet),
|
||
string::in, ps::in, ps::out) is semidet.
|
||
|
||
brackets(L, P, R) -->
|
||
punct(L),
|
||
P,
|
||
punct(R).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred ++(pred(ps, ps)::in(pred(in, out) is semidet),
|
||
pred(ps, ps)::in(pred(in, out) is semidet),
|
||
ps::in, ps::out) is semidet.
|
||
|
||
:- pragma inline((++)/4).
|
||
|
||
P ++ Q -->
|
||
P,
|
||
Q.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred comma_separated_list(pred(ps, ps)::in(pred(in, out) is semidet),
|
||
ps::in, ps::out) is semidet.
|
||
|
||
comma_separated_list(P) -->
|
||
P, zero_or_more(punct(",") ++ P).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred whitespace(ps::in, ps::out) is semidet.
|
||
|
||
whitespace -->
|
||
( if char(C1), { char.is_whitespace(C1) } then
|
||
whitespace
|
||
else if char('/'), char('/') then
|
||
skip_to_eol,
|
||
whitespace
|
||
else if char('/'), char('*') then
|
||
skip_to_end_of_trad_comment,
|
||
whitespace
|
||
else
|
||
[]
|
||
).
|
||
|
||
:- pred skip_to_eol(ps::in, ps::out) is semidet.
|
||
|
||
skip_to_eol -->
|
||
char(C),
|
||
( if { C = ('\n') } then [] else skip_to_eol ).
|
||
|
||
:- pred skip_to_end_of_trad_comment(ps::in, ps::out) is semidet.
|
||
|
||
skip_to_end_of_trad_comment -->
|
||
( if char('*'), char('/') then
|
||
[]
|
||
else
|
||
char(_),
|
||
skip_to_end_of_trad_comment
|
||
).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred punct(string::in, ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(punct/3).
|
||
punct(Punct) -->
|
||
match_string(Punct),
|
||
whitespace.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred keyword(string::in, ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(keyword/3).
|
||
keyword(Keyword) -->
|
||
match_string(Keyword),
|
||
not(java_identifier_part),
|
||
whitespace.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred keyword(string::in, pred(ps, ps)::in(pred(in, out) is semidet),
|
||
ps::in, ps::out) is semidet.
|
||
|
||
keyword(Keyword, P) -->
|
||
match_string(Keyword),
|
||
not(java_identifier_part),
|
||
whitespace,
|
||
P.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pragma memo(java_identifier/2, [allow_reset, fast_loose]).
|
||
|
||
:- pred java_identifier(/*string::out,*/ ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(java_identifier/2).
|
||
java_identifier/*(Identifier)*/ -->
|
||
% current_offset(Start),
|
||
java_identifier_start,
|
||
zero_or_more(java_identifier_part),
|
||
% current_offset(End),
|
||
% input_substring(Start, End, Identifier),
|
||
whitespace.
|
||
|
||
:- pred java_identifier_start(ps::in, ps::out) is semidet.
|
||
|
||
java_identifier_start -->
|
||
char(C),
|
||
{ char.is_alpha_or_underscore(C) ; C = ('$') }.
|
||
|
||
:- pred java_identifier_part(ps::in, ps::out) is semidet.
|
||
|
||
java_identifier_part -->
|
||
char(C),
|
||
{ char.is_alnum_or_underscore(C) ; C = ('$') }.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred floating_point_literal(ps::in, ps::out) is semidet.
|
||
|
||
floating_point_literal -->
|
||
( if optional(digits(10)), char('.'), digits(10) then
|
||
optional(exponent_part),
|
||
optional(float_type_suffix)
|
||
else
|
||
digits(10),
|
||
( if exponent_part then optional(float_type_suffix)
|
||
else float_type_suffix
|
||
)
|
||
).
|
||
|
||
:- pred exponent_part(ps::in, ps::out) is semidet.
|
||
|
||
exponent_part -->
|
||
char(C), { C = ('E') ; C = ('e') },
|
||
optional(sign),
|
||
one_or_more(digit(10)).
|
||
|
||
:- pred sign(ps::in, ps::out) is semidet.
|
||
|
||
sign -->
|
||
char(C), { C = ('+') ; C = ('-') }.
|
||
|
||
:- pred float_type_suffix(ps::in, ps::out) is semidet.
|
||
|
||
float_type_suffix -->
|
||
char(C), { C = ('F') ; C = ('f') ; C = ('D') ; C = ('d') }.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred integer_literal(ps::in, ps::out) is semidet.
|
||
|
||
integer_literal -->
|
||
( if
|
||
hex_literal
|
||
then
|
||
[]
|
||
else if
|
||
oct_literal
|
||
then
|
||
[]
|
||
else
|
||
dec_literal
|
||
).
|
||
|
||
:- pred hex_literal(ps::in, ps::out) is semidet.
|
||
|
||
hex_literal -->
|
||
char('0'),
|
||
char('x'),
|
||
digits(16),
|
||
optional(integer_type_suffix).
|
||
|
||
:- pred oct_literal(ps::in, ps::out) is semidet.
|
||
|
||
oct_literal -->
|
||
char('0'),
|
||
digits(8),
|
||
optional(integer_type_suffix).
|
||
|
||
:- pred dec_literal(ps::in, ps::out) is semidet.
|
||
|
||
dec_literal -->
|
||
( if char('0') then not digit(16) else digits(10) ),
|
||
optional(integer_type_suffix).
|
||
|
||
:- pred integer_type_suffix(ps::in, ps::out) is semidet.
|
||
|
||
integer_type_suffix -->
|
||
char(C), { C = ('L') ; C = ('l') }.
|
||
|
||
:- pred digits(int::in, ps::in, ps::out) is semidet.
|
||
|
||
digits(Base) -->
|
||
one_or_more(digit(Base)).
|
||
|
||
:- pred digit(int::in, ps::in, ps::out) is semidet.
|
||
|
||
digit(Base) -->
|
||
char(C), { char.digit_to_int(C, D), D < Base }.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred character_literal(ps::in, ps::out) is semidet.
|
||
|
||
character_literal -->
|
||
char('\''),
|
||
not char('\''),
|
||
possibly_escaped_char,
|
||
char('\'').
|
||
|
||
:- pred possibly_escaped_char(ps::in, ps::out) is semidet.
|
||
|
||
possibly_escaped_char -->
|
||
char(C1),
|
||
( if { C1 = ('\\') } then
|
||
( if digits(8) then
|
||
[]
|
||
else if char('u'), one_or_more(digits(16)) then
|
||
[]
|
||
else
|
||
char(C2),
|
||
{ member(C2, [('b'), ('t'), ('n'), ('f'), ('r'), ('\"'), ('\''),
|
||
('\\')]) }
|
||
)
|
||
else
|
||
[]
|
||
).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred string_literal(ps::in, ps::out) is semidet.
|
||
|
||
string_literal -->
|
||
char('\"'),
|
||
zero_or_more(string_char),
|
||
char('\"').
|
||
|
||
:- pred string_char(ps::in, ps::out) is semidet.
|
||
|
||
string_char -->
|
||
not(char('"')),
|
||
possibly_escaped_char.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred boolean_literal(ps::in, ps::out) is semidet.
|
||
|
||
boolean_literal -->
|
||
( if
|
||
keyword("true")
|
||
then
|
||
[]
|
||
else
|
||
keyword("false")
|
||
).
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
|
||
:- pred null_literal(ps::in, ps::out) is semidet.
|
||
|
||
null_literal -->
|
||
keyword("null").
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
%-----------------------------------------------------------------------------%
|
||
% Taken from
|
||
% http://java.sun.com/docs/books/jls/second_edition/html/syntax.doc.html
|
||
|
||
% _________________________________________________________________
|
||
%
|
||
% [5]Contents | [6]Prev | [7]Next | [8]Index Java Language Specification
|
||
% Second Edition
|
||
%
|
||
% [9]Copyright <EFBFBD> 2000 Sun Microsystems, Inc. All rights reserved
|
||
% Please send any comments or corrections to the [10]JLS team
|
||
|
||
% Syntax
|
||
% _________________________________________________________________
|
||
%
|
||
% This chapter presents a grammar for the Java programming language.
|
||
%
|
||
% The grammar presented piecemeal in the preceding chapters is much
|
||
% better for exposition, but it is not ideally suited as a basis for a
|
||
% parser. The grammar presented in this chapter is the basis for the
|
||
% reference implementation.
|
||
%
|
||
% The grammar below uses the following BNF-style conventions:
|
||
%
|
||
% * [x] denotes zero or one occurrences of x.
|
||
% * {x} denotes zero or more occurrences of x.
|
||
% * x | y means one of either x or y.
|
||
|
||
% Identifier:
|
||
% IDENTIFIER
|
||
%
|
||
% QualifiedIdentifier:
|
||
% Identifier { . Identifier }
|
||
|
||
:- pred qualified_identifier(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(qualified_identifier/2).
|
||
qualified_identifier -->
|
||
java_identifier, zero_or_more(dot_java_identifier).
|
||
|
||
:- pred dot_java_identifier(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(dot_java_identifier/2).
|
||
dot_java_identifier -->
|
||
punct("."),
|
||
java_identifier.
|
||
|
||
% Literal:
|
||
% IntegerLiteral
|
||
% FloatingPointLiteral
|
||
% CharacterLiteral
|
||
% StringLiteral
|
||
% BooleanLiteral
|
||
% NullLiteral
|
||
|
||
:- pred literal(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(literal/2).
|
||
literal -->
|
||
( if
|
||
floating_point_literal
|
||
then
|
||
[]
|
||
else if
|
||
integer_literal
|
||
then
|
||
[]
|
||
else if
|
||
character_literal
|
||
then
|
||
[]
|
||
else if
|
||
string_literal
|
||
then
|
||
[]
|
||
else if
|
||
boolean_literal
|
||
then
|
||
[]
|
||
else
|
||
null_literal
|
||
),
|
||
whitespace.
|
||
|
||
% Expression:
|
||
% Expression1 [AssignmentOperator Expression1]]
|
||
% XXX I think that should be
|
||
% Expression1 {AssignmentOperator Expression1}
|
||
|
||
:- pred expression(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(expression/2).
|
||
expression -->
|
||
expression1, zero_or_more(assignment_operator_expression1).
|
||
|
||
:- pred assignment_operator_expression1(ps::in, ps::out) is semidet.
|
||
|
||
assignment_operator_expression1 -->
|
||
assignment_operator, expression1.
|
||
|
||
% AssignmentOperator:
|
||
% =
|
||
% +=
|
||
% -=
|
||
% *=
|
||
% /=
|
||
% &=
|
||
% |=
|
||
% ^=
|
||
% %=
|
||
% <<=
|
||
% >>=
|
||
% >>>=
|
||
|
||
:- pred assignment_operator(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(assignment_operator/2).
|
||
assignment_operator -->
|
||
( if
|
||
punct("=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("+=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("-=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("*=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("/=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("&=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("|=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("^=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("%=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("<<=")
|
||
then
|
||
[]
|
||
else if
|
||
punct(">>=")
|
||
then
|
||
[]
|
||
else
|
||
punct(">>>=")
|
||
).
|
||
|
||
% Type:
|
||
% Identifier { . Identifier } BracketsOpt
|
||
% BasicType
|
||
|
||
:- pred java_type(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(java_type/2).
|
||
java_type -->
|
||
( if
|
||
qualified_identifier, brackets_opt
|
||
then
|
||
[]
|
||
else
|
||
basic_type
|
||
).
|
||
|
||
% StatementExpression:
|
||
% Expression
|
||
|
||
:- pred statement_expression(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(statement_expression/2).
|
||
statement_expression -->
|
||
expression.
|
||
|
||
% ConstantExpression:
|
||
% Expression
|
||
|
||
:- pred constant_expression(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(constant_expression/2).
|
||
constant_expression -->
|
||
expression.
|
||
|
||
% Expression1:
|
||
% Expression2 [Expression1Rest]
|
||
|
||
:- pred expression1(ps::in, ps::out) is semidet.
|
||
|
||
expression1 -->
|
||
expression2, optional(expression1_rest).
|
||
|
||
% Expression1Rest:
|
||
% [ ? Expression : Expression1]
|
||
|
||
:- pred expression1_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(expression1_rest/2).
|
||
expression1_rest -->
|
||
punct("?"), expression, punct(":"), expression1.
|
||
|
||
% Expression2 :
|
||
% Expression3 [Expression2Rest]
|
||
|
||
:- pred expression2(ps::in, ps::out) is semidet.
|
||
|
||
expression2 -->
|
||
expression3, optional(expression2_rest).
|
||
|
||
% Expression2Rest:
|
||
% {Infixop Expression3}
|
||
% Expression3 instanceof Type
|
||
% XXX The Expression3 here must be wrong...
|
||
% XXX And {Infixop Expression3} should be allowed after Type.
|
||
|
||
:- pred expression2_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(expression2_rest/2).
|
||
expression2_rest -->
|
||
( if
|
||
keyword("instanceof"), java_type, optional(expression2_rest)
|
||
then
|
||
[]
|
||
else
|
||
zero_or_more(infix_op_expression3)
|
||
).
|
||
|
||
:- pred infix_op_expression3(ps::in, ps::out) is semidet.
|
||
|
||
infix_op_expression3 -->
|
||
infix_op, expression3.
|
||
|
||
% Infixop:
|
||
% ||
|
||
% &&
|
||
% |
|
||
% ^
|
||
% &
|
||
% ==
|
||
% !=
|
||
% <
|
||
% >
|
||
% <=
|
||
% >=
|
||
% <<
|
||
% >>
|
||
% >>>
|
||
% +
|
||
% -
|
||
% *
|
||
% /
|
||
% %
|
||
|
||
:- pred infix_op(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(infix_op/2).
|
||
infix_op -->
|
||
( if
|
||
punct("||")
|
||
then
|
||
[]
|
||
else if
|
||
punct("&&")
|
||
then
|
||
[]
|
||
else if
|
||
punct("|")
|
||
then
|
||
[]
|
||
else if
|
||
punct("^")
|
||
then
|
||
[]
|
||
else if
|
||
punct("&")
|
||
then
|
||
[]
|
||
else if
|
||
punct("==")
|
||
then
|
||
[]
|
||
else if
|
||
punct("!=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("<=")
|
||
then
|
||
[]
|
||
else if
|
||
punct(">=")
|
||
then
|
||
[]
|
||
else if
|
||
punct("<<")
|
||
then
|
||
[]
|
||
else if
|
||
punct(">>>")
|
||
then
|
||
[]
|
||
else if
|
||
punct(">>")
|
||
then
|
||
[]
|
||
else if
|
||
punct("<")
|
||
then
|
||
[]
|
||
else if
|
||
punct(">")
|
||
then
|
||
[]
|
||
else if
|
||
punct("+")
|
||
then
|
||
[]
|
||
else if
|
||
punct("-")
|
||
then
|
||
[]
|
||
else if
|
||
punct("*")
|
||
then
|
||
[]
|
||
else if
|
||
punct("/")
|
||
then
|
||
[]
|
||
else
|
||
punct("%")
|
||
).
|
||
|
||
% Expression3:
|
||
% PrefixOp Expression3
|
||
% ( Expr | Type ) Expression3
|
||
% Primary {Selector} {PostfixOp}
|
||
|
||
:- pred expression3(ps::in, ps::out) is semidet.
|
||
|
||
expression3 -->
|
||
( if
|
||
prefix_op, expression3
|
||
then
|
||
[]
|
||
else if
|
||
brackets("(", expression_or_java_type, ")"), expression3
|
||
then
|
||
[]
|
||
else
|
||
primary, zero_or_more(selector), zero_or_more(postfix_op)
|
||
).
|
||
|
||
:- pred expression_or_java_type(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(expression_or_java_type/2).
|
||
expression_or_java_type -->
|
||
( if
|
||
java_type
|
||
then
|
||
[]
|
||
else
|
||
expression
|
||
).
|
||
|
||
% Primary:
|
||
% ( Expression )
|
||
% this [Arguments]
|
||
% super SuperSuffix
|
||
% Literal
|
||
% new Creator
|
||
% Identifier { . Identifier }[ IdentifierSuffix]
|
||
% BasicType BracketsOpt .class
|
||
% void.class
|
||
|
||
:- pred primary(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(primary/2).
|
||
primary -->
|
||
( if
|
||
brackets("(", expression, ")")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("this"), optional(arguments)
|
||
then
|
||
[]
|
||
else if
|
||
keyword("super"), super_suffix
|
||
then
|
||
[]
|
||
else if
|
||
keyword("new"), creator
|
||
then
|
||
[]
|
||
else if
|
||
keyword("void"), punct("."), keyword("class")
|
||
then
|
||
[]
|
||
else if
|
||
basic_type, brackets_opt, punct("."), keyword("class")
|
||
then
|
||
[]
|
||
else if
|
||
literal
|
||
then
|
||
[]
|
||
else
|
||
qualified_identifier, optional(identifier_suffix)
|
||
).
|
||
|
||
% XXX I don't understand how to read this rule:
|
||
%
|
||
% IdentifierSuffix:
|
||
% [ ( ] BracketsOpt . class | Expression ])
|
||
% Arguments
|
||
% . ( class | this | super Arguments | new InnerCreator )
|
||
|
||
:- pred identifier_suffix(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(identifier_suffix/2).
|
||
identifier_suffix -->
|
||
( if
|
||
brackets_opt, punct("."),
|
||
( if
|
||
keyword("class")
|
||
then
|
||
[]
|
||
else
|
||
expression
|
||
)
|
||
then
|
||
[]
|
||
else if
|
||
arguments
|
||
then
|
||
[]
|
||
else
|
||
punct("."),
|
||
( if
|
||
keyword("class")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("this")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("super"), arguments
|
||
then
|
||
[]
|
||
else
|
||
keyword("new"), inner_creator
|
||
)
|
||
).
|
||
|
||
% PrefixOp:
|
||
% ,
|
||
% --
|
||
% !
|
||
% ~
|
||
% +
|
||
% -
|
||
|
||
:- pred prefix_op(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(prefix_op/2).
|
||
prefix_op -->
|
||
( if
|
||
punct("++")
|
||
then
|
||
[]
|
||
else if
|
||
punct("--")
|
||
then
|
||
[]
|
||
else if
|
||
punct("!")
|
||
then
|
||
[]
|
||
else if
|
||
punct("~")
|
||
then
|
||
[]
|
||
else if
|
||
punct("+")
|
||
then
|
||
[]
|
||
else
|
||
punct("-")
|
||
).
|
||
|
||
% PostfixOp:
|
||
% ,
|
||
% --
|
||
|
||
:- pred postfix_op(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(postfix_op/2).
|
||
postfix_op -->
|
||
( if
|
||
punct("++")
|
||
then
|
||
[]
|
||
else
|
||
punct("--")
|
||
).
|
||
|
||
% Selector:
|
||
% . Identifier [Arguments]
|
||
% . this
|
||
% . super SuperSuffix
|
||
% . new InnerCreator
|
||
% [ Expression ]
|
||
|
||
:- pred selector(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(selector/2).
|
||
selector -->
|
||
( if
|
||
brackets("[", expression, "]")
|
||
then
|
||
[]
|
||
else
|
||
punct("."),
|
||
( if
|
||
keyword("this")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("super"), super_suffix
|
||
then
|
||
[]
|
||
else if
|
||
keyword("new"), inner_creator
|
||
then
|
||
[]
|
||
else
|
||
java_identifier, optional(arguments)
|
||
)
|
||
).
|
||
|
||
% SuperSuffix:
|
||
% Arguments
|
||
% . Identifier [Arguments]
|
||
|
||
:- pred super_suffix(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(super_suffix/2).
|
||
super_suffix -->
|
||
( if
|
||
arguments
|
||
then
|
||
[]
|
||
else
|
||
punct("."), java_identifier, optional(arguments)
|
||
).
|
||
|
||
% BasicType:
|
||
% byte
|
||
% short
|
||
% char
|
||
% int
|
||
% long
|
||
% float
|
||
% double
|
||
% boolean
|
||
|
||
:- pred basic_type(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(basic_type/2).
|
||
basic_type -->
|
||
( if
|
||
punct("byte")
|
||
then
|
||
[]
|
||
else if
|
||
punct("short")
|
||
then
|
||
[]
|
||
else if
|
||
punct("char")
|
||
then
|
||
[]
|
||
else if
|
||
punct("int")
|
||
then
|
||
[]
|
||
else if
|
||
punct("long")
|
||
then
|
||
[]
|
||
else if
|
||
punct("float")
|
||
then
|
||
[]
|
||
else if
|
||
punct("double")
|
||
then
|
||
[]
|
||
else
|
||
punct("boolean")
|
||
).
|
||
|
||
% Arguments:
|
||
% ( [Expression { , Expression }] )
|
||
|
||
:- pred arguments(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(arguments/2).
|
||
arguments -->
|
||
brackets("(", optional(comma_separated_list(expression)), ")").
|
||
|
||
% BracketsOpt:
|
||
% {[]}
|
||
|
||
:- pred brackets_opt(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(brackets_opt/2).
|
||
brackets_opt -->
|
||
zero_or_more(empty_brackets).
|
||
|
||
:- pred empty_brackets(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(empty_brackets/2).
|
||
empty_brackets -->
|
||
punct("["), punct("]").
|
||
|
||
% Creator:
|
||
% QualifiedIdentifier ( ArrayCreatorRest | ClassCreatorRest )
|
||
|
||
:- pred creator(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(creator/2).
|
||
creator -->
|
||
qualified_identifier, creator_rest.
|
||
|
||
:- pred creator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(creator_rest/2).
|
||
creator_rest -->
|
||
( if
|
||
array_creator_rest
|
||
then
|
||
[]
|
||
else
|
||
class_creator_rest
|
||
).
|
||
|
||
% InnerCreator:
|
||
% Identifier ClassCreatorRest
|
||
|
||
:- pred inner_creator(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(inner_creator/2).
|
||
inner_creator -->
|
||
java_identifier, class_creator_rest.
|
||
|
||
% XXX I don't understand how to read this rule:
|
||
%
|
||
% ArrayCreatorRest:
|
||
% [ ( ] BracketsOpt ArrayInitializer | Expression ] {[ Expression ]} BracketsOpt )
|
||
|
||
:- pred array_creator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(array_creator_rest/2).
|
||
array_creator_rest -->
|
||
one_or_more(brackets("[", optional(expression), "]")),
|
||
optional(array_initializer).
|
||
|
||
% ClassCreatorRest:
|
||
% Arguments [ClassBody]
|
||
|
||
:- pred class_creator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(class_creator_rest/2).
|
||
class_creator_rest -->
|
||
arguments, optional(class_body).
|
||
|
||
% ArrayInitializer:
|
||
% { [VariableInitializer {, VariableInitializer} [,]] }
|
||
|
||
:- pred array_initializer(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(array_initializer/2).
|
||
array_initializer -->
|
||
brackets("{", optional(array_initializer_body), "}").
|
||
|
||
:- pred array_initializer_body(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(array_initializer_body/2).
|
||
array_initializer_body -->
|
||
comma_separated_list(variable_initializer), optional(punct(",")).
|
||
|
||
% VariableInitializer:
|
||
% ArrayInitializer
|
||
% Expression
|
||
|
||
:- pred variable_initializer(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(variable_initializer/2).
|
||
variable_initializer -->
|
||
( if
|
||
array_initializer
|
||
then
|
||
[]
|
||
else
|
||
expression
|
||
).
|
||
|
||
% ParExpression:
|
||
% ( Expression )
|
||
|
||
:- pred par_expression(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(par_expression/2).
|
||
par_expression -->
|
||
brackets("(", expression, ")").
|
||
|
||
% Block:
|
||
% { BlockStatements }
|
||
|
||
:- pred block(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(block/2).
|
||
block -->
|
||
brackets("{", block_statements, "}").
|
||
|
||
% BlockStatements:
|
||
% { BlockStatement }
|
||
|
||
:- pred block_statements(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(block_statements/2).
|
||
block_statements -->
|
||
zero_or_more(block_statement).
|
||
|
||
% BlockStatement :
|
||
% LocalVariableDeclarationStatement
|
||
% ClassOrInterfaceDeclaration
|
||
% [Identifier :] Statement
|
||
|
||
:- pred block_statement(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(block_statement/2).
|
||
block_statement -->
|
||
( if
|
||
local_variable_declaration_statement
|
||
then
|
||
[]
|
||
else if
|
||
class_or_interface_declaration
|
||
then
|
||
[]
|
||
else
|
||
optional(label), statement
|
||
).
|
||
|
||
:- pred label(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(label/2).
|
||
label -->
|
||
java_identifier, punct(":").
|
||
|
||
% LocalVariableDeclarationStatement:
|
||
% [final] Type VariableDeclarators ;
|
||
% XXX I think this is wrong: [final] should be ModifiersOpt, surely?
|
||
|
||
:- pred local_variable_declaration_statement(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(local_variable_declaration_statement/2).
|
||
local_variable_declaration_statement -->
|
||
modifiers_opt,
|
||
java_type,
|
||
variable_declarators,
|
||
punct(";").
|
||
|
||
% Statement:
|
||
% Block
|
||
% if ParExpression Statement [else if Statement]
|
||
% for ( ForInitOpt ; [Expression] ; ForUpdateOpt ) Statement
|
||
% while ParExpression Statement
|
||
% do Statement while ParExpression ;
|
||
% try Block ( Catches | [Catches] finally Block )
|
||
% switch ParExpression { SwitchBlockStatementGroups }
|
||
% synchronized ParExpression Block
|
||
% return [Expression] ;
|
||
% throw Expression ;
|
||
% break [Identifier]
|
||
% continue [Identifier]
|
||
% ;
|
||
% ExpressionStatement
|
||
% Identifier : Statement
|
||
|
||
:- pred statement(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(statement/2).
|
||
statement -->
|
||
( if
|
||
block
|
||
then
|
||
[]
|
||
else if
|
||
keyword("if"), par_expression, statement,
|
||
optional(else_statement)
|
||
then
|
||
[]
|
||
else if
|
||
keyword("for"),
|
||
punct("("),
|
||
optional(for_init),
|
||
punct(";"),
|
||
optional(expression),
|
||
punct(";"),
|
||
optional(for_update),
|
||
punct(")"),
|
||
statement
|
||
then
|
||
[]
|
||
else if
|
||
keyword("while"), par_expression, statement
|
||
then
|
||
[]
|
||
else if
|
||
keyword("do"), statement,
|
||
keyword("while"), par_expression, punct(";")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("try"), block, catches_finally
|
||
then
|
||
[]
|
||
else if
|
||
keyword("switch"), par_expression,
|
||
brackets("{", switch_block_statement_groups, "}")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("synchronized"), par_expression, block
|
||
then
|
||
[]
|
||
else if
|
||
keyword("return"), optional(expression), punct(";")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("throw"), expression, punct(";")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("break"), optional(java_identifier), punct(";")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("continue"), optional(java_identifier), punct(";")
|
||
then
|
||
[]
|
||
else if
|
||
punct(";")
|
||
then
|
||
[]
|
||
else if
|
||
expression, punct(";")
|
||
then
|
||
[]
|
||
else
|
||
java_identifier, punct(":"), statement
|
||
).
|
||
|
||
:- pred else_statement(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(else_statement/2).
|
||
else_statement -->
|
||
keyword("else"), statement.
|
||
|
||
:- pred catches_finally(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(catches_finally/2).
|
||
catches_finally -->
|
||
( if
|
||
catches, optional(finally_block)
|
||
then
|
||
[]
|
||
else
|
||
finally_block
|
||
).
|
||
|
||
:- pred finally_block(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(finally_block/2).
|
||
finally_block -->
|
||
keyword("finally"), block.
|
||
|
||
% Catches:
|
||
% CatchClause {CatchClause}
|
||
|
||
:- pred catches(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(catches/2).
|
||
catches -->
|
||
one_or_more(catch_clause).
|
||
|
||
% CatchClause:
|
||
% catch ( FormalParameter ) Block
|
||
|
||
:- pred catch_clause(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(catch_clause/2).
|
||
catch_clause -->
|
||
keyword("catch"), brackets("(", formal_parameter, ")"), block.
|
||
|
||
% SwitchBlockStatementGroups:
|
||
% { SwitchBlockStatementGroup }
|
||
|
||
:- pred switch_block_statement_groups(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(switch_block_statement_groups/2).
|
||
switch_block_statement_groups -->
|
||
zero_or_more(switch_block_statement_group).
|
||
|
||
% SwitchBlockStatementGroup:
|
||
% SwitchLabel BlockStatements
|
||
|
||
:- pred switch_block_statement_group(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(switch_block_statement_group/2).
|
||
switch_block_statement_group -->
|
||
switch_label, block_statements.
|
||
|
||
% SwitchLabel:
|
||
% case ConstantExpression :
|
||
% default:
|
||
|
||
:- pred switch_label(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(switch_label/2).
|
||
switch_label -->
|
||
( if
|
||
keyword("case"), constant_expression, punct(":")
|
||
then
|
||
[]
|
||
else
|
||
keyword("default"), punct(":")
|
||
).
|
||
|
||
% MoreStatementExpressions:
|
||
% { , StatementExpression }
|
||
%
|
||
% ForInit:
|
||
% StatementExpression MoreStatementExpressions
|
||
% [final] Type VariableDeclarators
|
||
|
||
:- pred for_init(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(for_init/2).
|
||
for_init -->
|
||
( if
|
||
comma_separated_list(for_init_statement_expression)
|
||
then
|
||
[]
|
||
else
|
||
optional(keyword("final")), java_type, variable_declarators
|
||
).
|
||
|
||
:- pred for_init_statement_expression(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(for_init_statement_expression/2).
|
||
for_init_statement_expression -->
|
||
( if
|
||
java_type, java_identifier, equals_variable_initializer
|
||
then
|
||
[]
|
||
else
|
||
statement_expression
|
||
).
|
||
|
||
% ForUpdate:
|
||
% StatementExpression MoreStatementExpressions
|
||
|
||
:- pred for_update(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(for_update/2).
|
||
for_update -->
|
||
comma_separated_list(statement_expression).
|
||
|
||
% ModifiersOpt:
|
||
% { Modifier }
|
||
|
||
:- pred modifiers_opt(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(modifiers_opt/2).
|
||
modifiers_opt -->
|
||
zero_or_more(modifier).
|
||
|
||
% Modifier:
|
||
% public
|
||
% protected
|
||
% private
|
||
% static
|
||
% abstract
|
||
% final
|
||
% native
|
||
% synchronized
|
||
% transient
|
||
% volatile
|
||
% strictfp
|
||
|
||
:- pred modifier(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(modifier/2).
|
||
modifier -->
|
||
( if
|
||
keyword("public")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("protected")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("private")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("static")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("abstract")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("final")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("native")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("synchronized")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("transient")
|
||
then
|
||
[]
|
||
else if
|
||
keyword("volatile")
|
||
then
|
||
[]
|
||
else
|
||
keyword("strictfp")
|
||
).
|
||
|
||
% VariableDeclarators:
|
||
% VariableDeclarator { , VariableDeclarator }
|
||
|
||
:- pred variable_declarators(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(variable_declarators/2).
|
||
variable_declarators -->
|
||
comma_separated_list(variable_declarator).
|
||
|
||
% ConstantDeclaratorsRest:
|
||
% ConstantDeclaratorRest { , ConstantDeclarator }
|
||
|
||
:- pred constant_declarators_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(constant_declarators_rest/2).
|
||
constant_declarators_rest -->
|
||
comma_separated_list(constant_declarator_rest).
|
||
|
||
% VariableDeclarator:
|
||
% Identifier VariableDeclaratorRest
|
||
|
||
:- pred variable_declarator(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(variable_declarator/2).
|
||
variable_declarator -->
|
||
java_identifier, variable_declarator_rest.
|
||
|
||
% ConstantDeclarator:
|
||
% Identifier ConstantDeclaratorRest
|
||
|
||
:- pred constant_declarator(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(constant_declarator/2).
|
||
constant_declarator -->
|
||
java_identifier, constant_declarator_rest.
|
||
|
||
% VariableDeclaratorRest:
|
||
% BracketsOpt [ = VariableInitializer]
|
||
|
||
:- pred variable_declarator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(variable_declarator_rest/2).
|
||
variable_declarator_rest -->
|
||
brackets_opt, optional(equals_variable_initializer).
|
||
|
||
:- pred equals_variable_initializer(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(equals_variable_initializer/2).
|
||
equals_variable_initializer -->
|
||
punct("="),
|
||
variable_initializer.
|
||
|
||
% ConstantDeclaratorRest:
|
||
% BracketsOpt = VariableInitializer
|
||
|
||
:- pred constant_declarator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(constant_declarator_rest/2).
|
||
constant_declarator_rest -->
|
||
brackets_opt, punct("="), variable_initializer.
|
||
|
||
% VariableDeclaratorId:
|
||
% Identifier BracketsOpt
|
||
|
||
:- pred variable_declarator_id(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(variable_declarator_id/2).
|
||
variable_declarator_id -->
|
||
java_identifier, brackets_opt.
|
||
|
||
% CompilationUnit:
|
||
% [package QualifiedIdentifier ; ] {ImportDeclaration} {TypeDeclaration}
|
||
|
||
:- pred compilation_unit(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(compilation_unit/2).
|
||
compilation_unit -->
|
||
whitespace,
|
||
optional(package_declaration),
|
||
zero_or_more(import_declaration),
|
||
zero_or_more(type_declaration),
|
||
eof.
|
||
|
||
:- pred package_declaration(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(package_declaration/2).
|
||
package_declaration -->
|
||
keyword("package"), qualified_identifier, punct(";").
|
||
|
||
% ImportDeclaration:
|
||
% import Identifier { . Identifier } [ . * ] ;
|
||
|
||
:- pred import_declaration(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(import_declaration/2).
|
||
import_declaration -->
|
||
keyword("import"),
|
||
qualified_identifier,
|
||
optional(dot_star),
|
||
punct(";").
|
||
|
||
:- pred dot_star(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(dot_star/2).
|
||
dot_star -->
|
||
punct("."), punct("*").
|
||
|
||
% TypeDeclaration:
|
||
% ClassOrInterfaceDeclaration
|
||
|
||
:- pred type_declaration(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(type_declaration/2).
|
||
type_declaration -->
|
||
class_or_interface_declaration.
|
||
|
||
% ClassOrInterfaceDeclaration:
|
||
% ModifiersOpt (ClassDeclaration | InterfaceDeclaration)
|
||
|
||
:- pred class_or_interface_declaration(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(class_or_interface_declaration/2).
|
||
class_or_interface_declaration -->
|
||
modifiers_opt,
|
||
( if
|
||
class_declaration
|
||
then
|
||
[]
|
||
else
|
||
interface_declaration
|
||
).
|
||
|
||
% ClassDeclaration:
|
||
% class Identifier [extends Type] [implements TypeList] ClassBody
|
||
|
||
:- pred class_declaration(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(class_declaration/2).
|
||
class_declaration -->
|
||
keyword("class"),
|
||
java_identifier,
|
||
optional(keyword("extends", java_type)),
|
||
optional(keyword("implements", java_type_list)),
|
||
class_body.
|
||
|
||
% InterfaceDeclaration:
|
||
% interface Identifier [extends TypeList] InterfaceBody
|
||
|
||
:- pred interface_declaration(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(interface_declaration/2).
|
||
interface_declaration -->
|
||
keyword("interface"),
|
||
java_identifier,
|
||
optional(keyword("extends", java_type_list)),
|
||
interface_body.
|
||
|
||
% TypeList:
|
||
% Type { , Type}
|
||
|
||
:- pred java_type_list(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(java_type_list/2).
|
||
java_type_list -->
|
||
comma_separated_list(java_type).
|
||
|
||
% ClassBody:
|
||
% { {ClassBodyDeclaration} }
|
||
|
||
:- pred class_body(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(class_body/2).
|
||
class_body -->
|
||
brackets("{", zero_or_more(class_body_declaration), "}").
|
||
|
||
% InterfaceBody:
|
||
% { {InterfaceBodyDeclaration} }
|
||
|
||
:- pred interface_body(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(interface_body/2).
|
||
interface_body -->
|
||
brackets("{", zero_or_more(interface_body_declaration), "}").
|
||
|
||
% ClassBodyDeclaration:
|
||
% ;
|
||
% [static] Block
|
||
% ModifiersOpt MemberDecl
|
||
|
||
:- pred class_body_declaration(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(class_body_declaration/2).
|
||
class_body_declaration -->
|
||
( if
|
||
punct(";")
|
||
then
|
||
[]
|
||
else if
|
||
optional(keyword("static")), block
|
||
then
|
||
[]
|
||
else
|
||
modifiers_opt, member_decl
|
||
).
|
||
|
||
% MemberDecl:
|
||
% MethodOrFieldDecl
|
||
% void Identifier MethodDeclaratorRest
|
||
% Identifier ConstructorDeclaratorRest
|
||
% ClassOrInterfaceDeclaration
|
||
|
||
:- pred member_decl(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(member_decl/2).
|
||
member_decl -->
|
||
( if
|
||
class_or_interface_declaration
|
||
then
|
||
[]
|
||
else if
|
||
method_or_field_decl
|
||
then
|
||
[]
|
||
else if
|
||
keyword("void"), java_identifier, method_declarator_rest
|
||
then
|
||
[]
|
||
else
|
||
java_identifier, constructor_declarator_rest
|
||
).
|
||
|
||
% MethodOrFieldDecl:
|
||
% Type Identifier MethodOrFieldRest
|
||
|
||
:- pred method_or_field_decl(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(method_or_field_decl/2).
|
||
method_or_field_decl -->
|
||
java_type, java_identifier, method_or_field_rest.
|
||
|
||
% MethodOrFieldRest:
|
||
% VariableDeclaratorRest
|
||
% MethodDeclaratorRest
|
||
% XXX First should be
|
||
% VariableDeclaratorRest [',' VariableDeclarators]
|
||
|
||
:- pred method_or_field_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(method_or_field_rest/2).
|
||
method_or_field_rest -->
|
||
( if
|
||
method_declarator_rest
|
||
then
|
||
[]
|
||
else
|
||
variable_declarator_rest,
|
||
( if punct(",") then
|
||
variable_declarators
|
||
else
|
||
[]
|
||
)
|
||
).
|
||
|
||
% InterfaceBodyDeclaration:
|
||
% ;
|
||
% ModifiersOpt InterfaceMemberDecl
|
||
|
||
:- pred interface_body_declaration(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(interface_body_declaration/2).
|
||
interface_body_declaration -->
|
||
( if
|
||
punct(";")
|
||
then
|
||
[]
|
||
else
|
||
modifiers_opt, interface_member_decl
|
||
).
|
||
|
||
% InterfaceMemberDecl:
|
||
% InterfaceMethodOrFieldDecl
|
||
% void Identifier VoidInterfaceMethodDeclaratorRest
|
||
% ClassOrInterfaceDeclaration
|
||
|
||
:- pred interface_member_decl(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(interface_member_decl/2).
|
||
interface_member_decl -->
|
||
( if
|
||
interface_method_or_field_decl
|
||
then
|
||
[]
|
||
else if
|
||
keyword("void"), java_identifier, void_interface_method_declarator_rest
|
||
then
|
||
[]
|
||
else
|
||
class_or_interface_declaration
|
||
).
|
||
|
||
% InterfaceMethodOrFieldDecl:
|
||
% Type Identifier InterfaceMethodOrFieldRest
|
||
|
||
:- pred interface_method_or_field_decl(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(interface_method_or_field_decl/2).
|
||
interface_method_or_field_decl -->
|
||
java_type, java_identifier, interface_method_or_field_rest.
|
||
|
||
% InterfaceMethodOrFieldRest:
|
||
% ConstantDeclaratorsRest ;
|
||
% InterfaceMethodDeclaratorRest
|
||
|
||
:- pred interface_method_or_field_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(interface_method_or_field_rest/2).
|
||
interface_method_or_field_rest -->
|
||
( if
|
||
constant_declarator_rest
|
||
then
|
||
[]
|
||
else
|
||
interface_method_declarator_rest
|
||
).
|
||
|
||
% MethodDeclaratorRest:
|
||
% FormalParameters BracketsOpt [throws QualifiedIdentifierList] ( MethodBody | ; )
|
||
|
||
:- pred method_declarator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(method_declarator_rest/2).
|
||
method_declarator_rest -->
|
||
formal_parameters,
|
||
brackets_opt,
|
||
optional(throws_qualified_identifier_list),
|
||
method_body_or_semicolon.
|
||
|
||
:- pred method_body_or_semicolon(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(method_body_or_semicolon/2).
|
||
method_body_or_semicolon -->
|
||
( if
|
||
method_body
|
||
then
|
||
[]
|
||
else
|
||
punct(";")
|
||
).
|
||
|
||
% VoidMethodDeclaratorRest:
|
||
% FormalParameters [throws QualifiedIdentifierList] ( MethodBody | ; )
|
||
|
||
:- pred void_method_declarator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(void_method_declarator_rest/2).
|
||
void_method_declarator_rest -->
|
||
formal_parameters,
|
||
optional(throws_qualified_identifier_list),
|
||
method_body_or_semicolon.
|
||
|
||
% InterfaceMethodDeclaratorRest:
|
||
% FormalParameters BracketsOpt [throws QualifiedIdentifierList] ;
|
||
|
||
:- pred interface_method_declarator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(interface_method_declarator_rest/2).
|
||
interface_method_declarator_rest -->
|
||
formal_parameters,
|
||
brackets_opt,
|
||
optional(throws_qualified_identifier_list),
|
||
punct(";").
|
||
|
||
% VoidInterfaceMethodDeclaratorRest:
|
||
% FormalParameters [throws QualifiedIdentifierList] ;
|
||
|
||
:- pred void_interface_method_declarator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(void_interface_method_declarator_rest/2).
|
||
void_interface_method_declarator_rest -->
|
||
formal_parameters, optional(throws_qualified_identifier_list), punct(";").
|
||
|
||
% ConstructorDeclaratorRest:
|
||
% FormalParameters [throws QualifiedIdentifierList] MethodBody
|
||
|
||
:- pred constructor_declarator_rest(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(constructor_declarator_rest/2).
|
||
constructor_declarator_rest -->
|
||
formal_parameters, optional(throws_qualified_identifier_list), method_body.
|
||
|
||
:- pred throws_qualified_identifier_list(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(throws_qualified_identifier_list/2).
|
||
throws_qualified_identifier_list -->
|
||
keyword("throws"), qualified_identifier_list.
|
||
|
||
% QualifiedIdentifierList:
|
||
% QualifiedIdentifier { , QualifiedIdentifier}
|
||
|
||
:- pred qualified_identifier_list(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(qualified_identifier_list/2).
|
||
qualified_identifier_list -->
|
||
comma_separated_list(qualified_identifier).
|
||
|
||
% FormalParameters:
|
||
% ( [FormalParameter { , FormalParameter}] )
|
||
|
||
:- pred formal_parameters(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(formal_parameters/2).
|
||
formal_parameters -->
|
||
brackets("(", optional(comma_separated_list(formal_parameter)), ")").
|
||
|
||
% FormalParameter:
|
||
% [final] Type VariableDeclaratorId
|
||
|
||
:- pred formal_parameter(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(formal_parameter/2).
|
||
formal_parameter -->
|
||
optional(keyword("final")), java_type, variable_declarator_id.
|
||
|
||
% MethodBody:
|
||
% Block
|
||
|
||
:- pred method_body(ps::in, ps::out) is semidet.
|
||
|
||
% :- pragma memo(method_body/2).
|
||
method_body -->
|
||
block.
|
||
|
||
%-----------------------------------------------------------------------------%
|
||
%-----------------------------------------------------------------------------%
|