fix, valid operator combinations could be detected as invalid

This commit is contained in:
Basile Burg 2016-03-28 02:40:42 +02:00
parent c74f6af73f
commit 487241064c
3 changed files with 137 additions and 72 deletions

View File

@ -827,7 +827,7 @@ begin
exit; exit;
end; end;
// symbols 1 // symbols
if isSymbol(reader^) then if isSymbol(reader^) then
begin begin
fTokKind := tkSymbl; fTokKind := tkSymbl;
@ -856,31 +856,60 @@ begin
if isOperator1(reader^) then if isOperator1(reader^) then
begin begin
fTokKind := tkSymbl; fTokKind := tkSymbl;
while isOperator1(readerNext^) do (*!*); while isOperator1(readerNext^) do
case fTokStop - fTokStart of if fTokStop - fTokStart = 4 then break;
4:begin if (fTokStop - fTokStart = 4) then
if (not isOperator1(reader^)) and begin
isOperator4(fLineBuf[fTokStart..fTokStop-1]) if isOperator4(fLineBuf[fTokStart..fTokStart+3]) then
then exit; exit;
if isOperator3(fLineBuf[fTokStart..fTokStart+2]) then
begin
readerPrev;
exit;
end; end;
3:begin if isOperator2(fLineBuf[fTokStart..fTokStart+1]) then
if (not isOperator1(reader^)) and begin
(isOperator3(fLineBuf[fTokStart..fTokStop-1]) or readerPrev;
(isOperator2(fLineBuf[fTokStart..fTokStop-2]) and readerPrev;
isPostOpSymbol(fLineBuf[fTokStop-1]))) exit;
then exit;
end; end;
2:begin if isOperator1(fLineBuf[fTokStart]) then
if (not isOperator1(reader^)) and begin
isOperator2(fLineBuf[fTokStart..fTokStop-1]) readerPrev;
then exit; readerPrev;
end; readerPrev;
1:begin exit;
if not isOperator1(reader^) then exit;
end; end;
end; end;
if (fTokStop - fTokStart = 3) then
begin
if isOperator3(fLineBuf[fTokStart..fTokStart+2]) then
exit;
if isOperator2(fLineBuf[fTokStart..fTokStart+1]) then
begin
readerPrev;
exit;
end;
if isOperator1(fLineBuf[fTokStart]) then
begin
readerPrev;
readerPrev;
exit;
end;
end;
if (fTokStop - fTokStart = 2) then
begin
if isOperator2(fLineBuf[fTokStart..fTokStart+1]) then
exit;
if isOperator1(fLineBuf[fTokStart]) then
begin
readerPrev;
exit;
end;
end;
if (fTokStop - fTokStart = 1) and isOperator1(fLineBuf[fTokStart]) then
exit;
fTokKind := tkError; fTokKind := tkError;
//if isWhite(reader^) then
exit; exit;
end; end;

View File

@ -739,51 +739,97 @@ begin
if isOutOfBound then if isOutOfBound then
exit; exit;
identifier += reader.head^; identifier += reader.head^;
if length(identifier) = 4 then
break;
end; end;
case length(identifier) of if length(identifier) = 4 then
4:
begin begin
if (not isOperator1(reader.head^)) and if isOperator4(identifier) then
isOperator4(identifier) then
begin begin
addToken(ltkOperator); addToken(ltkOperator);
if callBackDoStop then if callBackDoStop then
exit; exit;
continue; continue;
end; end;
if isOperator3(identifier[1..length(identifier)-1]) then
begin
reader.previous;
addToken(ltkOperator);
if callBackDoStop then
exit;
continue;
end; end;
3: if isOperator2(identifier[1..length(identifier)-2]) then
begin begin
if (not isOperator1(reader.head^)) and reader.previous;
isOperator3(identifier) then reader.previous;
addToken(ltkOperator);
if callBackDoStop then
exit;
continue;
end;
if isOperator1(identifier[1]) then
begin begin
reader.previous;
reader.previous;
reader.previous;
addToken(ltkOperator); addToken(ltkOperator);
if callBackDoStop then if callBackDoStop then
exit; exit;
continue; continue;
end; end;
end; end;
2: if length(identifier) = 3 then
begin begin
if (not isOperator1(reader.head^)) and if isOperator3(identifier) then
isOperator2(identifier) then
begin begin
addToken(ltkOperator); addToken(ltkOperator);
if callBackDoStop then if callBackDoStop then
exit; exit;
continue; continue;
end; end;
if isOperator2(identifier[1..length(identifier)-1]) then
begin
reader.previous;
addToken(ltkOperator);
if callBackDoStop then
exit;
continue;
end; end;
1: if isOperator1(identifier[1]) then
begin
if not isOperator1(reader.head^) then
begin begin
reader.previous;
reader.previous;
addToken(ltkOperator); addToken(ltkOperator);
if callBackDoStop then if callBackDoStop then
exit; exit;
continue; continue;
end; end;
end; end;
if length(identifier) = 2 then
begin
if isOperator2(identifier) then
begin
addToken(ltkOperator);
if callBackDoStop then
exit;
continue;
end;
if isOperator1(identifier[1]) then
begin
reader.previous;
addToken(ltkOperator);
if callBackDoStop then
exit;
continue;
end;
end;
if (length(identifier) = 1) and isOperator1(identifier[1]) then
begin
addToken(ltkOperator);
if callBackDoStop then
exit;
continue;
end; end;
end; end;
@ -807,7 +853,9 @@ begin
end; end;
// error // error
{$IFDEF DEBUG}
identifier += ' (unrecognized lexer input)'; identifier += ' (unrecognized lexer input)';
{$ENDIF}
addToken(ltkIllegal); addToken(ltkIllegal);
end; end;

View File

@ -26,8 +26,6 @@ function isBit(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isAlNum(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF} function isAlNum(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isHex(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF} function isHex(const c: Char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isSymbol(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF} function isSymbol(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isPtrOperator(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isPostOpSymbol(const c: char): boolean; {$IFNDEF DEBUG} inline; {$ENDIF}
function isOperator1(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF} function isOperator1(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isOperator2(const s: string): boolean; {$IFNDEF DEBUG}inline;{$ENDIF} function isOperator2(const s: string): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
function isOperator3(const s: string): boolean; {$IFNDEF DEBUG} inline; {$ENDIF} function isOperator3(const s: string): boolean; {$IFNDEF DEBUG} inline; {$ENDIF}
@ -97,16 +95,6 @@ begin
exit(c in [';', '{', '}', '(', ')', '[', ']', ',', '.', ':' , '"', #39, '?', '$', #35]); exit(c in [';', '{', '}', '(', ')', '[', ']', ',', '.', ':' , '"', #39, '?', '$', #35]);
end; end;
function isPtrOperator(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(c in ['&', '*']);
end;
function isPostOpSymbol (const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin
exit(c in ['+', '-', '*', '&']);
end;
function isOperator1(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF} function isOperator1(const c: char): boolean; {$IFNDEF DEBUG}inline;{$ENDIF}
begin begin
exit(c in ['/', '*', '-', '+', '%', '>', '<', '=', '!', '&', '|', '^', '~']); exit(c in ['/', '*', '-', '+', '%', '>', '<', '=', '!', '&', '|', '^', '~']);