Flag more appropriate errors about unexpected tokens in type names.

Previously, these would report "identifier expected"; now they correctly say "')' expected".

This introduces a new UnexpectedTokenError procedure that can be used more generally for cases where the expected token may differ based on context.
This commit is contained in:
Stephen Heumann 2020-01-18 16:43:25 -06:00
parent dbe330a7b1
commit b4232fd4ea
2 changed files with 49 additions and 11 deletions

View File

@ -2526,12 +2526,15 @@ Match(semicolonch, 22);
end; {DoStaticAssert}
procedure DeclarationSpecifiers (allowedTokens: tokenSet);
procedure DeclarationSpecifiers (allowedTokens: tokenSet;
expectedNext: tokenEnum);
{ handle declaration specifiers or a specifier-qualifier list }
{ }
{ parameters: }
{ allowedTokens - specifiers/qualifiers that can be used }
{ expectedNext - token usually expected after declaration }
{ specifiers (used for error messages only) }
{ }
{ outputs: }
{ isForwardDeclared - is the field list component }
@ -2606,7 +2609,7 @@ var
goto 1;
end; {if}
typeSpec := wordPtr; {default type specifier is an integer}
DeclarationSpecifiers(specifierQualifierListElement);
DeclarationSpecifiers(specifierQualifierListElement, ident);
if not skipDeclarator then
repeat {declare the variables...}
if didFlexibleArray then
@ -2779,7 +2782,7 @@ var
myTypeSpec := wordPtr;
end {else if}
else
Error(9);
UnexpectedTokenError(expectedNext);
end; {ResolveType}
@ -2797,7 +2800,7 @@ while token.kind in allowedTokens do begin
autosy,externsy,registersy,staticsy,typedefsy: begin
if storageClass <> ident then begin
if typeDone or (typeSpecifiers <> []) then
Error(9)
UnexpectedTokenError(expectedNext)
else
Error(26);
end; {if}
@ -2854,7 +2857,7 @@ while token.kind in allowedTokens do begin
if token.kind = lparench then begin
{_Atomic(typename) as type specifier}
if typeDone or (typeSpecifiers <> []) then
Error(9);
UnexpectedTokenError(expectedNext);
NextToken;
TypeName;
myTypeSpec := typeSpec;
@ -2867,13 +2870,13 @@ while token.kind in allowedTokens do begin
unsignedsy,signedsy,intsy,longsy,charsy,shortsy,floatsy,doublesy,voidsy,
compsy,extendedsy,_Boolsy: begin
if typeDone then
Error(9)
UnexpectedTokenError(expectedNext)
else if token.kind in typeSpecifiers then begin
if (token.kind = longsy)
and (typeSpecifiers <= [signedsy,unsignedsy,longsy,intsy]) then
Error(134)
else
Error(9);
UnexpectedTokenError(expectedNext);
end {if}
else begin
typeSpecifiers := typeSpecifiers + [token.kind];
@ -2889,7 +2892,7 @@ while token.kind in allowedTokens do begin
enumsy: begin {enum}
if typeDone or (typeSpecifiers <> []) then
Error(9);
UnexpectedTokenError(expectedNext);
NextToken; {skip the 'enum' token}
if token.kind = ident then begin {handle a type definition}
variable := FindSymbol(token, tagSpace, true, true);
@ -2959,7 +2962,7 @@ while token.kind in allowedTokens do begin
structsy, {struct}
unionsy: begin {union}
if typeDone or (typeSpecifiers <> []) then
Error(9);
UnexpectedTokenError(expectedNext);
globalStruct := false; {we didn't make it global}
if token.kind = structsy then {set the type kind to use}
tKind := structType
@ -3358,7 +3361,7 @@ typeSpec := wordPtr; {default type specifier is an integer}
{handle a TypeSpecifier/declarator}
if token.kind in declarationSpecifiersElement then
typeFound := true;
DeclarationSpecifiers(declarationSpecifiersElement);
DeclarationSpecifiers(declarationSpecifiersElement, ident);
isPascal := pascalsy in functionSpecifiers;
isAsm := asmsy in functionSpecifiers;
isInline := inlinesy in functionSpecifiers;
@ -3875,7 +3878,7 @@ var
begin {TypeName}
{read and process the type specifier}
typeSpec := wordPtr;
DeclarationSpecifiers(specifierQualifierListElement);
DeclarationSpecifiers(specifierQualifierListElement, rparench);
{handle the abstract-declarator part}
tl := nil; {no types so far}

View File

@ -111,6 +111,13 @@ procedure Error (err: integer);
{ err - error number }
procedure UnexpectedTokenError (expectedToken: tokenEnum);
{ flag an error for an unexpected token }
{ }
{ expectedToken - what was expected }
procedure InitScanner (start, endPtr: ptr);
{ initialize the scanner }
@ -654,6 +661,7 @@ if list or (numErr <> 0) then begin
137: msg := @'atomic types are not supported by ORCA/C';
138: msg := @'unsupported alignment';
139: msg := @'thread-local storage is not supported by ORCA/C';
140: msg := @'unexpected token';
otherwise: Error(57);
end; {case}
writeln(msg^);
@ -2975,6 +2983,33 @@ Error(err);
end; {Error2}
procedure UnexpectedTokenError {expectedToken: tokenEnum};
{ flag an error for an unexpected token }
{ }
{ expectedToken - what was expected }
begin {UnexpectedTokenError}
case expectedToken of
ident: Error(9);
rparench: Error(12);
lparench: Error(13);
gtch: Error(15);
intconst: Error(18);
semicolonch: Error(22);
rbracech: Error(23);
rbrackch: Error(24);
lbracech: Error(27);
colonch: Error(29);
whilesy: Error(30);
stringconst: Error(83);
commach: Error(86);
dotch: Error(89);
otherwise: Error(140);
end; {case}
end; {UnexpectedTokenError}
procedure DoNumber {scanWork: boolean};
{ The current character starts a number - scan it }