using System.Collections.Generic;
using System.Numerics;
using Microsoft.Boogie;
using System.IO;
using System.Text;
using System;
using System.Diagnostics.Contracts;
namespace Microsoft.Dafny {
public class Parser {
public const int _EOF = 0;
public const int _ident = 1;
public const int _digits = 2;
public const int _hexdigits = 3;
public const int _decimaldigits = 4;
public const int _arrayToken = 5;
public const int _string = 6;
public const int _colon = 7;
public const int _semi = 8;
public const int _lbrace = 9;
public const int _rbrace = 10;
public const int _openparen = 11;
public const int _star = 12;
public const int _notIn = 13;
public const int maxT = 126;
const bool T = true;
const bool x = false;
const int minErrDist = 2;
public Scanner/*!*/ scanner;
public Errors/*!*/ errors;
public Token/*!*/ t; // last recognized token
public Token/*!*/ la; // lookahead token
int errDist = minErrDist;
readonly Expression/*!*/ dummyExpr;
readonly AssignmentRhs/*!*/ dummyRhs;
readonly FrameExpression/*!*/ dummyFrameExpr;
readonly Statement/*!*/ dummyStmt;
readonly Attributes.Argument/*!*/ dummyAttrArg;
readonly ModuleDecl theModule;
readonly BuiltIns theBuiltIns;
readonly bool theVerifyThisFile;
int anonymousIds = 0;
struct MemberModifiers {
public bool IsGhost;
public bool IsStatic;
}
///
/// Parses top-level things (modules, classes, datatypes, class members) from "filename"
/// and appends them in appropriate form to "module".
/// Returns the number of parsing errors encountered.
/// Note: first initialize the Scanner.
///
public static int Parse (string/*!*/ filename, ModuleDecl module, BuiltIns builtIns, Errors/*!*/ errors, bool verifyThisFile=true) /* throws System.IO.IOException */ {
Contract.Requires(filename != null);
Contract.Requires(module != null);
string s;
if (filename == "stdin.dfy") {
s = Microsoft.Boogie.ParserHelper.Fill(System.Console.In, new List());
return Parse(s, filename, module, builtIns, errors, verifyThisFile);
} else {
using (System.IO.StreamReader reader = new System.IO.StreamReader(filename)) {
s = Microsoft.Boogie.ParserHelper.Fill(reader, new List());
return Parse(s, filename, module, builtIns, errors, verifyThisFile);
}
}
}
///
/// Parses top-level things (modules, classes, datatypes, class members)
/// and appends them in appropriate form to "module".
/// Returns the number of parsing errors encountered.
/// Note: first initialize the Scanner.
///
public static int Parse (string/*!*/ s, string/*!*/ filename, ModuleDecl module, BuiltIns builtIns, bool verifyThisFile=true) {
Contract.Requires(s != null);
Contract.Requires(filename != null);
Contract.Requires(module != null);
Errors errors = new Errors();
return Parse(s, filename, module, builtIns, errors, verifyThisFile);
}
///
/// Parses top-level things (modules, classes, datatypes, class members)
/// and appends them in appropriate form to "module".
/// Returns the number of parsing errors encountered.
/// Note: first initialize the Scanner with the given Errors sink.
///
public static int Parse (string/*!*/ s, string/*!*/ filename, ModuleDecl module, BuiltIns builtIns,
Errors/*!*/ errors, bool verifyThisFile=true) {
Contract.Requires(s != null);
Contract.Requires(filename != null);
Contract.Requires(module != null);
Contract.Requires(errors != null);
byte[]/*!*/ buffer = cce.NonNull( UTF8Encoding.Default.GetBytes(s));
MemoryStream ms = new MemoryStream(buffer,false);
Scanner scanner = new Scanner(ms, errors, filename);
Parser parser = new Parser(scanner, errors, module, builtIns, verifyThisFile);
parser.Parse();
return parser.errors.count;
}
public Parser(Scanner/*!*/ scanner, Errors/*!*/ errors, ModuleDecl module, BuiltIns builtIns, bool verifyThisFile=true)
: this(scanner, errors) // the real work
{
// initialize readonly fields
dummyExpr = new LiteralExpr(Token.NoToken);
dummyRhs = new ExprRhs(dummyExpr, null);
dummyFrameExpr = new FrameExpression(dummyExpr.tok, dummyExpr, null);
dummyStmt = new ReturnStmt(Token.NoToken, Token.NoToken, null);
dummyAttrArg = new Attributes.Argument(Token.NoToken, "dummyAttrArg");
theModule = module;
theBuiltIns = builtIns;
theVerifyThisFile = verifyThisFile;
}
bool IsAttribute() {
Token x = scanner.Peek();
return la.kind == _lbrace && x.kind == _colon;
}
bool IsAlternative() {
Token x = scanner.Peek();
return la.kind == _lbrace && x.val == "case";
}
bool IsLoopSpec() {
return la.val == "invariant" | la.val == "decreases" | la.val == "modifies";
}
bool IsLoopSpecOrAlternative() {
Token x = scanner.Peek();
return IsLoopSpec() || (la.kind == _lbrace && x.val == "case");
}
bool IsParenStar() {
scanner.ResetPeek();
Token x = scanner.Peek();
return la.kind == _openparen && x.kind == _star;
}
bool IsIdentParen() {
Token x = scanner.Peek();
return la.kind == _ident && x.kind == _openparen;
}
bool SemiFollowsCall(bool allowSemi, Expression e) {
return allowSemi && la.kind == _semi &&
(e is FunctionCallExpr ||
(e is IdentifierSequence && ((IdentifierSequence)e).OpenParen != null));
}
/*--------------------------------------------------------------------------*/
public Parser(Scanner/*!*/ scanner, Errors/*!*/ errors) {
this.scanner = scanner;
this.errors = errors;
Token/*!*/ tok = new Token();
tok.val = "";
this.la = tok;
this.t = new Token(); // just to satisfy its non-null constraint
}
void SynErr (int n) {
if (errDist >= minErrDist) errors.SynErr(la.filename, la.line, la.col, n);
errDist = 0;
}
public void SemErr (string/*!*/ msg) {
Contract.Requires(msg != null);
if (errDist >= minErrDist) errors.SemErr(t, msg);
errDist = 0;
}
public void SemErr(IToken/*!*/ tok, string/*!*/ msg) {
Contract.Requires(tok != null);
Contract.Requires(msg != null);
errors.SemErr(tok, msg);
}
void Get () {
for (;;) {
t = la;
la = scanner.Scan();
if (la.kind <= maxT) { ++errDist; break; }
la = t;
}
}
void Expect (int n) {
if (la.kind==n) Get(); else { SynErr(n); }
}
bool StartOf (int s) {
return set[s, la.kind];
}
void ExpectWeak (int n, int follow) {
if (la.kind == n) Get();
else {
SynErr(n);
while (!StartOf(follow)) Get();
}
}
bool WeakSeparator(int n, int syFol, int repFol) {
int kind = la.kind;
if (kind == n) {Get(); return true;}
else if (StartOf(repFol)) {return false;}
else {
SynErr(n);
while (!(set[syFol, kind] || set[repFol, kind] || set[0, kind])) {
Get();
kind = la.kind;
}
return StartOf(syFol);
}
}
void Dafny() {
ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt; ArbitraryTypeDecl at; IteratorDecl iter;
List membersDefaultClass = new List();
ModuleDecl submodule;
// to support multiple files, create a default module only if theModule is null
DefaultModuleDecl defaultModule = (DefaultModuleDecl)((LiteralModuleDecl)theModule).ModuleDef;
// theModule should be a DefaultModuleDecl (actually, the singular DefaultModuleDecl)
Contract.Assert(defaultModule != null);
while (la.kind == 14) {
Get();
Expect(6);
{
string parsedFile = t.filename;
string includedFile = t.val.Substring(1, t.val.Length - 2);
if (!Path.IsPathRooted(includedFile)) {
string basePath = Path.GetDirectoryName(parsedFile);
includedFile = Path.GetFullPath(Path.Combine(basePath, includedFile));
}
defaultModule.Includes.Add(new Include(t, includedFile));
}
}
while (StartOf(1)) {
switch (la.kind) {
case 15: case 16: case 18: {
SubModuleDecl(defaultModule, out submodule);
defaultModule.TopLevelDecls.Add(submodule);
break;
}
case 23: {
ClassDecl(defaultModule, out c);
defaultModule.TopLevelDecls.Add(c);
break;
}
case 26: case 27: {
DatatypeDecl(defaultModule, out dt);
defaultModule.TopLevelDecls.Add(dt);
break;
}
case 31: {
ArbitraryTypeDecl(defaultModule, out at);
defaultModule.TopLevelDecls.Add(at);
break;
}
case 34: {
IteratorDecl(defaultModule, out iter);
defaultModule.TopLevelDecls.Add(iter);
break;
}
case 24: case 25: case 29: case 40: case 41: case 42: case 43: case 44: case 62: case 63: case 64: {
ClassMemberDecl(membersDefaultClass, false);
break;
}
}
}
DefaultClassDecl defaultClass = null;
foreach (TopLevelDecl topleveldecl in defaultModule.TopLevelDecls) {
defaultClass = topleveldecl as DefaultClassDecl;
if (defaultClass != null) {
defaultClass.Members.AddRange(membersDefaultClass);
break;
}
}
if (defaultClass == null) { // create the default class here, because it wasn't found
defaultClass = new DefaultClassDecl(defaultModule, membersDefaultClass);
defaultModule.TopLevelDecls.Add(defaultClass);
}
Expect(0);
}
void SubModuleDecl(ModuleDefinition parent, out ModuleDecl submodule) {
ClassDecl/*!*/ c; DatatypeDecl/*!*/ dt; ArbitraryTypeDecl at; IteratorDecl iter;
Attributes attrs = null; IToken/*!*/ id;
List namedModuleDefaultClassMembers = new List();;
List idRefined = null, idPath = null, idAssignment = null;
ModuleDefinition module;
ModuleDecl sm;
submodule = null; // appease compiler
bool isAbstract = false;
bool opened = false;
if (la.kind == 15 || la.kind == 16) {
if (la.kind == 15) {
Get();
isAbstract = true;
}
Expect(16);
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (la.kind == 17) {
Get();
QualifiedName(out idRefined);
}
module = new ModuleDefinition(id, id.val, isAbstract, false, idRefined == null ? null : idRefined, parent, attrs, false);
Expect(9);
module.BodyStartTok = t;
while (StartOf(1)) {
switch (la.kind) {
case 15: case 16: case 18: {
SubModuleDecl(module, out sm);
module.TopLevelDecls.Add(sm);
break;
}
case 23: {
ClassDecl(module, out c);
module.TopLevelDecls.Add(c);
break;
}
case 26: case 27: {
DatatypeDecl(module, out dt);
module.TopLevelDecls.Add(dt);
break;
}
case 31: {
ArbitraryTypeDecl(module, out at);
module.TopLevelDecls.Add(at);
break;
}
case 34: {
IteratorDecl(module, out iter);
module.TopLevelDecls.Add(iter);
break;
}
case 24: case 25: case 29: case 40: case 41: case 42: case 43: case 44: case 62: case 63: case 64: {
ClassMemberDecl(namedModuleDefaultClassMembers, false);
break;
}
}
}
Expect(10);
module.BodyEndTok = t;
module.TopLevelDecls.Add(new DefaultClassDecl(module, namedModuleDefaultClassMembers));
submodule = new LiteralModuleDecl(module, parent);
} else if (la.kind == 18) {
Get();
if (la.kind == 19) {
Get();
opened = true;
}
NoUSIdent(out id);
if (la.kind == 20 || la.kind == 21) {
if (la.kind == 20) {
Get();
QualifiedName(out idPath);
submodule = new AliasModuleDecl(idPath, id, parent, opened);
} else {
Get();
QualifiedName(out idPath);
if (la.kind == 22) {
Get();
QualifiedName(out idAssignment);
}
submodule = new ModuleFacadeDecl(idPath, id, parent, idAssignment, opened);
}
}
if (la.kind == 8) {
while (!(la.kind == 0 || la.kind == 8)) {SynErr(127); Get();}
Get();
}
if (submodule == null) {
idPath = new List();
idPath.Add(id);
submodule = new AliasModuleDecl(idPath, id, parent, opened);
}
} else SynErr(128);
}
void ClassDecl(ModuleDefinition/*!*/ module, out ClassDecl/*!*/ c) {
Contract.Requires(module != null);
Contract.Ensures(Contract.ValueAtReturn(out c) != null);
IToken/*!*/ id;
Attributes attrs = null;
List typeArgs = new List();
List members = new List();
IToken bodyStart;
while (!(la.kind == 0 || la.kind == 23)) {SynErr(129); Get();}
Expect(23);
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (la.kind == 38) {
GenericParameters(typeArgs);
}
Expect(9);
bodyStart = t;
while (StartOf(2)) {
ClassMemberDecl(members, true);
}
Expect(10);
c = new ClassDecl(id, id.val, module, typeArgs, members, attrs);
c.BodyStartTok = bodyStart;
c.BodyEndTok = t;
}
void DatatypeDecl(ModuleDefinition/*!*/ module, out DatatypeDecl/*!*/ dt) {
Contract.Requires(module != null);
Contract.Ensures(Contract.ValueAtReturn(out dt)!=null);
IToken/*!*/ id;
Attributes attrs = null;
List typeArgs = new List();
List ctors = new List();
IToken bodyStart = Token.NoToken; // dummy assignment
bool co = false;
while (!(la.kind == 0 || la.kind == 26 || la.kind == 27)) {SynErr(130); Get();}
if (la.kind == 26) {
Get();
} else if (la.kind == 27) {
Get();
co = true;
} else SynErr(131);
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (la.kind == 38) {
GenericParameters(typeArgs);
}
Expect(20);
bodyStart = t;
DatatypeMemberDecl(ctors);
while (la.kind == 28) {
Get();
DatatypeMemberDecl(ctors);
}
if (la.kind == 8) {
while (!(la.kind == 0 || la.kind == 8)) {SynErr(132); Get();}
Get();
}
if (co) {
dt = new CoDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs);
} else {
dt = new IndDatatypeDecl(id, id.val, module, typeArgs, ctors, attrs);
}
dt.BodyStartTok = bodyStart;
dt.BodyEndTok = t;
}
void ArbitraryTypeDecl(ModuleDefinition/*!*/ module, out ArbitraryTypeDecl at) {
IToken/*!*/ id;
Attributes attrs = null;
var eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
Expect(31);
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (la.kind == 11) {
Get();
Expect(32);
Expect(33);
eqSupport = TypeParameter.EqualitySupportValue.Required;
}
at = new ArbitraryTypeDecl(id, id.val, module, eqSupport, attrs);
if (la.kind == 8) {
while (!(la.kind == 0 || la.kind == 8)) {SynErr(133); Get();}
Get();
}
}
void IteratorDecl(ModuleDefinition module, out IteratorDecl/*!*/ iter) {
Contract.Ensures(Contract.ValueAtReturn(out iter) != null);
IToken/*!*/ id;
Attributes attrs = null;
List/*!*/ typeArgs = new List();
IToken openParen;
List ins = new List();
List outs = new List();
List reads = new List();
List mod = new List();
List decreases = new List();
List req = new List();
List ens = new List();
List yieldReq = new List();
List yieldEns = new List();
List dec = new List();
Attributes readsAttrs = null;
Attributes modAttrs = null;
Attributes decrAttrs = null;
BlockStmt body = null;
IToken signatureEllipsis = null;
IToken bodyStart = Token.NoToken;
IToken bodyEnd = Token.NoToken;
while (!(la.kind == 0 || la.kind == 34)) {SynErr(134); Get();}
Expect(34);
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (la.kind == 11 || la.kind == 38) {
if (la.kind == 38) {
GenericParameters(typeArgs);
}
Formals(true, true, ins, out openParen);
if (la.kind == 35 || la.kind == 36) {
if (la.kind == 35) {
Get();
} else {
Get();
SemErr(t, "iterators don't have a 'returns' clause; did you mean 'yields'?");
}
Formals(false, true, outs, out openParen);
}
} else if (la.kind == 37) {
Get();
signatureEllipsis = t; openParen = Token.NoToken;
} else SynErr(135);
while (StartOf(3)) {
IteratorSpec(reads, mod, decreases, req, ens, yieldReq, yieldEns, ref readsAttrs, ref modAttrs, ref decrAttrs);
}
if (la.kind == 9) {
BlockStmt(out body, out bodyStart, out bodyEnd);
}
iter = new IteratorDecl(id, id.val, module, typeArgs, ins, outs,
new Specification(reads, readsAttrs),
new Specification(mod, modAttrs),
new Specification(decreases, decrAttrs),
req, ens, yieldReq, yieldEns,
body, attrs, signatureEllipsis);
iter.BodyStartTok = bodyStart;
iter.BodyEndTok = bodyEnd;
}
void ClassMemberDecl(List/*!*/ mm, bool allowConstructors) {
Contract.Requires(cce.NonNullElements(mm));
Method/*!*/ m;
Function/*!*/ f;
MemberModifiers mmod = new MemberModifiers();
while (la.kind == 24 || la.kind == 25) {
if (la.kind == 24) {
Get();
mmod.IsGhost = true;
} else {
Get();
mmod.IsStatic = true;
}
}
if (la.kind == 29) {
FieldDecl(mmod, mm);
} else if (la.kind == 62 || la.kind == 63 || la.kind == 64) {
FunctionDecl(mmod, out f);
mm.Add(f);
} else if (StartOf(4)) {
MethodDecl(mmod, allowConstructors, out m);
mm.Add(m);
} else SynErr(136);
}
void Attribute(ref Attributes attrs) {
Expect(9);
AttributeBody(ref attrs);
Expect(10);
}
void NoUSIdent(out IToken/*!*/ x) {
Contract.Ensures(Contract.ValueAtReturn(out x) != null);
Expect(1);
x = t;
if (x.val.StartsWith("_")) {
SemErr("cannot declare identifier beginning with underscore");
}
}
void QualifiedName(out List ids) {
IToken id; IToken idPrime; ids = new List();
Ident(out id);
ids.Add(id);
while (la.kind == 61) {
IdentOrDigitsSuffix(out id, out idPrime);
ids.Add(id);
if (idPrime != null) { ids.Add(idPrime); }
}
}
void Ident(out IToken/*!*/ x) {
Contract.Ensures(Contract.ValueAtReturn(out x) != null);
Expect(1);
x = t;
}
void IdentOrDigitsSuffix(out IToken x, out IToken y) {
Contract.Ensures(Contract.ValueAtReturn(out x) != null);
x = Token.NoToken;
y = null;
Expect(61);
if (la.kind == 1) {
Get();
x = t;
} else if (la.kind == 2) {
Get();
x = t;
} else if (la.kind == 4) {
Get();
x = t;
int exponent = x.val.IndexOf('e');
if (0 <= exponent) {
// this is not a legal field/destructor name
SemErr(x, "invalid IdentOrDigitsSuffix");
} else {
int dot = x.val.IndexOf('.');
if (0 <= dot) {
y = new Token();
y.pos = x.pos + dot + 1;
y.val = x.val.Substring(dot + 1);
x.val = x.val.Substring(0, dot);
y.col = x.col + dot + 1;
y.line = x.line;
y.filename = x.filename;
y.kind = x.kind;
}
}
} else SynErr(137);
}
void GenericParameters(List/*!*/ typeArgs) {
Contract.Requires(cce.NonNullElements(typeArgs));
IToken/*!*/ id;
TypeParameter.EqualitySupportValue eqSupport;
Expect(38);
NoUSIdent(out id);
eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
if (la.kind == 11) {
Get();
Expect(32);
Expect(33);
eqSupport = TypeParameter.EqualitySupportValue.Required;
}
typeArgs.Add(new TypeParameter(id, id.val, eqSupport));
while (la.kind == 30) {
Get();
NoUSIdent(out id);
eqSupport = TypeParameter.EqualitySupportValue.Unspecified;
if (la.kind == 11) {
Get();
Expect(32);
Expect(33);
eqSupport = TypeParameter.EqualitySupportValue.Required;
}
typeArgs.Add(new TypeParameter(id, id.val, eqSupport));
}
Expect(39);
}
void FieldDecl(MemberModifiers mmod, List/*!*/ mm) {
Contract.Requires(cce.NonNullElements(mm));
Attributes attrs = null;
IToken/*!*/ id; Type/*!*/ ty;
while (!(la.kind == 0 || la.kind == 29)) {SynErr(138); Get();}
Expect(29);
if (mmod.IsStatic) { SemErr(t, "fields cannot be declared 'static'"); }
while (la.kind == 9) {
Attribute(ref attrs);
}
FIdentType(out id, out ty);
mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs));
while (la.kind == 30) {
Get();
FIdentType(out id, out ty);
mm.Add(new Field(id, id.val, mmod.IsGhost, ty, attrs));
}
while (!(la.kind == 0 || la.kind == 8)) {SynErr(139); Get();}
Expect(8);
}
void FunctionDecl(MemberModifiers mmod, out Function/*!*/ f) {
Contract.Ensures(Contract.ValueAtReturn(out f)!=null);
Attributes attrs = null;
IToken/*!*/ id = Token.NoToken; // to please compiler
List typeArgs = new List();
List formals = new List();
Type/*!*/ returnType = new BoolType();
List reqs = new List();
List ens = new List();
List reads = new List();
List decreases;
Expression body = null;
bool isPredicate = false; bool isCoPredicate = false;
bool isFunctionMethod = false;
IToken openParen = null;
IToken bodyStart = Token.NoToken;
IToken bodyEnd = Token.NoToken;
IToken signatureEllipsis = null;
if (la.kind == 62) {
Get();
if (la.kind == 40) {
Get();
isFunctionMethod = true;
}
if (mmod.IsGhost) { SemErr(t, "functions cannot be declared 'ghost' (they are ghost by default)"); }
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (la.kind == 11 || la.kind == 38) {
if (la.kind == 38) {
GenericParameters(typeArgs);
}
Formals(true, isFunctionMethod, formals, out openParen);
Expect(7);
Type(out returnType);
} else if (la.kind == 37) {
Get();
signatureEllipsis = t;
openParen = Token.NoToken;
} else SynErr(140);
} else if (la.kind == 63) {
Get();
isPredicate = true;
if (la.kind == 40) {
Get();
isFunctionMethod = true;
}
if (mmod.IsGhost) { SemErr(t, "predicates cannot be declared 'ghost' (they are ghost by default)"); }
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (StartOf(5)) {
if (la.kind == 38) {
GenericParameters(typeArgs);
}
if (la.kind == 11) {
Formals(true, isFunctionMethod, formals, out openParen);
if (la.kind == 7) {
Get();
SemErr(t, "predicates do not have an explicitly declared return type; it is always bool");
}
}
} else if (la.kind == 37) {
Get();
signatureEllipsis = t;
openParen = Token.NoToken;
} else SynErr(141);
} else if (la.kind == 64) {
Get();
isCoPredicate = true;
if (mmod.IsGhost) { SemErr(t, "copredicates cannot be declared 'ghost' (they are ghost by default)"); }
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (StartOf(5)) {
if (la.kind == 38) {
GenericParameters(typeArgs);
}
if (la.kind == 11) {
Formals(true, isFunctionMethod, formals, out openParen);
if (la.kind == 7) {
Get();
SemErr(t, "copredicates do not have an explicitly declared return type; it is always bool");
}
}
} else if (la.kind == 37) {
Get();
signatureEllipsis = t;
openParen = Token.NoToken;
} else SynErr(142);
} else SynErr(143);
decreases = isCoPredicate ? null : new List();
while (StartOf(6)) {
FunctionSpec(reqs, reads, ens, decreases);
}
if (la.kind == 9) {
FunctionBody(out body, out bodyStart, out bodyEnd);
}
if (!theVerifyThisFile) { // We still need the func bodies, but don't bother verifying their correctness
List args = new List();
Attributes.Argument/*!*/ anArg;
anArg = new Attributes.Argument(id, new LiteralExpr(t, false));
args.Add(anArg);
attrs = new Attributes("verify", args, attrs);
}
if (DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 && !Attributes.Contains(attrs, "axiom")) {
SemErr(t, "a function with an ensures clause must have a body, unless given the :axiom attribute");
}
if (isPredicate) {
f = new Predicate(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals,
reqs, reads, ens, new Specification(decreases, null), body, Predicate.BodyOriginKind.OriginalOrInherited, attrs, signatureEllipsis);
} else if (isCoPredicate) {
f = new CoPredicate(id, id.val, mmod.IsStatic, typeArgs, openParen, formals,
reqs, reads, ens, body, attrs, signatureEllipsis);
} else {
f = new Function(id, id.val, mmod.IsStatic, !isFunctionMethod, typeArgs, openParen, formals, returnType,
reqs, reads, ens, new Specification(decreases, null), body, attrs, signatureEllipsis);
}
f.BodyStartTok = bodyStart;
f.BodyEndTok = bodyEnd;
}
void MethodDecl(MemberModifiers mmod, bool allowConstructor, out Method/*!*/ m) {
Contract.Ensures(Contract.ValueAtReturn(out m) !=null);
IToken/*!*/ id = Token.NoToken;
bool hasName = false; IToken keywordToken;
Attributes attrs = null;
List/*!*/ typeArgs = new List();
IToken openParen;
List ins = new List();
List outs = new List();
List req = new List();
List mod = new List();
List ens = new List();
List dec = new List();
Attributes decAttrs = null;
Attributes modAttrs = null;
BlockStmt body = null;
bool isLemma = false;
bool isConstructor = false;
bool isCoLemma = false;
IToken signatureEllipsis = null;
IToken bodyStart = Token.NoToken;
IToken bodyEnd = Token.NoToken;
while (!(StartOf(7))) {SynErr(144); Get();}
if (la.kind == 40) {
Get();
} else if (la.kind == 41) {
Get();
isLemma = true;
} else if (la.kind == 42) {
Get();
isCoLemma = true;
} else if (la.kind == 43) {
Get();
isCoLemma = true;
errors.Warning(t, "the 'comethod' keyword has been deprecated; it has been renamed to 'colemma'");
} else if (la.kind == 44) {
Get();
if (allowConstructor) {
isConstructor = true;
} else {
SemErr(t, "constructors are only allowed in classes");
}
} else SynErr(145);
keywordToken = t;
if (isLemma) {
if (mmod.IsGhost) {
SemErr(t, "lemmas cannot be declared 'ghost' (they are automatically 'ghost')");
}
} else if (isConstructor) {
if (mmod.IsGhost) {
SemErr(t, "constructors cannot be declared 'ghost'");
}
if (mmod.IsStatic) {
SemErr(t, "constructors cannot be declared 'static'");
}
} else if (isCoLemma) {
if (mmod.IsGhost) {
SemErr(t, "colemmas cannot be declared 'ghost' (they are automatically 'ghost')");
}
}
while (la.kind == 9) {
Attribute(ref attrs);
}
if (la.kind == 1) {
NoUSIdent(out id);
hasName = true;
}
if (!hasName) {
id = keywordToken;
if (!isConstructor) {
SemErr(la, "a method must be given a name (expecting identifier)");
}
}
if (la.kind == 11 || la.kind == 38) {
if (la.kind == 38) {
GenericParameters(typeArgs);
}
Formals(true, !mmod.IsGhost, ins, out openParen);
if (la.kind == 36) {
Get();
if (isConstructor) { SemErr(t, "constructors cannot have out-parameters"); }
Formals(false, !mmod.IsGhost, outs, out openParen);
}
} else if (la.kind == 37) {
Get();
signatureEllipsis = t; openParen = Token.NoToken;
} else SynErr(146);
while (StartOf(8)) {
MethodSpec(req, mod, ens, dec, ref decAttrs, ref modAttrs);
}
if (la.kind == 9) {
BlockStmt(out body, out bodyStart, out bodyEnd);
}
if (!theVerifyThisFile) {
body = null;
List args = new List();
Attributes.Argument/*!*/ anArg;
anArg = new Attributes.Argument(id, new LiteralExpr(t, false));
args.Add(anArg);
attrs = new Attributes("verify", args, attrs);
}
if (Attributes.Contains(attrs, "axiom") && !mmod.IsGhost && !isLemma) {
SemErr(t, "only ghost methods can have the :axiom attribute");
}
if (DafnyOptions.O.DisallowSoundnessCheating && body == null && ens.Count > 0 && !Attributes.Contains(attrs, "axiom")) {
SemErr(t, "a method with an ensures clause must have a body, unless given the :axiom attribute");
}
if (isConstructor) {
m = new Constructor(id, hasName ? id.val : "_ctor", typeArgs, ins,
req, new Specification(mod, modAttrs), ens, new Specification(dec, decAttrs), body, attrs, signatureEllipsis);
} else if (isCoLemma) {
m = new CoLemma(id, id.val, mmod.IsStatic, typeArgs, ins, outs,
req, new Specification(mod, modAttrs), ens, new Specification(dec, decAttrs), body, attrs, signatureEllipsis);
} else if (isLemma) {
m = new Lemma(id, id.val, mmod.IsStatic, typeArgs, ins, outs,
req, new Specification(mod, modAttrs), ens, new Specification(dec, decAttrs), body, attrs, signatureEllipsis);
} else {
m = new Method(id, id.val, mmod.IsStatic, mmod.IsGhost, typeArgs, ins, outs,
req, new Specification(mod, modAttrs), ens, new Specification(dec, decAttrs), body, attrs, signatureEllipsis);
}
m.BodyStartTok = bodyStart;
m.BodyEndTok = bodyEnd;
}
void DatatypeMemberDecl(List/*!*/ ctors) {
Contract.Requires(cce.NonNullElements(ctors));
Attributes attrs = null;
IToken/*!*/ id;
List formals = new List();
while (la.kind == 9) {
Attribute(ref attrs);
}
NoUSIdent(out id);
if (la.kind == 11) {
FormalsOptionalIds(formals);
}
ctors.Add(new DatatypeCtor(id, id.val, formals, attrs));
}
void FormalsOptionalIds(List/*!*/ formals) {
Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; string/*!*/ name; bool isGhost;
Expect(11);
if (StartOf(9)) {
TypeIdentOptional(out id, out name, out ty, out isGhost);
formals.Add(new Formal(id, name, ty, true, isGhost));
while (la.kind == 30) {
Get();
TypeIdentOptional(out id, out name, out ty, out isGhost);
formals.Add(new Formal(id, name, ty, true, isGhost));
}
}
Expect(33);
}
void FIdentType(out IToken/*!*/ id, out Type/*!*/ ty) {
Contract.Ensures(Contract.ValueAtReturn(out id) != null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
id = Token.NoToken;
if (la.kind == 1) {
WildIdent(out id, false);
} else if (la.kind == 2) {
Get();
id = t;
} else SynErr(147);
Expect(7);
Type(out ty);
}
void GIdentType(bool allowGhostKeyword, out IToken/*!*/ id, out Type/*!*/ ty, out bool isGhost) {
Contract.Ensures(Contract.ValueAtReturn(out id)!=null);
Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
isGhost = false;
if (la.kind == 24) {
Get();
if (allowGhostKeyword) { isGhost = true; } else { SemErr(t, "formal cannot be declared 'ghost' in this context"); }
}
IdentType(out id, out ty, true);
}
void IdentType(out IToken/*!*/ id, out Type/*!*/ ty, bool allowWildcardId) {
Contract.Ensures(Contract.ValueAtReturn(out id) != null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
WildIdent(out id, allowWildcardId);
Expect(7);
Type(out ty);
}
void WildIdent(out IToken/*!*/ x, bool allowWildcardId) {
Contract.Ensures(Contract.ValueAtReturn(out x) != null);
Expect(1);
x = t;
if (x.val.StartsWith("_")) {
if (allowWildcardId && x.val.Length == 1) {
t.val = "_v" + anonymousIds++;
} else {
SemErr("cannot declare identifier beginning with underscore");
}
}
}
void Type(out Type/*!*/ ty) {
Contract.Ensures(Contract.ValueAtReturn(out ty) != null); IToken/*!*/ tok;
TypeAndToken(out tok, out ty);
}
void LocalIdentTypeOptional(out LocalVariable var, bool isGhost) {
IToken id; Type ty; Type optType = null;
WildIdent(out id, true);
if (la.kind == 7) {
Get();
Type(out ty);
optType = ty;
}
var = new LocalVariable(id, id, id.val, optType == null ? new InferredTypeProxy() : optType, isGhost);
}
void IdentTypeOptional(out BoundVar var) {
Contract.Ensures(Contract.ValueAtReturn(out var) != null);
IToken id; Type ty; Type optType = null;
WildIdent(out id, true);
if (la.kind == 7) {
Get();
Type(out ty);
optType = ty;
}
var = new BoundVar(id, id.val, optType == null ? new InferredTypeProxy() : optType);
}
void TypeIdentOptional(out IToken/*!*/ id, out string/*!*/ identName, out Type/*!*/ ty, out bool isGhost) {
Contract.Ensures(Contract.ValueAtReturn(out id)!=null);
Contract.Ensures(Contract.ValueAtReturn(out ty)!=null);
Contract.Ensures(Contract.ValueAtReturn(out identName)!=null);
string name = null; id = Token.NoToken; ty = new BoolType()/*dummy*/; isGhost = false;
if (la.kind == 24) {
Get();
isGhost = true;
}
if (StartOf(10)) {
TypeAndToken(out id, out ty);
if (la.kind == 7) {
Get();
UserDefinedType udt = ty as UserDefinedType;
if (udt != null && udt.TypeArgs.Count == 0) {
name = udt.Name;
} else {
SemErr(id, "invalid formal-parameter name in datatype constructor");
}
Type(out ty);
}
} else if (la.kind == 2) {
Get();
id = t; name = id.val;
Expect(7);
Type(out ty);
} else SynErr(148);
if (name != null) {
identName = name;
} else {
identName = "#" + anonymousIds++;
}
}
void TypeAndToken(out IToken/*!*/ tok, out Type/*!*/ ty) {
Contract.Ensures(Contract.ValueAtReturn(out tok)!=null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null); tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
List/*!*/ gt;
switch (la.kind) {
case 52: {
Get();
tok = t;
break;
}
case 53: {
Get();
tok = t; ty = new NatType();
break;
}
case 54: {
Get();
tok = t; ty = new IntType();
break;
}
case 55: {
Get();
tok = t; ty = new RealType();
break;
}
case 56: {
Get();
tok = t; gt = new List();
if (la.kind == 38) {
GenericInstantiation(gt);
}
if (gt.Count > 1) {
SemErr("set type expects only one type argument");
}
ty = new SetType(gt.Count == 1 ? gt[0] : null);
break;
}
case 57: {
Get();
tok = t; gt = new List();
if (la.kind == 38) {
GenericInstantiation(gt);
}
if (gt.Count > 1) {
SemErr("multiset type expects only one type argument");
}
ty = new MultiSetType(gt.Count == 1 ? gt[0] : null);
break;
}
case 58: {
Get();
tok = t; gt = new List();
if (la.kind == 38) {
GenericInstantiation(gt);
}
if (gt.Count > 1) {
SemErr("seq type expects only one type argument");
}
ty = new SeqType(gt.Count == 1 ? gt[0] : null);
break;
}
case 59: {
Get();
tok = t; gt = new List();
if (la.kind == 38) {
GenericInstantiation(gt);
}
if (gt.Count == 0) {
ty = new MapType(null, null);
} else if (gt.Count != 2) {
SemErr("map type expects two type arguments");
ty = new MapType(gt[0], gt.Count == 1 ? new InferredTypeProxy() : gt[1]);
} else {
ty = new MapType(gt[0], gt[1]);
}
break;
}
case 1: case 5: case 60: {
ReferenceType(out tok, out ty);
break;
}
default: SynErr(149); break;
}
}
void Formals(bool incoming, bool allowGhostKeyword, List/*!*/ formals, out IToken openParen) {
Contract.Requires(cce.NonNullElements(formals)); IToken/*!*/ id; Type/*!*/ ty; bool isGhost;
Expect(11);
openParen = t;
if (la.kind == 1 || la.kind == 24) {
GIdentType(allowGhostKeyword, out id, out ty, out isGhost);
formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
while (la.kind == 30) {
Get();
GIdentType(allowGhostKeyword, out id, out ty, out isGhost);
formals.Add(new Formal(id, id.val, ty, incoming, isGhost));
}
}
Expect(33);
}
void IteratorSpec(List/*!*/ reads, List/*!*/ mod, List decreases,
List/*!*/ req, List/*!*/ ens,
List/*!*/ yieldReq, List/*!*/ yieldEns,
ref Attributes readsAttrs, ref Attributes modAttrs, ref Attributes decrAttrs) {
Expression/*!*/ e; FrameExpression/*!*/ fe; bool isFree = false; bool isYield = false; Attributes ensAttrs = null;
while (!(StartOf(11))) {SynErr(150); Get();}
if (la.kind == 50) {
Get();
while (IsAttribute()) {
Attribute(ref readsAttrs);
}
if (StartOf(12)) {
FrameExpression(out fe);
reads.Add(fe);
while (la.kind == 30) {
Get();
FrameExpression(out fe);
reads.Add(fe);
}
}
while (!(la.kind == 0 || la.kind == 8)) {SynErr(151); Get();}
Expect(8);
} else if (la.kind == 45) {
Get();
while (IsAttribute()) {
Attribute(ref modAttrs);
}
if (StartOf(12)) {
FrameExpression(out fe);
mod.Add(fe);
while (la.kind == 30) {
Get();
FrameExpression(out fe);
mod.Add(fe);
}
}
while (!(la.kind == 0 || la.kind == 8)) {SynErr(152); Get();}
Expect(8);
} else if (StartOf(13)) {
if (la.kind == 46) {
Get();
isFree = true;
}
if (la.kind == 51) {
Get();
isYield = true;
}
if (la.kind == 47) {
Get();
Expression(out e, false);
while (!(la.kind == 0 || la.kind == 8)) {SynErr(153); Get();}
Expect(8);
if (isYield) {
yieldReq.Add(new MaybeFreeExpression(e, isFree));
} else {
req.Add(new MaybeFreeExpression(e, isFree));
}
} else if (la.kind == 48) {
Get();
while (IsAttribute()) {
Attribute(ref ensAttrs);
}
Expression(out e, false);
while (!(la.kind == 0 || la.kind == 8)) {SynErr(154); Get();}
Expect(8);
if (isYield) {
yieldEns.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
} else {
ens.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
}
} else SynErr(155);
} else if (la.kind == 49) {
Get();
while (IsAttribute()) {
Attribute(ref decrAttrs);
}
DecreasesList(decreases, false);
while (!(la.kind == 0 || la.kind == 8)) {SynErr(156); Get();}
Expect(8);
} else SynErr(157);
}
void BlockStmt(out BlockStmt/*!*/ block, out IToken bodyStart, out IToken bodyEnd) {
Contract.Ensures(Contract.ValueAtReturn(out block) != null);
List body = new List();
Expect(9);
bodyStart = t;
while (StartOf(14)) {
Stmt(body);
}
Expect(10);
bodyEnd = t;
block = new BlockStmt(bodyStart, bodyEnd, body);
}
void MethodSpec(List/*!*/ req, List/*!*/ mod, List/*!*/ ens,
List/*!*/ decreases, ref Attributes decAttrs, ref Attributes modAttrs) {
Contract.Requires(cce.NonNullElements(req)); Contract.Requires(cce.NonNullElements(mod)); Contract.Requires(cce.NonNullElements(ens)); Contract.Requires(cce.NonNullElements(decreases));
Expression/*!*/ e; FrameExpression/*!*/ fe; bool isFree = false; Attributes ensAttrs = null;
while (!(StartOf(15))) {SynErr(158); Get();}
if (la.kind == 45) {
Get();
while (IsAttribute()) {
Attribute(ref modAttrs);
}
if (StartOf(12)) {
FrameExpression(out fe);
mod.Add(fe);
while (la.kind == 30) {
Get();
FrameExpression(out fe);
mod.Add(fe);
}
}
while (!(la.kind == 0 || la.kind == 8)) {SynErr(159); Get();}
Expect(8);
} else if (la.kind == 46 || la.kind == 47 || la.kind == 48) {
if (la.kind == 46) {
Get();
isFree = true;
}
if (la.kind == 47) {
Get();
Expression(out e, false);
while (!(la.kind == 0 || la.kind == 8)) {SynErr(160); Get();}
Expect(8);
req.Add(new MaybeFreeExpression(e, isFree));
} else if (la.kind == 48) {
Get();
while (IsAttribute()) {
Attribute(ref ensAttrs);
}
Expression(out e, false);
while (!(la.kind == 0 || la.kind == 8)) {SynErr(161); Get();}
Expect(8);
ens.Add(new MaybeFreeExpression(e, isFree, ensAttrs));
} else SynErr(162);
} else if (la.kind == 49) {
Get();
while (IsAttribute()) {
Attribute(ref decAttrs);
}
DecreasesList(decreases, true);
while (!(la.kind == 0 || la.kind == 8)) {SynErr(163); Get();}
Expect(8);
} else SynErr(164);
}
void FrameExpression(out FrameExpression/*!*/ fe) {
Contract.Ensures(Contract.ValueAtReturn(out fe) != null);
Expression/*!*/ e;
IToken/*!*/ id;
string fieldName = null; IToken feTok = null;
fe = null;
if (StartOf(16)) {
Expression(out e, false);
feTok = e.tok;
if (la.kind == 65) {
Get();
Ident(out id);
fieldName = id.val; feTok = id;
}
fe = new FrameExpression(feTok, e, fieldName);
} else if (la.kind == 65) {
Get();
Ident(out id);
fieldName = id.val;
fe = new FrameExpression(id, new ImplicitThisExpr(id), fieldName);
} else SynErr(165);
}
void Expression(out Expression e, bool allowSemi) {
Expression e0; IToken endTok;
EquivExpression(out e, allowSemi);
if (SemiFollowsCall(allowSemi, e)) {
Expect(8);
endTok = t;
Expression(out e0, allowSemi);
e = new StmtExpr(e.tok,
new UpdateStmt(e.tok, endTok, new List(), new List() { new ExprRhs(e, null) }),
e0);
}
}
void DecreasesList(List decreases, bool allowWildcard) {
Expression/*!*/ e;
PossiblyWildExpression(out e);
if (!allowWildcard && e is WildcardExpr) {
SemErr(e.tok, "'decreases *' is only allowed on loops and tail-recursive methods");
} else {
decreases.Add(e);
}
while (la.kind == 30) {
Get();
PossiblyWildExpression(out e);
if (!allowWildcard && e is WildcardExpr) {
SemErr(e.tok, "'decreases *' is only allowed on loops and tail-recursive methods");
} else {
decreases.Add(e);
}
}
}
void GenericInstantiation(List/*!*/ gt) {
Contract.Requires(cce.NonNullElements(gt)); Type/*!*/ ty;
Expect(38);
Type(out ty);
gt.Add(ty);
while (la.kind == 30) {
Get();
Type(out ty);
gt.Add(ty);
}
Expect(39);
}
void ReferenceType(out IToken/*!*/ tok, out Type/*!*/ ty) {
Contract.Ensures(Contract.ValueAtReturn(out tok) != null); Contract.Ensures(Contract.ValueAtReturn(out ty) != null);
tok = Token.NoToken; ty = new BoolType(); /*keep compiler happy*/
List/*!*/ gt;
List path;
if (la.kind == 60) {
Get();
tok = t; ty = new ObjectType();
} else if (la.kind == 5) {
Get();
tok = t; gt = new List();
GenericInstantiation(gt);
if (gt.Count != 1) {
SemErr("array type expects exactly one type argument");
}
int dims = 1;
if (tok.val.Length != 5) {
dims = int.Parse(tok.val.Substring(5));
}
ty = theBuiltIns.ArrayType(tok, dims, gt[0], true);
} else if (la.kind == 1) {
Ident(out tok);
gt = new List();
path = new List();
while (la.kind == 61) {
path.Add(tok);
Get();
Ident(out tok);
}
if (la.kind == 38) {
GenericInstantiation(gt);
}
ty = (tok.val == "real") ? (Type)Microsoft.Dafny.Type.Real : new UserDefinedType(tok, tok.val, gt, path);
} else SynErr(166);
}
void FunctionSpec(List/*!*/ reqs, List/*!*/ reads, List/*!*/ ens, List decreases) {
Contract.Requires(cce.NonNullElements(reqs));
Contract.Requires(cce.NonNullElements(reads));
Contract.Requires(decreases == null || cce.NonNullElements(decreases));
Expression/*!*/ e; FrameExpression/*!*/ fe;
if (la.kind == 47) {
while (!(la.kind == 0 || la.kind == 47)) {SynErr(167); Get();}
Get();
Expression(out e, false);
while (!(la.kind == 0 || la.kind == 8)) {SynErr(168); Get();}
Expect(8);
reqs.Add(e);
} else if (la.kind == 50) {
Get();
if (StartOf(17)) {
PossiblyWildFrameExpression(out fe);
reads.Add(fe);
while (la.kind == 30) {
Get();
PossiblyWildFrameExpression(out fe);
reads.Add(fe);
}
}
while (!(la.kind == 0 || la.kind == 8)) {SynErr(169); Get();}
Expect(8);
} else if (la.kind == 48) {
Get();
Expression(out e, false);
while (!(la.kind == 0 || la.kind == 8)) {SynErr(170); Get();}
Expect(8);
ens.Add(e);
} else if (la.kind == 49) {
Get();
if (decreases == null) {
SemErr(t, "'decreases' clauses are meaningless for copredicates, so they are not allowed");
decreases = new List();
}
DecreasesList(decreases, false);
while (!(la.kind == 0 || la.kind == 8)) {SynErr(171); Get();}
Expect(8);
} else SynErr(172);
}
void FunctionBody(out Expression/*!*/ e, out IToken bodyStart, out IToken bodyEnd) {
Contract.Ensures(Contract.ValueAtReturn(out e) != null); e = dummyExpr;
Expect(9);
bodyStart = t;
Expression(out e, true);
Expect(10);
bodyEnd = t;
}
void PossiblyWildFrameExpression(out FrameExpression/*!*/ fe) {
Contract.Ensures(Contract.ValueAtReturn(out fe) != null); fe = dummyFrameExpr;
if (la.kind == 12) {
Get();
fe = new FrameExpression(t, new WildcardExpr(t), null);
} else if (StartOf(12)) {
FrameExpression(out fe);
} else SynErr(173);
}
void PossiblyWildExpression(out Expression/*!*/ e) {
Contract.Ensures(Contract.ValueAtReturn(out e)!=null);
e = dummyExpr;
if (la.kind == 12) {
Get();
e = new WildcardExpr(t);
} else if (StartOf(16)) {
Expression(out e, false);
} else SynErr(174);
}
void Stmt(List/*!*/ ss) {
Statement/*!*/ s;
OneStmt(out s);
ss.Add(s);
}
void OneStmt(out Statement/*!*/ s) {
Contract.Ensures(Contract.ValueAtReturn(out s) != null); IToken/*!*/ x; IToken/*!*/ id; string label = null;
s = dummyStmt; /* to please the compiler */
BlockStmt bs;
IToken bodyStart, bodyEnd;
int breakCount;
while (!(StartOf(18))) {SynErr(175); Get();}
switch (la.kind) {
case 9: {
BlockStmt(out bs, out bodyStart, out bodyEnd);
s = bs;
break;
}
case 83: {
AssertStmt(out s);
break;
}
case 72: {
AssumeStmt(out s);
break;
}
case 84: {
PrintStmt(out s);
break;
}
case 1: case 2: case 3: case 4: case 11: case 28: case 54: case 55: case 113: case 114: case 115: case 116: case 117: case 118: {
UpdateStmt(out s);
break;
}
case 24: case 29: {
VarDeclStatement(out s);
break;
}
case 76: {
IfStmt(out s);
break;
}
case 80: {
WhileStmt(out s);
break;
}
case 82: {
MatchStmt(out s);
break;
}
case 85: case 86: {
ForallStmt(out s);
break;
}
case 88: {
CalcStmt(out s);
break;
}
case 87: {
ModifyStmt(out s);
break;
}
case 66: {
Get();
x = t;
NoUSIdent(out id);
Expect(7);
OneStmt(out s);
s.Labels = new LList