You've already forked lazarus-ccr
fpspreadsheet: Add string concatenation operation & to expression parser; remove string concatenation by means of "+"
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@3501 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -36,12 +36,17 @@
|
|||||||
<PackageName Value="LazUtils"/>
|
<PackageName Value="LazUtils"/>
|
||||||
</Item1>
|
</Item1>
|
||||||
</RequiredPackages>
|
</RequiredPackages>
|
||||||
<Units Count="1">
|
<Units Count="2">
|
||||||
<Unit0>
|
<Unit0>
|
||||||
<Filename Value="demo_expression_parser.pas"/>
|
<Filename Value="demo_expression_parser.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
<UnitName Value="demo_expression_parser"/>
|
<UnitName Value="demo_expression_parser"/>
|
||||||
</Unit0>
|
</Unit0>
|
||||||
|
<Unit1>
|
||||||
|
<Filename Value="..\..\fpsexprparser.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<UnitName Value="fpsExprParser"/>
|
||||||
|
</Unit1>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
|
@ -31,14 +31,15 @@ begin
|
|||||||
workbook := TsWorkbook.Create;
|
workbook := TsWorkbook.Create;
|
||||||
try
|
try
|
||||||
worksheet := workbook.AddWorksheet('Test');
|
worksheet := workbook.AddWorksheet('Test');
|
||||||
|
{
|
||||||
worksheet.WriteNumber(0, 0, 2); // A1
|
worksheet.WriteNumber(0, 0, 2); // A1
|
||||||
worksheet.WriteNumber(0, 1, 2.5); // B1
|
worksheet.WriteNumber(0, 1, 2.5); // B1
|
||||||
{
|
}
|
||||||
worksheet.WriteUTF8Text(0, 0, 'Hallo'); // A1
|
worksheet.WriteUTF8Text(0, 0, 'Hallo'); // A1
|
||||||
worksheet.WriteUTF8Text(0, 1, 'Welt'); // B1
|
worksheet.WriteUTF8Text(0, 1, 'World'); // B1
|
||||||
}
|
|
||||||
cell := worksheet.WriteFormula(1, 0, '=(A1+2)*3'); // A2
|
//cell := worksheet.WriteFormula(1, 0, '=(A1+2)*3'); // A2
|
||||||
|
cell := worksheet.WriteFormula(1, 0, 'A1&" "&B1');
|
||||||
|
|
||||||
WriteLn('A1 = ', worksheet.ReadAsUTF8Text(0, 0));
|
WriteLn('A1 = ', worksheet.ReadAsUTF8Text(0, 0));
|
||||||
WriteLn('B1 = ', worksheet.ReadAsUTF8Text(0, 1));
|
WriteLn('B1 = ', worksheet.ReadAsUTF8Text(0, 1));
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
Modified for integration into fpspreadsheet by Werner Pamler:
|
Modified for integration into fpspreadsheet by Werner Pamler:
|
||||||
- Original file name: fpexprpars.pp
|
- Original file name: fpexprpars.pp
|
||||||
- Rename identifiers to avoid naming conflicts with the original
|
- Rename identifiers to avoid naming conflicts with the original
|
||||||
- TsExpressionParser and TsBuiltinExpressionManager are not components any more
|
- TsExpressionParser and TsBuiltinExpressionManager are not components
|
||||||
|
any more
|
||||||
- TsExpressionParser is created with the worksheet as a parameter.
|
- TsExpressionParser is created with the worksheet as a parameter.
|
||||||
- add new TExprNode classes:
|
- add new TExprNode classes:
|
||||||
- TsCellExprNode for references to cells
|
- TsCellExprNode for references to cells
|
||||||
@ -26,7 +27,7 @@
|
|||||||
- remove and modifiy built-in function such that the parser is compatible
|
- remove and modifiy built-in function such that the parser is compatible
|
||||||
with Excel syntax (and OpenOffice - which is the same).
|
with Excel syntax (and OpenOffice - which is the same).
|
||||||
|
|
||||||
**********************************************************************}
|
******************************************************************************}
|
||||||
{$mode objfpc}
|
{$mode objfpc}
|
||||||
{$h+}
|
{$h+}
|
||||||
unit fpsExprParser;
|
unit fpsExprParser;
|
||||||
@ -49,7 +50,7 @@ type
|
|||||||
fekParen,
|
fekParen,
|
||||||
*)
|
*)
|
||||||
TTokenType = (
|
TTokenType = (
|
||||||
ttPlus, ttMinus, ttMul, ttDiv, ttPercent, ttPower, ttLeft, ttRight,
|
ttPlus, ttMinus, ttMul, ttDiv, ttConcat, ttPercent, ttPower, ttLeft, ttRight,
|
||||||
ttLessThan, ttLargerThan, ttEqual, ttNotEqual, ttLessThanEqual, ttLargerThanEqual,
|
ttLessThan, ttLargerThan, ttEqual, ttNotEqual, ttLessThanEqual, ttLargerThanEqual,
|
||||||
ttNumber, ttString, ttIdentifier, ttCell, ttCellRange,
|
ttNumber, ttString, ttIdentifier, ttCell, ttCellRange,
|
||||||
ttComma, ttAnd, ttOr, ttXor, ttTrue, ttFalse, ttNot, ttIf,
|
ttComma, ttAnd, ttOr, ttXor, ttTrue, ttFalse, ttNot, ttIf,
|
||||||
@ -272,6 +273,17 @@ type
|
|||||||
property Condition: TsExprNode read FCondition;
|
property Condition: TsExprNode read FCondition;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ TsConcatExprNode }
|
||||||
|
TsConcatExprNode = class(TsBinaryOperationExprNode)
|
||||||
|
protected
|
||||||
|
procedure Check; override;
|
||||||
|
procedure GetNodeValue(var Result: TsExpressionResult); override;
|
||||||
|
function NodeType: TsResultType; override;
|
||||||
|
public
|
||||||
|
function AsRPNItem(ANext: PRPNItem): PRPNItem; override;
|
||||||
|
function AsString: string ; override;
|
||||||
|
end;
|
||||||
|
|
||||||
{ TsMathOperationExprNode }
|
{ TsMathOperationExprNode }
|
||||||
TsMathOperationExprNode = class(TsBinaryOperationExprNode)
|
TsMathOperationExprNode = class(TsBinaryOperationExprNode)
|
||||||
protected
|
protected
|
||||||
@ -914,7 +926,7 @@ begin
|
|||||||
'/' : Result := ttDiv;
|
'/' : Result := ttDiv;
|
||||||
'^' : Result := ttPower;
|
'^' : Result := ttPower;
|
||||||
'%' : Result := ttPercent;
|
'%' : Result := ttPercent;
|
||||||
'&' : Result := ttPlus;
|
'&' : Result := ttConcat;
|
||||||
'<' : Result := ttLessThan;
|
'<' : Result := ttLessThan;
|
||||||
'>' : Result := ttLargerThan;
|
'>' : Result := ttLargerThan;
|
||||||
'=' : Result := ttEqual;
|
'=' : Result := ttEqual;
|
||||||
@ -1356,7 +1368,7 @@ begin
|
|||||||
{$ifdef debugexpr} Writeln('Level 3 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
|
{$ifdef debugexpr} Writeln('Level 3 ',TokenName(TokenType),': ',CurrentToken);{$endif debugexpr}
|
||||||
Result := Level4;
|
Result := Level4;
|
||||||
try
|
try
|
||||||
while TokenType in [ttPlus, ttMinus] do begin
|
while TokenType in [ttPlus, ttMinus, ttConcat] do begin
|
||||||
tt := TokenType;
|
tt := TokenType;
|
||||||
GetToken;
|
GetToken;
|
||||||
CheckEOF;
|
CheckEOF;
|
||||||
@ -1365,6 +1377,7 @@ begin
|
|||||||
case tt of
|
case tt of
|
||||||
ttPlus : Result := TsAddExprNode.Create(Result, right);
|
ttPlus : Result := TsAddExprNode.Create(Result, right);
|
||||||
ttMinus : Result := TsSubtractExprNode.Create(Result, right);
|
ttMinus : Result := TsSubtractExprNode.Create(Result, right);
|
||||||
|
ttConcat: Result := TsConcatExprNode.Create(Result, right);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
except
|
except
|
||||||
@ -1483,10 +1496,6 @@ begin
|
|||||||
// Determine number of arguments
|
// Determine number of arguments
|
||||||
if isIF then
|
if isIF then
|
||||||
ACount := 3
|
ACount := 3
|
||||||
{
|
|
||||||
else if isCASE then
|
|
||||||
ACount := -4
|
|
||||||
}
|
|
||||||
else if (ID.IdentifierType in [itFunctionCallBack, itFunctionHandler]) then
|
else if (ID.IdentifierType in [itFunctionCallBack, itFunctionHandler]) then
|
||||||
ACount := ID.ArgumentCount
|
ACount := ID.ArgumentCount
|
||||||
else
|
else
|
||||||
@ -2662,11 +2671,49 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TsConcatExprNode }
|
||||||
|
|
||||||
|
procedure TsConcatExprNode.Check;
|
||||||
|
begin
|
||||||
|
inherited Check;
|
||||||
|
CheckNodeType(Left, [rtString]);
|
||||||
|
CheckNodeType(Right, [rtString]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TsConcatExprNode.GetNodeValue(var Result: TsExpressionResult);
|
||||||
|
var
|
||||||
|
RRes : TsExpressionResult;
|
||||||
|
begin
|
||||||
|
Left.GetNodeValue(Result);
|
||||||
|
Right.GetNodeValue(RRes);
|
||||||
|
Result.ResString := Result.ResString + RRes.ResString;
|
||||||
|
Result.ResultType := rtString;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TsConcatExprNode.NodeType: TsResultType;
|
||||||
|
begin
|
||||||
|
Result := rtString;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TsConcatExprNode.AsRPNItem(ANext: PRPNItem): PRPNItem;
|
||||||
|
begin
|
||||||
|
Result := RPNFunc(fekConcat,
|
||||||
|
Right.AsRPNItem(
|
||||||
|
Left.AsRPNItem(
|
||||||
|
nil)));
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TsConcatExprNode.AsString: string;
|
||||||
|
begin
|
||||||
|
Result := Left.AsString + '&' + Right.AsString;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TsMathOperationExprNode }
|
{ TsMathOperationExprNode }
|
||||||
|
|
||||||
procedure TsMathOperationExprNode.Check;
|
procedure TsMathOperationExprNode.Check;
|
||||||
const
|
const
|
||||||
AllowedTypes = [rtInteger, rtfloat, rtDateTime, rtString];
|
AllowedTypes = [rtInteger, rtfloat, rtDateTime];
|
||||||
begin
|
begin
|
||||||
inherited Check;
|
inherited Check;
|
||||||
CheckNodeType(Left, AllowedTypes);
|
CheckNodeType(Left, AllowedTypes);
|
||||||
@ -2704,7 +2751,7 @@ begin
|
|||||||
Right.GetNodeValue(RRes);
|
Right.GetNodeValue(RRes);
|
||||||
case Result.ResultType of
|
case Result.ResultType of
|
||||||
rtInteger : Result.ResInteger := Result.ResInteger + RRes.ResInteger;
|
rtInteger : Result.ResInteger := Result.ResInteger + RRes.ResInteger;
|
||||||
rtString : Result.ResString := Result.ResString + RRes.ResString;
|
// rtString : Result.ResString := Result.ResString + RRes.ResString;
|
||||||
rtDateTime : Result.ResDateTime := Result.ResDateTime + RRes.ResDateTime;
|
rtDateTime : Result.ResDateTime := Result.ResDateTime + RRes.ResDateTime;
|
||||||
rtFloat : Result.ResFloat := Result.ResFloat + RRes.ResFloat;
|
rtFloat : Result.ResFloat := Result.ResFloat + RRes.ResFloat;
|
||||||
end;
|
end;
|
||||||
|
Reference in New Issue
Block a user