Files
mercury/tests/tabling/mercury_java_parser_dead_proc_elim_bug2.m
Zoltan Somogyi 58ea6ffff2 Delete old obsolete predicates and functions.
library/*.m:
    Specifically, delete any predicates and functions whose `pragma obsolete'
    dates from 2018 or before. Keep the ones that were obsoleted
    only this year or last year.

NEWS:
    Announce the changes.

tests/debugger/io_tab_goto.m:
tests/debugger/tabled_read.m:
tests/declarative_debugger/io_stream_test.m:
tests/declarative_debugger/tabled_read_decl.m:
tests/declarative_debugger/tabled_read_decl_goto.m:
tests/general/array_test.m:
tests/hard_coded/mutable_init_impure.m:
tests/hard_coded/remove_file.m:
tests/tabling/mercury_java_parser_dead_proc_elim_bug.m:
tests/tabling/mercury_java_parser_dead_proc_elim_bug2.m:
tests/valid/mercury_java_parser_follow_code_bug.m:
    Replace references to predicates and functions that this diff deletes
    with their suggested replacements.

    In several test cases, bring the programming style up to date.

tests/hard_coded/shift_test.{m,exp}:
    Most of this test case tested the now-deleted legacy shift operations.
    Replace these with tests of their non-legacy versions, including
    testing for the expected exceptions.

tests/hard_coded/shift_test.{m,exp}:
    Don't pass --no-warn-obsolete when compiling shift_test.m anymore.
2020-08-18 11:57:47 +10:00

2084 lines
42 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
%
% This is a regression test. In versions of the compiler before 9 Aug 2007,
% it used to cause a compiler abort.
%
% The problem involved an unused procedure (in this case, the procedure
% constant_declarators_rest) that was kept around so that the code generator
% would create the table associated with it. Since the procedure was unused,
% its body was thought to be unused too. If it contained a reference to a
% procedure that wasn't referred to from anywhere else, that procedure
% would be removed, leaving a dangling reference.
%
%---------------------------------------------------------------------------%
% mercury_java_parser_memoed.m
% 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_dead_proc_elim_bug2.
:- 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 pair.
:- import_module std_util.
:- import_module string.
:- pragma require_feature_set([memo]).
% The parser "state". This is just the offset into the input string,
% which (depending on the version) may be passed around or stored in
% a C global variable.
%
% We do the latter 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.
parse_file(Filename, !IO) :-
global_table_reset(!IO),
io.write_string(Filename, !IO),
io.see(Filename, _, !IO),
io.read_file_as_string(Result, !IO),
( if Result = ok(Str) then
promise_pure ( 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(ps::in, ps::out) is semidet.
eof(Offset, Offset) :-
promise_pure (
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, ps::in, ps::out) is semidet.
char(Char, Offset, Offset + 1) :-
promise_pure (
semipure input_string_and_length(Str, Length),
Offset < Length,
Char = Str ^ unsafe_elem(Offset)
).
%---------------------------------------------------------------------------%
:- pred input_substring(int::in, int::in, string::out,
ps::in, ps::out) is semidet.
input_substring(Start, End, Substring, Offset, Offset) :-
promise_pure (
semipure input_string_and_length(Str, Length),
End =< Length,
Substring = unsafe_between(Str, Start, End)
).
%---------------------------------------------------------------------------%
:- pred match_string(string::in, int::in, int::out) is semidet.
match_string(MatchStr, Offset, Offset + N) :-
promise_pure (
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 seq(
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(seq/4).
seq(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(seq(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.
punct(Punct) -->
match_string(Punct),
whitespace.
:- pred keyword(string::in, ps::in, ps::out) is semidet.
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.
%---------------------------------------------------------------------------%
:- pred java_identifier( /*string::out, */ ps::in, ps::out)
is semidet.
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.decimal_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 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.
qualified_identifier -->
java_identifier,
zero_or_more(dot_java_identifier).
:- pred dot_java_identifier(ps::in, ps::out) is semidet.
dot_java_identifier -->
punct("."),
java_identifier.
% Literal:
% IntegerLiteral
% FloatingPointLiteral
% CharacterLiteral
% StringLiteral
% BooleanLiteral
% NullLiteral
:- pred literal(ps::in, ps::out) is semidet.
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.
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.
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.
java_type -->
( if
qualified_identifier,
brackets_opt
then
[]
else
basic_type
).
% StatementExpression:
% Expression
:- pred statement_expression(ps::in, ps::out) is semidet.
statement_expression -->
expression.
% ConstantExpression:
% Expression
:- pred constant_expression(ps::in, ps::out) is semidet.
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.
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.
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.
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.
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.
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.
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.
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.
postfix_op -->
( if
punct("++")
then
[]
else
punct("--")
).
% Selector:
% . Identifier [Arguments]
% . this
% . super SuperSuffix
% . new InnerCreator
% [ Expression ]
:- pred selector(ps::in, ps::out) is semidet.
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.
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.
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.
arguments -->
brackets(
"(",
optional(comma_separated_list(expression)),
")").
% BracketsOpt:
% {[]}
:- pred brackets_opt(ps::in, ps::out) is semidet.
brackets_opt -->
zero_or_more(empty_brackets).
:- pred empty_brackets(ps::in, ps::out) is semidet.
empty_brackets -->
punct("["),
punct("]").
% Creator:
% QualifiedIdentifier ( ArrayCreatorRest | ClassCreatorRest )
:- pred creator(ps::in, ps::out) is semidet.
creator -->
qualified_identifier,
creator_rest.
:- pred creator_rest(ps::in, ps::out) is semidet.
creator_rest -->
( if
array_creator_rest
then
[]
else
class_creator_rest
).
% InnerCreator:
% Identifier ClassCreatorRest
:- pred inner_creator(ps::in, ps::out) is semidet.
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.
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.
class_creator_rest -->
arguments,
optional(class_body).
% ArrayInitializer:
% { [VariableInitializer {, VariableInitializer} [, ]] }
:- pred array_initializer(ps::in, ps::out) is semidet.
array_initializer -->
brackets(
"{",
optional(array_initializer_body),
"}").
:- pred array_initializer_body(ps::in, ps::out) is semidet.
array_initializer_body -->
comma_separated_list(variable_initializer),
optional(punct(", ")).
% VariableInitializer:
% ArrayInitializer
% Expression
:- pred variable_initializer(ps::in, ps::out) is semidet.
variable_initializer -->
( if
array_initializer
then
[]
else
expression
).
% ParExpression:
% ( Expression )
:- pred par_expression(ps::in, ps::out) is semidet.
par_expression -->
brackets(
"(",
expression,
")").
% Block:
% { BlockStatements }
:- pred block(ps::in, ps::out) is semidet.
block -->
brackets(
"{",
block_statements,
"}").
% BlockStatements:
% { BlockStatement }
:- pred block_statements(ps::in, ps::out) is semidet.
block_statements -->
zero_or_more(block_statement).
% BlockStatement :
% LocalVariableDeclarationStatement
% ClassOrInterfaceDeclaration
% [Identifier :] Statement
:- pred block_statement(ps::in, ps::out) is semidet.
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.
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.
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.
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.
else_statement -->
keyword("else"),
statement.
:- pred catches_finally(ps::in, ps::out) is semidet.
catches_finally -->
( if
catches,
optional(finally_block)
then
[]
else
finally_block
).
:- pred finally_block(ps::in, ps::out) is semidet.
finally_block -->
keyword("finally"),
block.
% Catches:
% CatchClause {CatchClause}
:- pred catches(ps::in, ps::out) is semidet.
catches -->
one_or_more(catch_clause).
% CatchClause:
% catch ( FormalParameter ) Block
:- pred catch_clause(ps::in, ps::out) is semidet.
catch_clause -->
keyword("catch"),
brackets(
"(",
formal_parameter,
")"),
block.
% SwitchBlockStatementGroups:
% { SwitchBlockStatementGroup }
:- pred switch_block_statement_groups(ps::in, ps::out) is semidet.
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.
switch_block_statement_group -->
switch_label,
block_statements.
% SwitchLabel:
% case ConstantExpression :
% default:
:- pred switch_label(ps::in, ps::out) is semidet.
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.
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.
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.
for_update -->
comma_separated_list(statement_expression).
% ModifiersOpt:
% { Modifier }
:- pred modifiers_opt(ps::in, ps::out) is semidet.
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.
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.
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, [allow_reset,
specified([addr, output])]).
constant_declarators_rest -->
comma_separated_list(constant_declarator_rest).
% VariableDeclarator:
% Identifier VariableDeclaratorRest
:- pred variable_declarator(ps::in, ps::out) is semidet.
variable_declarator -->
java_identifier,
variable_declarator_rest.
% ConstantDeclarator:
% Identifier ConstantDeclaratorRest
:- pred constant_declarator(ps::in, ps::out) is semidet.
constant_declarator -->
java_identifier,
constant_declarator_rest.
% VariableDeclaratorRest:
% BracketsOpt [ = VariableInitializer]
:- pred variable_declarator_rest(ps::in, ps::out) is semidet.
variable_declarator_rest -->
brackets_opt,
optional(equals_variable_initializer).
:- pred equals_variable_initializer(ps::in, ps::out) is semidet.
equals_variable_initializer -->
punct("="),
variable_initializer.
% ConstantDeclaratorRest:
% BracketsOpt = VariableInitializer
:- pred constant_declarator_rest(ps::in, ps::out) is semidet.
constant_declarator_rest -->
brackets_opt,
punct("="),
variable_initializer.
% VariableDeclaratorId:
% Identifier BracketsOpt
:- pred variable_declarator_id(ps::in, ps::out) is semidet.
variable_declarator_id -->
java_identifier,
brackets_opt.
% CompilationUnit:
% [package QualifiedIdentifier ; ] {ImportDeclaration} {TypeDeclaration}
:- pred compilation_unit(ps::in, ps::out) is semidet.
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.
package_declaration -->
keyword("package"),
qualified_identifier,
punct(";").
% ImportDeclaration:
% import Identifier { . Identifier } [ . * ] ;
:- pred import_declaration(ps::in, ps::out) is semidet.
import_declaration -->
keyword("import"),
qualified_identifier,
optional(dot_star),
punct(";").
:- pred dot_star(ps::in, ps::out) is semidet.
dot_star -->
punct("."),
punct("*").
% TypeDeclaration:
% ClassOrInterfaceDeclaration
:- pred type_declaration(ps::in, ps::out) is semidet.
type_declaration -->
class_or_interface_declaration.
% ClassOrInterfaceDeclaration:
% ModifiersOpt (ClassDeclaration | InterfaceDeclaration)
:- pred class_or_interface_declaration(ps::in, ps::out)
is semidet.
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.
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.
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.
java_type_list -->
comma_separated_list(java_type).
% ClassBody:
% { {ClassBodyDeclaration} }
:- pred class_body(ps::in, ps::out) is semidet.
class_body -->
brackets(
"{",
zero_or_more(class_body_declaration),
"}").
% InterfaceBody:
% { {InterfaceBodyDeclaration} }
:- pred interface_body(ps::in, ps::out) is semidet.
interface_body -->
brackets(
"{",
zero_or_more(interface_body_declaration),
"}").
% ClassBodyDeclaration:
% ;
% [static] Block
% ModifiersOpt MemberDecl
:- pred class_body_declaration(ps::in, ps::out) is semidet.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
constructor_declarator_rest -->
formal_parameters,
optional(throws_qualified_identifier_list),
method_body.
:- pred throws_qualified_identifier_list(ps::in, ps::out)
is semidet.
throws_qualified_identifier_list -->
keyword("throws"),
qualified_identifier_list.
% QualifiedIdentifierList:
% QualifiedIdentifier { , QualifiedIdentifier}
:- pred qualified_identifier_list(ps::in, ps::out) is semidet.
qualified_identifier_list -->
comma_separated_list(qualified_identifier).
% FormalParameters:
% ( [FormalParameter { , FormalParameter}] )
:- pred formal_parameters(ps::in, ps::out) is semidet.
formal_parameters -->
brackets(
"(",
optional(
comma_separated_list(formal_parameter)),
")").
% FormalParameter:
% [final] Type VariableDeclaratorId
:- pred formal_parameter(ps::in, ps::out) is semidet.
formal_parameter -->
optional(keyword("final")),
java_type,
variable_declarator_id.
% MethodBody:
% Block
:- pred method_body(ps::in, ps::out) is semidet.
method_body -->
block.
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- pred global_table_reset(io::di, io::uo) is det.
global_table_reset(!IO) :-
table_reset_for_constant_declarators_rest_2(!IO),
true.