Remove code that treats # as an illegal character in most places.
C90 had constraints requiring # and ## tokens to only appear in preprocessing directives, but C99 and later removed those constraints, so this code is no longer necessary when targeting current languages versions. (It would be necessary in a "strict C90" mode, if that was ever implemented.) The main practical effect of this is that # and ## tokens can be passed as parameters to macros, provided the macro either ignores or stringizes that parameter. # and ## tokens still have no role in the grammar of the C language after preprocessing, so they will be an unexpected token and produce some kind of error if they appear anywhere. This also contains a change to ensure that a line containing one or more illegal characters (e.g. $) and then a # is not treated as a preprocessing directive.
This commit is contained in:
parent
99a10590b1
commit
b8b7dc2c2b
4
Asm.pas
4
Asm.pas
|
@ -166,10 +166,8 @@ var
|
||||||
{ An error was found: skip to the end & quit }
|
{ An error was found: skip to the end & quit }
|
||||||
|
|
||||||
begin {Skip}
|
begin {Skip}
|
||||||
charKinds[ord('#')] := ch_pound;
|
|
||||||
while not (token.kind in [rbracech,eofsy]) do
|
while not (token.kind in [rbracech,eofsy]) do
|
||||||
NextToken;
|
NextToken;
|
||||||
charKinds[ord('#')] := illegal;
|
|
||||||
goto 99;
|
goto 99;
|
||||||
end; {Skip}
|
end; {Skip}
|
||||||
|
|
||||||
|
@ -329,7 +327,6 @@ while not (token.kind in [rbracech,eofsy]) do begin
|
||||||
|
|
||||||
{find the label and op-code}
|
{find the label and op-code}
|
||||||
CheckForComment;
|
CheckForComment;
|
||||||
charKinds[ord('#')] := ch_pound; {allow # as a token}
|
|
||||||
if token.kind <> ident then begin {error if not an identifier}
|
if token.kind <> ident then begin {error if not an identifier}
|
||||||
Error(9);
|
Error(9);
|
||||||
Skip;
|
Skip;
|
||||||
|
@ -345,7 +342,6 @@ while not (token.kind in [rbracech,eofsy]) do begin
|
||||||
opname := token;
|
opname := token;
|
||||||
NextToken;
|
NextToken;
|
||||||
end; {while}
|
end; {while}
|
||||||
charKinds[ord('#')] := illegal; {don't allow # as a token}
|
|
||||||
|
|
||||||
{identify the op-code}
|
{identify the op-code}
|
||||||
if length(opname.name^) = 3 then begin
|
if length(opname.name^) = 3 then begin
|
||||||
|
|
18
Parser.pas
18
Parser.pas
|
@ -3625,33 +3625,19 @@ var
|
||||||
|
|
||||||
var
|
var
|
||||||
braceCount: integer; {# of unmatched { chars}
|
braceCount: integer; {# of unmatched { chars}
|
||||||
doingAsm: boolean; {compiling an asm statement?}
|
|
||||||
|
|
||||||
begin {SkipFunction}
|
begin {SkipFunction}
|
||||||
Match(lbracech,27); {skip to the closing rbrackch}
|
Match(lbracech,27); {skip to the closing rbrackch}
|
||||||
braceCount := 1;
|
braceCount := 1;
|
||||||
doingAsm := false;
|
|
||||||
if isAsm then
|
|
||||||
charKinds[ord('#')] := ch_pound;
|
|
||||||
while (not (token.kind = eofsy)) and (braceCount <> 0) do begin
|
while (not (token.kind = eofsy)) and (braceCount <> 0) do begin
|
||||||
if token.kind = asmsy then begin
|
if token.kind = lbracech then
|
||||||
doingAsm := true;
|
|
||||||
charKinds[ord('#')] := ch_pound;
|
|
||||||
end {if}
|
|
||||||
else if token.kind = lbracech then
|
|
||||||
braceCount := braceCount+1
|
braceCount := braceCount+1
|
||||||
else if token.kind = rbracech then begin
|
else if token.kind = rbracech then
|
||||||
braceCount := braceCount-1;
|
braceCount := braceCount-1;
|
||||||
if doingAsm then begin
|
|
||||||
doingAsm := false;
|
|
||||||
charKinds[ord('#')] := illegal;
|
|
||||||
end; {if}
|
|
||||||
end; {else if}
|
|
||||||
NextToken;
|
NextToken;
|
||||||
end; {while}
|
end; {while}
|
||||||
nameFound := false; {no pc_nam for the next function (yet)}
|
nameFound := false; {no pc_nam for the next function (yet)}
|
||||||
doingFunction := false; {no longer doing a function}
|
doingFunction := false; {no longer doing a function}
|
||||||
charKinds[ord('#')] := illegal; {# is a preprocessor command}
|
|
||||||
end; {SkipFunction}
|
end; {SkipFunction}
|
||||||
|
|
||||||
|
|
||||||
|
|
37
Scanner.pas
37
Scanner.pas
|
@ -2545,7 +2545,6 @@ var
|
||||||
mPtr^.saved := false; {not saved in symbol file}
|
mPtr^.saved := false; {not saved in symbol file}
|
||||||
mPtr^.tokens := nil; {no tokens yet}
|
mPtr^.tokens := nil; {no tokens yet}
|
||||||
mPtr^.isVarargs := false; {not varargs (yet)}
|
mPtr^.isVarargs := false; {not varargs (yet)}
|
||||||
charKinds[ord('#')] := ch_pound; {allow # as a token}
|
|
||||||
if ch = '(' then begin {scan the parameter list...}
|
if ch = '(' then begin {scan the parameter list...}
|
||||||
NextToken; {done with the name token...}
|
NextToken; {done with the name token...}
|
||||||
NextToken; {skip the opening '('}
|
NextToken; {skip the opening '('}
|
||||||
|
@ -2750,7 +2749,6 @@ var
|
||||||
parameterList := np^.next;
|
parameterList := np^.next;
|
||||||
dispose(np);
|
dispose(np);
|
||||||
end; {while}
|
end; {while}
|
||||||
charKinds[ord('#')] := illegal; {don't allow # as a token}
|
|
||||||
saveNumber := false; {stop saving numeric strings}
|
saveNumber := false; {stop saving numeric strings}
|
||||||
end; {DoDefine}
|
end; {DoDefine}
|
||||||
|
|
||||||
|
@ -3480,7 +3478,6 @@ else if charKinds[ord(ch)] = ch_eol {allow null commands}
|
||||||
if not tSkipping then
|
if not tSkipping then
|
||||||
Error(8); {bad preprocessor command}
|
Error(8); {bad preprocessor command}
|
||||||
2:
|
2:
|
||||||
charKinds[ord('#')] := ch_pound; {allow # as a token}
|
|
||||||
expandMacros := false; {skip to the end of the line}
|
expandMacros := false; {skip to the end of the line}
|
||||||
flagOverflows := false;
|
flagOverflows := false;
|
||||||
skipping := tSkipping;
|
skipping := tSkipping;
|
||||||
|
@ -3488,7 +3485,6 @@ while not (token.kind in [eolsy,eofsy]) do
|
||||||
NextToken;
|
NextToken;
|
||||||
flagOverflows := true;
|
flagOverflows := true;
|
||||||
expandMacros := true;
|
expandMacros := true;
|
||||||
charKinds[ord('#')] := illegal; {don't allow # as a token}
|
|
||||||
reportEOL := lReportEOL; {restore flags}
|
reportEOL := lReportEOL; {restore flags}
|
||||||
suppressMacroExpansions := lSuppressMacroExpansions;
|
suppressMacroExpansions := lSuppressMacroExpansions;
|
||||||
skipping := tskipping;
|
skipping := tskipping;
|
||||||
|
@ -4243,7 +4239,6 @@ new(macros); {no preprocessor macros so far}
|
||||||
for i := 0 to hashSize do
|
for i := 0 to hashSize do
|
||||||
macros^[i] := nil;
|
macros^[i] := nil;
|
||||||
pathList := nil; {no additional search paths}
|
pathList := nil; {no additional search paths}
|
||||||
charKinds[ord('#')] := illegal; {don't allow # as a token}
|
|
||||||
tokenList := nil; {nothing in putback buffer}
|
tokenList := nil; {nothing in putback buffer}
|
||||||
saveNumber := false; {don't save numbers}
|
saveNumber := false; {don't save numbers}
|
||||||
expandMacros := true; {enable macro expansion}
|
expandMacros := true; {enable macro expansion}
|
||||||
|
@ -4619,7 +4614,7 @@ procedure NextToken;
|
||||||
|
|
||||||
{ Read the next token from the file. }
|
{ Read the next token from the file. }
|
||||||
|
|
||||||
label 1,2,3,4,5,6;
|
label 1,2,3,4,5,6,7;
|
||||||
|
|
||||||
type
|
type
|
||||||
three = (s100,s1000,sMAX); {these declarations are used for a}
|
three = (s100,s1000,sMAX); {these declarations are used for a}
|
||||||
|
@ -4974,21 +4969,14 @@ if tokenList <> nil then begin {get a token put back by a macro}
|
||||||
goto 2;
|
goto 2;
|
||||||
end; {if}
|
end; {if}
|
||||||
5: {skip white space}
|
5: {skip white space}
|
||||||
while charKinds[ord(ch)] in [illegal,ch_white,ch_eol] do begin
|
while charKinds[ord(ch)] in [illegal,ch_white,ch_eol,ch_pound] do begin
|
||||||
if charKinds[ord(ch)] = illegal then begin
|
if charKinds[ord(ch)] = ch_pound then begin
|
||||||
if (ch = '#') and (lastWasReturn or (token.kind = eolsy)) then begin
|
if lastWasReturn or (token.kind = eolsy) then begin
|
||||||
NextCh; {skip the '#' char}
|
NextCh; {skip the '#' char}
|
||||||
PreProcess {call the preprocessor}
|
PreProcess {call the preprocessor}
|
||||||
end {if}
|
end {if}
|
||||||
else begin
|
else
|
||||||
tokenLine := lineNumber; {record a # token}
|
goto 7;
|
||||||
tokenColumn := ord(ord4(chPtr)-ord4(firstPtr));
|
|
||||||
tokenStart := pointer(ord4(chPtr)-1);
|
|
||||||
tokenEnd := chPtr;
|
|
||||||
if (not skipping) or (not (skipIllegalTokens or (ch = '#'))) then
|
|
||||||
Error(1);
|
|
||||||
NextCh;
|
|
||||||
end; {else}
|
|
||||||
end {if}
|
end {if}
|
||||||
else if (charKinds[ord(ch)] = ch_eol) and reportEOL then begin
|
else if (charKinds[ord(ch)] = ch_eol) and reportEOL then begin
|
||||||
token.class := reservedSymbol; {record an eol token}
|
token.class := reservedSymbol; {record an eol token}
|
||||||
|
@ -5000,6 +4988,16 @@ while charKinds[ord(ch)] in [illegal,ch_white,ch_eol] do begin
|
||||||
NextCh;
|
NextCh;
|
||||||
goto 2;
|
goto 2;
|
||||||
end {if}
|
end {if}
|
||||||
|
else if charKinds[ord(ch)] = illegal then begin
|
||||||
|
tokenLine := lineNumber; {record an illegal token}
|
||||||
|
tokenColumn := ord(ord4(chPtr)-ord4(firstPtr));
|
||||||
|
tokenStart := pointer(ord4(chPtr)-1);
|
||||||
|
tokenEnd := chPtr;
|
||||||
|
token.kind := questionch; {make sure it is not eolsy}
|
||||||
|
if (not skipping) or (not skipIllegalTokens) then
|
||||||
|
Error(1);
|
||||||
|
NextCh;
|
||||||
|
end {else if}
|
||||||
else begin {skip white space}
|
else begin {skip white space}
|
||||||
if printMacroExpansions and not suppressMacroExpansions then
|
if printMacroExpansions and not suppressMacroExpansions then
|
||||||
if charKinds[ord(ch)] = ch_eol then begin
|
if charKinds[ord(ch)] = ch_eol then begin
|
||||||
|
@ -5011,6 +5009,7 @@ while charKinds[ord(ch)] in [illegal,ch_white,ch_eol] do begin
|
||||||
NextCh;
|
NextCh;
|
||||||
end;
|
end;
|
||||||
end; {while}
|
end; {while}
|
||||||
|
7:
|
||||||
tokenLine := lineNumber; {record the position of the token}
|
tokenLine := lineNumber; {record the position of the token}
|
||||||
tokenColumn := ord(ord4(currentChPtr)-ord4(firstPtr)+1);
|
tokenColumn := ord(ord4(currentChPtr)-ord4(firstPtr)+1);
|
||||||
tokenStart := currentChPtr;
|
tokenStart := currentChPtr;
|
||||||
|
@ -5183,8 +5182,6 @@ case charKinds[ord(ch)] of
|
||||||
token.isDigraph := true;
|
token.isDigraph := true;
|
||||||
if (ch = '%') and (chPtr <> eofPtr) and (chr(chPtr^) = ':') then begin
|
if (ch = '%') and (chPtr <> eofPtr) and (chr(chPtr^) = ':') then begin
|
||||||
token.kind := poundpoundop; {%:%: digraph}
|
token.kind := poundpoundop; {%:%: digraph}
|
||||||
if charKinds[ord('#')] = illegal then
|
|
||||||
Error(1);
|
|
||||||
NextCh;
|
NextCh;
|
||||||
NextCh;
|
NextCh;
|
||||||
end
|
end
|
||||||
|
|
|
@ -57,7 +57,7 @@ charKinds start character set
|
||||||
dc i'ch_white' space
|
dc i'ch_white' space
|
||||||
dc i'ch_exc' !
|
dc i'ch_exc' !
|
||||||
dc i'ch_string' "
|
dc i'ch_string' "
|
||||||
dc i'illegal' #
|
dc i'ch_pound' #
|
||||||
dc i'illegal' $
|
dc i'illegal' $
|
||||||
dc i'ch_percent' %
|
dc i'ch_percent' %
|
||||||
dc i'ch_and' &
|
dc i'ch_and' &
|
||||||
|
|
Loading…
Reference in New Issue