mirror of
https://github.com/byteworksinc/ORCA-C.git
synced 2024-05-29 04:41:27 +00:00
Add a function to peek at the next character.
This is necessary to correctly handle line continuations in a few places: * Between an initial . and the subsequent digit in a floating constant * Between the third and fourth characters of a %:%: digraph * Between the second and third dots of a ... token Previously, these would not be tokenized correctly, leading to spurious errors in the first and second cases above. Here is a sample program illustrating the problem: int printf(const char * restrict, ..\ \ ??/ .); int main(void) { double d = .??/ \ ??/ \ 1234; printf("%f\n", d); }
This commit is contained in:
parent
6fadd52fc2
commit
83ac0ecebf
61
Scanner.pas
61
Scanner.pas
|
@ -4610,6 +4610,61 @@ else begin {record the name}
|
||||||
end; {CheckIdentifier}
|
end; {CheckIdentifier}
|
||||||
|
|
||||||
|
|
||||||
|
function PeekCh: char;
|
||||||
|
|
||||||
|
{ Peek at the next character from the file, without advancing }
|
||||||
|
{ the character pointer. }
|
||||||
|
{ }
|
||||||
|
{ This is typically the character that will be produced by the }
|
||||||
|
{ next call to NextCh, but this function only deals with }
|
||||||
|
{ translation phases 1 and 2 (trigraphs and line continuations).}
|
||||||
|
{ It does not skip comments. }
|
||||||
|
|
||||||
|
label 1;
|
||||||
|
|
||||||
|
var
|
||||||
|
cp: ptr; {work pointer}
|
||||||
|
ch: char; {work character}
|
||||||
|
|
||||||
|
begin {PeekCh}
|
||||||
|
cp := chPtr;
|
||||||
|
1:
|
||||||
|
if cp = eofPtr then
|
||||||
|
PeekCh := chr(0)
|
||||||
|
else begin
|
||||||
|
ch := chr(cp^);
|
||||||
|
if ch = '?' then {handle trigraphs}
|
||||||
|
if ord4(eofPtr)-ord4(cp) > 2 then
|
||||||
|
if chr(ptr(ord4(cp)+1)^) = '?' then
|
||||||
|
if chr(ptr(ord4(cp)+2)^) in
|
||||||
|
['=','(','/',')','''','<','!','>','-'] then begin
|
||||||
|
case chr(ptr(ord4(cp)+2)^) of
|
||||||
|
'(': ch := '[';
|
||||||
|
'<': ch := '{';
|
||||||
|
'/': ch := '\';
|
||||||
|
'''': ch := '^';
|
||||||
|
'=': ch := '#';
|
||||||
|
')': ch := ']';
|
||||||
|
'>': ch := '}';
|
||||||
|
'!': ch := '|';
|
||||||
|
'-': ch := '~';
|
||||||
|
end; {case}
|
||||||
|
cp := pointer(ord4(cp)+2);
|
||||||
|
end; {if}
|
||||||
|
if ch = '\' then {handle line continuations}
|
||||||
|
if ord4(eofPtr)-ord4(cp) > 1 then
|
||||||
|
if charKinds[ptr(ord4(cp)+1)^] = ch_eol then begin
|
||||||
|
if ord4(eofPtr)-ord4(cp) > 2 then
|
||||||
|
if ptr(ord4(cp)+2)^ in [$06,$07] then
|
||||||
|
cp := pointer(ord4(cp)+1); {skip debugger characters}
|
||||||
|
cp := pointer(ord4(cp)+2);
|
||||||
|
goto 1;
|
||||||
|
end; {if}
|
||||||
|
PeekCh := ch;
|
||||||
|
end; {else}
|
||||||
|
end; {PeekCh}
|
||||||
|
|
||||||
|
|
||||||
procedure NextToken;
|
procedure NextToken;
|
||||||
|
|
||||||
{ Read the next token from the file. }
|
{ Read the next token from the file. }
|
||||||
|
@ -5180,7 +5235,7 @@ case charKinds[ord(ch)] of
|
||||||
else if ch = ':' then begin
|
else if ch = ':' then begin
|
||||||
NextCh;
|
NextCh;
|
||||||
token.isDigraph := true;
|
token.isDigraph := true;
|
||||||
if (ch = '%') and (chPtr <> eofPtr) and (chr(chPtr^) = ':') then begin
|
if (ch = '%') and (PeekCh = ':') then begin
|
||||||
token.kind := poundpoundop; {%:%: digraph}
|
token.kind := poundpoundop; {%:%: digraph}
|
||||||
NextCh;
|
NextCh;
|
||||||
NextCh;
|
NextCh;
|
||||||
|
@ -5228,11 +5283,11 @@ case charKinds[ord(ch)] of
|
||||||
end;
|
end;
|
||||||
|
|
||||||
ch_dot : begin {tokens that start with '.'}
|
ch_dot : begin {tokens that start with '.'}
|
||||||
if charKinds[chPtr^] = digit then
|
if charKinds[ord(PeekCh)] = digit then
|
||||||
DoNumber(false)
|
DoNumber(false)
|
||||||
else begin
|
else begin
|
||||||
NextCh;
|
NextCh;
|
||||||
if (ch = '.') and (chPtr <> eofPtr) and (chr(chPtr^) = '.') then begin
|
if (ch = '.') and (PeekCh = '.') then begin
|
||||||
token.kind := dotdotdotsy;
|
token.kind := dotdotdotsy;
|
||||||
NextCh;
|
NextCh;
|
||||||
NextCh;
|
NextCh;
|
||||||
|
|
2
cc.notes
2
cc.notes
|
@ -1919,6 +1919,8 @@ int foo(int[42]);
|
||||||
|
|
||||||
212. If fgets() is called with an n value of 1, it should write a single terminating null character to the buffer. (It was writing two.)
|
212. If fgets() is called with an n value of 1, it should write a single terminating null character to the buffer. (It was writing two.)
|
||||||
|
|
||||||
|
213. If a floating-point constant beginning with . had a line continuation between the . and the first digit, a spurious error would be reported.
|
||||||
|
|
||||||
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
|
-- Bugs from C 2.1.0 that have been fixed -----------------------------------
|
||||||
|
|
||||||
1. In some situations, fread() reread the first 1K or so of the file.
|
1. In some situations, fread() reread the first 1K or so of the file.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user