Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
tsoc
openmm
Commits
259cb45a
Commit
259cb45a
authored
Jul 23, 2009
by
Peter Eastman
Browse files
Creating expression parsing library for use in custom forces
parent
65452671
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
1229 additions
and
0 deletions
+1229
-0
libraries/lepton/include/Exception.h
libraries/lepton/include/Exception.h
+59
-0
libraries/lepton/include/ExpressionTreeNode.h
libraries/lepton/include/ExpressionTreeNode.h
+62
-0
libraries/lepton/include/Operation.h
libraries/lepton/include/Operation.h
+531
-0
libraries/lepton/include/ParsedExpression.h
libraries/lepton/include/ParsedExpression.h
+55
-0
libraries/lepton/include/Parser.h
libraries/lepton/include/Parser.h
+63
-0
libraries/lepton/include/windowsIncludes.h
libraries/lepton/include/windowsIncludes.h
+41
-0
libraries/lepton/src/ExpressionTreeNode.cpp
libraries/lepton/src/ExpressionTreeNode.cpp
+87
-0
libraries/lepton/src/ParsedExpression.cpp
libraries/lepton/src/ParsedExpression.cpp
+59
-0
libraries/lepton/src/Parser.cpp
libraries/lepton/src/Parser.cpp
+272
-0
No files found.
libraries/lepton/include/Exception.h
0 → 100644
View file @
259cb45a
#ifndef LEPTON_EXCEPTION_H_
#define LEPTON_EXCEPTION_H_
/* -------------------------------------------------------------------------- *
* Lepton *
* -------------------------------------------------------------------------- *
* This is part of the Lepton expression parser originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include <exception>
#include <string>
namespace
Lepton
{
/**
* This class is used for all exceptions thrown by Lepton.
*/
class
Exception
:
public
std
::
exception
{
public:
Exception
(
const
std
::
string
&
message
)
:
message
(
message
)
{
}
~
Exception
()
throw
()
{
}
const
char
*
what
()
const
throw
()
{
return
message
.
c_str
();
}
private:
std
::
string
message
;
};
}
// namespace Lepton
#endif
/*LEPTON_EXCEPTION_H_*/
libraries/lepton/include/ExpressionTreeNode.h
0 → 100644
View file @
259cb45a
#ifndef LEPTON_EXPRESSION_TREE_NODE_H_
#define LEPTON_EXPRESSION_TREE_NODE_H_
/* -------------------------------------------------------------------------- *
* Lepton *
* -------------------------------------------------------------------------- *
* This is part of the Lepton expression parser originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "windowsIncludes.h"
#include <string>
#include <vector>
namespace
Lepton
{
class
Operation
;
class
LEPTON_EXPORT
ExpressionTreeNode
{
public:
ExpressionTreeNode
(
Operation
*
operation
,
const
std
::
vector
<
ExpressionTreeNode
>&
children
);
ExpressionTreeNode
(
Operation
*
operation
,
const
ExpressionTreeNode
&
child1
,
const
ExpressionTreeNode
&
child2
);
ExpressionTreeNode
(
Operation
*
operation
,
const
ExpressionTreeNode
&
child
);
ExpressionTreeNode
(
Operation
*
operation
);
ExpressionTreeNode
(
const
ExpressionTreeNode
&
node
);
ExpressionTreeNode
();
~
ExpressionTreeNode
();
ExpressionTreeNode
&
operator
=
(
const
ExpressionTreeNode
&
node
);
const
Operation
&
getOperation
()
const
;
const
std
::
vector
<
ExpressionTreeNode
>&
getChildren
()
const
;
private:
Operation
*
operation
;
std
::
vector
<
ExpressionTreeNode
>
children
;
};
}
// namespace Lepton
#endif
/*LEPTON_EXPRESSION_TREE_NODE_H_*/
libraries/lepton/include/Operation.h
0 → 100644
View file @
259cb45a
#ifndef LEPTON_OPERATION_H_
#define LEPTON_OPERATION_H_
/* -------------------------------------------------------------------------- *
* Lepton *
* -------------------------------------------------------------------------- *
* This is part of the Lepton expression parser originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "windowsIncludes.h"
#include <cmath>
#include <map>
#include <string>
#include <vector>
#include <sstream>
namespace
Lepton
{
class
LEPTON_EXPORT
Operation
{
public:
enum
Id
{
CONSTANT
,
VARIABLE
,
CUSTOM
,
ADD
,
SUBTRACT
,
MULTIPLY
,
DIVIDE
,
POWER
,
NEGATE
,
SQRT
,
EXP
,
LOG
,
SIN
,
COS
,
SEC
,
CSC
,
TAN
,
COT
,
ASIN
,
ACOS
,
ATAN
};
virtual
std
::
string
getName
()
const
=
0
;
virtual
Id
getId
()
const
=
0
;
virtual
int
getNumArguments
()
const
=
0
;
virtual
Operation
*
clone
()
const
=
0
;
virtual
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
=
0
;
class
Constant
;
class
Variable
;
class
Custom
;
class
Add
;
class
Subtract
;
class
Multiply
;
class
Divide
;
class
Power
;
class
Negate
;
class
Sqrt
;
class
Exp
;
class
Log
;
class
Sin
;
class
Cos
;
class
Sec
;
class
Csc
;
class
Tan
;
class
Cot
;
class
Asin
;
class
Acos
;
class
Atan
;
};
class
Operation
::
Constant
:
public
Operation
{
public:
Constant
(
double
value
)
:
value
(
value
)
{
}
std
::
string
getName
()
const
{
std
::
stringstream
name
;
name
<<
value
;
return
name
.
str
();
}
Id
getId
()
const
{
return
CONSTANT
;
}
int
getNumArguments
()
const
{
return
0
;
}
Operation
*
clone
()
const
{
return
new
Constant
(
value
);
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
value
;
}
private:
double
value
;
};
class
Operation
::
Variable
:
public
Operation
{
public:
Variable
(
const
std
::
string
&
name
)
:
name
(
name
)
{
}
std
::
string
getName
()
const
{
return
name
;
}
Id
getId
()
const
{
return
VARIABLE
;
}
int
getNumArguments
()
const
{
return
0
;
}
Operation
*
clone
()
const
{
return
new
Variable
(
name
);
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
std
::
map
<
std
::
string
,
double
>::
const_iterator
iter
=
variables
.
find
(
name
);
if
(
iter
==
variables
.
end
())
throw
std
::
exception
();
return
iter
->
second
;
}
private:
std
::
string
name
;
};
class
Operation
::
Custom
:
public
Operation
{
public:
Custom
(
const
std
::
string
&
name
,
int
arguments
)
:
name
(
name
),
arguments
(
arguments
)
{
}
std
::
string
getName
()
const
{
return
name
;
}
Id
getId
()
const
{
return
CUSTOM
;
}
int
getNumArguments
()
const
{
return
arguments
;
}
Operation
*
clone
()
const
{
return
new
Custom
(
name
,
arguments
);
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
0.0
;
}
private:
std
::
string
name
;
int
arguments
;
};
class
Operation
::
Add
:
public
Operation
{
public:
Add
()
{
}
std
::
string
getName
()
const
{
return
"+"
;
}
Id
getId
()
const
{
return
ADD
;
}
int
getNumArguments
()
const
{
return
2
;
}
Operation
*
clone
()
const
{
return
new
Add
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
args
[
0
]
+
args
[
1
];
}
};
class
Operation
::
Subtract
:
public
Operation
{
public:
Subtract
()
{
}
std
::
string
getName
()
const
{
return
"-"
;
}
Id
getId
()
const
{
return
SUBTRACT
;
}
int
getNumArguments
()
const
{
return
2
;
}
Operation
*
clone
()
const
{
return
new
Subtract
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
args
[
0
]
-
args
[
1
];
}
};
class
Operation
::
Multiply
:
public
Operation
{
public:
Multiply
()
{
}
std
::
string
getName
()
const
{
return
"*"
;
}
Id
getId
()
const
{
return
MULTIPLY
;
}
int
getNumArguments
()
const
{
return
2
;
}
Operation
*
clone
()
const
{
return
new
Multiply
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
args
[
0
]
*
args
[
1
];
}
};
class
Operation
::
Divide
:
public
Operation
{
public:
Divide
()
{
}
std
::
string
getName
()
const
{
return
"/"
;
}
Id
getId
()
const
{
return
DIVIDE
;
}
int
getNumArguments
()
const
{
return
2
;
}
Operation
*
clone
()
const
{
return
new
Divide
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
args
[
0
]
/
args
[
1
];
}
};
class
Operation
::
Power
:
public
Operation
{
public:
Power
()
{
}
std
::
string
getName
()
const
{
return
"^"
;
}
Id
getId
()
const
{
return
POWER
;
}
int
getNumArguments
()
const
{
return
2
;
}
Operation
*
clone
()
const
{
return
new
Power
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
pow
(
args
[
0
],
args
[
1
]);
}
};
class
Operation
::
Negate
:
public
Operation
{
public:
Negate
()
{
}
std
::
string
getName
()
const
{
return
"-"
;
}
Id
getId
()
const
{
return
NEGATE
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Negate
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
-
args
[
0
];
}
};
class
Operation
::
Sqrt
:
public
Operation
{
public:
Sqrt
()
{
}
std
::
string
getName
()
const
{
return
"sqrt"
;
}
Id
getId
()
const
{
return
SQRT
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Sqrt
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
sqrt
(
args
[
0
]);
}
};
class
Operation
::
Exp
:
public
Operation
{
public:
Exp
()
{
}
std
::
string
getName
()
const
{
return
"exp"
;
}
Id
getId
()
const
{
return
EXP
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Exp
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
exp
(
args
[
0
]);
}
};
class
Operation
::
Log
:
public
Operation
{
public:
Log
()
{
}
std
::
string
getName
()
const
{
return
"log"
;
}
Id
getId
()
const
{
return
SQRT
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Log
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
log
(
args
[
0
]);
}
};
class
Operation
::
Sin
:
public
Operation
{
public:
Sin
()
{
}
std
::
string
getName
()
const
{
return
"sin"
;
}
Id
getId
()
const
{
return
LOG
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Sin
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
sin
(
args
[
0
]);
}
};
class
Operation
::
Cos
:
public
Operation
{
public:
Cos
()
{
}
std
::
string
getName
()
const
{
return
"cos"
;
}
Id
getId
()
const
{
return
COS
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Cos
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
cos
(
args
[
0
]);
}
};
class
Operation
::
Sec
:
public
Operation
{
public:
Sec
()
{
}
std
::
string
getName
()
const
{
return
"sec"
;
}
Id
getId
()
const
{
return
SEC
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Sec
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
1.0
/
std
::
cos
(
args
[
0
]);
}
};
class
Operation
::
Csc
:
public
Operation
{
public:
Csc
()
{
}
std
::
string
getName
()
const
{
return
"csc"
;
}
Id
getId
()
const
{
return
CSC
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Csc
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
1.0
/
std
::
sin
(
args
[
0
]);
}
};
class
Operation
::
Tan
:
public
Operation
{
public:
Tan
()
{
}
std
::
string
getName
()
const
{
return
"tan"
;
}
Id
getId
()
const
{
return
TAN
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Tan
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
tan
(
args
[
0
]);
}
};
class
Operation
::
Cot
:
public
Operation
{
public:
Cot
()
{
}
std
::
string
getName
()
const
{
return
"cot"
;
}
Id
getId
()
const
{
return
COT
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Cot
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
1.0
/
std
::
tan
(
args
[
0
]);
}
};
class
Operation
::
Asin
:
public
Operation
{
public:
Asin
()
{
}
std
::
string
getName
()
const
{
return
"asin"
;
}
Id
getId
()
const
{
return
ASIN
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Asin
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
asin
(
args
[
0
]);
}
};
class
Operation
::
Acos
:
public
Operation
{
public:
Acos
()
{
}
std
::
string
getName
()
const
{
return
"acos"
;
}
Id
getId
()
const
{
return
ACOS
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Acos
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
acos
(
args
[
0
]);
}
};
class
Operation
::
Atan
:
public
Operation
{
public:
Atan
()
{
}
std
::
string
getName
()
const
{
return
"atan"
;
}
Id
getId
()
const
{
return
ATAN
;
}
int
getNumArguments
()
const
{
return
1
;
}
Operation
*
clone
()
const
{
return
new
Atan
();
}
double
evaluate
(
double
*
args
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
std
::
atan
(
args
[
0
]);
}
};
}
// namespace Lepton
#endif
/*LEPTON_OPERATION_H_*/
libraries/lepton/include/ParsedExpression.h
0 → 100644
View file @
259cb45a
#ifndef LEPTON_PARSED_EXPRESSION_H_
#define LEPTON_PARSED_EXPRESSION_H_
/* -------------------------------------------------------------------------- *
* Lepton *
* -------------------------------------------------------------------------- *
* This is part of the Lepton expression parser originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "ExpressionTreeNode.h"
#include "windowsIncludes.h"
#include <map>
#include <string>
namespace
Lepton
{
class
LEPTON_EXPORT
ParsedExpression
{
public:
ParsedExpression
(
ExpressionTreeNode
rootNode
);
const
ExpressionTreeNode
&
getRootNode
()
const
;
double
evaluate
()
const
;
double
evaluate
(
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
;
private:
double
evaluate
(
const
ExpressionTreeNode
&
node
,
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
;
ExpressionTreeNode
rootNode
;
};
}
// namespace Lepton
#endif
/*LEPTON_PARSED_EXPRESSION_H_*/
libraries/lepton/include/Parser.h
0 → 100644
View file @
259cb45a
#ifndef LEPTON_PARSER_H_
#define LEPTON_PARSER_H_
/* -------------------------------------------------------------------------- *
* Lepton *
* -------------------------------------------------------------------------- *
* This is part of the Lepton expression parser originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "windowsIncludes.h"
#include <string>
#include <vector>
namespace
Lepton
{
class
ExpressionTreeNode
;
class
Operation
;
class
ParsedExpression
;
class
ParseToken
;
/**
* This class provides the main interface for parsing expressions.
*/
class
LEPTON_EXPORT
Parser
{
public:
static
ParsedExpression
parse
(
std
::
string
expression
);
private:
static
std
::
vector
<
ParseToken
>
tokenize
(
std
::
string
expression
);
static
ParseToken
getNextToken
(
std
::
string
expression
,
int
start
);
static
ExpressionTreeNode
parsePrecedence
(
const
std
::
vector
<
ParseToken
>&
tokens
,
int
&
pos
,
int
precedence
);
static
Operation
*
getOperatorOperation
(
const
std
::
string
&
name
);
static
Operation
*
getFunctionOperation
(
const
std
::
string
&
name
,
int
arguments
);
};
}
// namespace Lepton
#endif
/*LEPTON_PARSER_H_*/
libraries/lepton/include/windowsIncludes.h
0 → 100644
View file @
259cb45a
#ifndef LEPTON_WINDOW_INCLUDE_H_
#define LEPTON_WINDOW_INCLUDE_H_
/*
* Shared libraries are messy in Visual Studio. We have to distinguish three
* cases:
* (1) this header is being used to build the Lepton shared library
* (dllexport)
* (2) this header is being used by a *client* of the Lepton shared
* library (dllimport)
* (3) we are building the Lepton static library, or the client is
* being compiled with the expectation of linking with the
* Lepton static library (nothing special needed)
* In the CMake script for building this library, we define one of the symbols
* Lepton_BUILDING_{SHARED|STATIC}_LIBRARY
* Client code normally has no special symbol defined, in which case we'll
* assume it wants to use the shared library. However, if the client defines
* the symbol LEPTON_USE_STATIC_LIBRARIES we'll suppress the dllimport so
* that the client code can be linked with static libraries. Note that
* the client symbol is not library dependent, while the library symbols
* affect only the Lepton library, meaning that other libraries can
* be clients of this one. However, we are assuming all-static or all-shared.
*/
#ifdef _MSC_VER
// We don't want to hear about how sprintf is "unsafe".
#pragma warning(disable:4996)
#if defined(LEPTON_BUILDING_SHARED_LIBRARY)
#define LEPTON_EXPORT __declspec(dllexport)
// Keep MS VC++ quiet about lack of dll export of private members.
#pragma warning(disable:4251)
#elif defined(LEPTON_BUILDING_STATIC_LIBRARY) || defined(LEPTON_USE_STATIC_LIBRARIES)
#define LEPTON_EXPORT
#else
#define LEPTON_EXPORT __declspec(dllimport) // i.e., a client of a shared library
#endif
#else
#define LEPTON_EXPORT // Linux, Mac
#endif
#endif // LEPTON_WINDOW_INCLUDE_H_
libraries/lepton/src/ExpressionTreeNode.cpp
0 → 100644
View file @
259cb45a
/* -------------------------------------------------------------------------- *
* Lepton *
* -------------------------------------------------------------------------- *
* This is part of the Lepton expression parser originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "ExpressionTreeNode.h"
#include "Exception.h"
#include "Operation.h"
using
namespace
Lepton
;
using
namespace
std
;
ExpressionTreeNode
::
ExpressionTreeNode
(
Operation
*
operation
,
const
vector
<
ExpressionTreeNode
>&
children
)
:
operation
(
operation
),
children
(
children
)
{
if
(
operation
->
getNumArguments
()
!=
children
.
size
())
throw
Exception
(
"Parse error: wrong number of arguments to function"
);
}
ExpressionTreeNode
::
ExpressionTreeNode
(
Operation
*
operation
,
const
ExpressionTreeNode
&
child1
,
const
ExpressionTreeNode
&
child2
)
:
operation
(
operation
)
{
children
.
push_back
(
child1
);
children
.
push_back
(
child2
);
if
(
operation
->
getNumArguments
()
!=
children
.
size
())
throw
Exception
(
"Parse error: wrong number of arguments to function"
);
}
ExpressionTreeNode
::
ExpressionTreeNode
(
Operation
*
operation
,
const
ExpressionTreeNode
&
child
)
:
operation
(
operation
)
{
children
.
push_back
(
child
);
if
(
operation
->
getNumArguments
()
!=
children
.
size
())
throw
Exception
(
"Parse error: wrong number of arguments to function"
);
}
ExpressionTreeNode
::
ExpressionTreeNode
(
Operation
*
operation
)
:
operation
(
operation
)
{
if
(
operation
->
getNumArguments
()
!=
children
.
size
())
throw
Exception
(
"Parse error: wrong number of arguments to function"
);
}
ExpressionTreeNode
::
ExpressionTreeNode
(
const
ExpressionTreeNode
&
node
)
:
operation
(
node
.
getOperation
().
clone
()),
children
(
node
.
getChildren
())
{
}
ExpressionTreeNode
::
ExpressionTreeNode
()
:
operation
(
NULL
)
{
}
ExpressionTreeNode
::~
ExpressionTreeNode
()
{
if
(
operation
!=
NULL
)
delete
operation
;
}
ExpressionTreeNode
&
ExpressionTreeNode
::
operator
=
(
const
ExpressionTreeNode
&
node
)
{
if
(
operation
!=
NULL
)
delete
operation
;
operation
=
node
.
getOperation
().
clone
();
children
=
node
.
getChildren
();
return
*
this
;
}
const
Operation
&
ExpressionTreeNode
::
getOperation
()
const
{
return
*
operation
;
}
const
vector
<
ExpressionTreeNode
>&
ExpressionTreeNode
::
getChildren
()
const
{
return
children
;
}
libraries/lepton/src/ParsedExpression.cpp
0 → 100644
View file @
259cb45a
/* -------------------------------------------------------------------------- *
* Lepton *
* -------------------------------------------------------------------------- *
* This is part of the Lepton expression parser originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "ParsedExpression.h"
#include "Operation.h"
#include <vector>
using
namespace
Lepton
;
using
namespace
std
;
ParsedExpression
::
ParsedExpression
(
ExpressionTreeNode
rootNode
)
:
rootNode
(
rootNode
)
{
}
const
ExpressionTreeNode
&
ParsedExpression
::
getRootNode
()
const
{
return
rootNode
;
}
double
ParsedExpression
::
evaluate
()
const
{
return
evaluate
(
rootNode
,
map
<
string
,
double
>
());
}
double
ParsedExpression
::
evaluate
(
const
std
::
map
<
std
::
string
,
double
>&
variables
)
const
{
return
evaluate
(
rootNode
,
variables
);
}
double
ParsedExpression
::
evaluate
(
const
ExpressionTreeNode
&
node
,
const
map
<
string
,
double
>&
variables
)
const
{
vector
<
double
>
args
(
node
.
getChildren
().
size
());
for
(
int
i
=
0
;
i
<
args
.
size
();
i
++
)
args
[
i
]
=
evaluate
(
node
.
getChildren
()[
i
],
variables
);
return
node
.
getOperation
().
evaluate
(
&
args
[
0
],
variables
);
}
libraries/lepton/src/Parser.cpp
0 → 100644
View file @
259cb45a
/* -------------------------------------------------------------------------- *
* Lepton *
* -------------------------------------------------------------------------- *
* This is part of the Lepton expression parser originating from *
* Simbios, the NIH National Center for Physics-Based Simulation of *
* Biological Structures at Stanford, funded under the NIH Roadmap for *
* Medical Research, grant U54 GM072970. See https://simtk.org. *
* *
* Portions copyright (c) 2009 Stanford University and the Authors. *
* Authors: Peter Eastman *
* Contributors: *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *
* THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE *
* USE OR OTHER DEALINGS IN THE SOFTWARE. *
* -------------------------------------------------------------------------- */
#include "Parser.h"
#include "Exception.h"
#include "ExpressionTreeNode.h"
#include "Operation.h"
#include "ParsedExpression.h"
#include <iostream>
using
namespace
Lepton
;
using
namespace
std
;
static
const
string
Digits
=
"0123456789"
;
static
const
string
Operators
=
"+-*/^"
;
static
const
bool
LeftAssociative
[]
=
{
true
,
true
,
true
,
true
,
false
};
static
const
int
Precedence
[]
=
{
0
,
0
,
1
,
1
,
3
};
static
const
Operation
::
Id
OperationId
[]
=
{
Operation
::
ADD
,
Operation
::
SUBTRACT
,
Operation
::
MULTIPLY
,
Operation
::
DIVIDE
,
Operation
::
POWER
};
class
Lepton
::
ParseToken
{
public:
enum
Type
{
Number
,
Operator
,
Variable
,
Function
,
LeftParen
,
RightParen
,
Comma
,
Whitespace
};
ParseToken
(
string
text
,
Type
type
)
:
text
(
text
),
type
(
type
)
{
}
const
string
&
getText
()
const
{
return
text
;
}
Type
getType
()
const
{
return
type
;
}
private:
string
text
;
Type
type
;
};
ParseToken
Parser
::
getNextToken
(
string
expression
,
int
start
)
{
char
c
=
expression
[
start
];
if
(
c
==
'('
)
return
ParseToken
(
"("
,
ParseToken
::
LeftParen
);
if
(
c
==
')'
)
return
ParseToken
(
")"
,
ParseToken
::
RightParen
);
if
(
c
==
','
)
return
ParseToken
(
","
,
ParseToken
::
Comma
);
if
(
Operators
.
find
(
c
)
!=
string
::
npos
)
return
ParseToken
(
string
(
1
,
c
),
ParseToken
::
Operator
);
if
(
c
==
' '
)
{
// White space
for
(
int
pos
=
start
+
1
;
pos
<
expression
.
size
();
pos
++
)
{
if
(
expression
[
pos
]
!=
' '
)
return
ParseToken
(
expression
.
substr
(
start
,
pos
-
start
),
ParseToken
::
Whitespace
);
}
return
ParseToken
(
expression
.
substr
(
start
,
string
::
npos
),
ParseToken
::
Whitespace
);
}
if
(
c
==
'.'
||
Digits
.
find
(
c
)
!=
string
::
npos
)
{
// A number
bool
foundDecimal
=
(
c
==
'.'
);
bool
foundExp
=
false
;
int
pos
;
for
(
pos
=
start
+
1
;
pos
<
expression
.
size
();
pos
++
)
{
c
=
expression
[
pos
];
if
(
Digits
.
find
(
c
)
!=
string
::
npos
)
continue
;
if
(
c
==
'.'
&&
!
foundDecimal
)
{
foundDecimal
=
true
;
continue
;
}
if
((
c
==
'e'
||
c
==
'E'
)
&&
!
foundExp
)
{
foundExp
=
true
;
if
(
pos
<
expression
.
size
()
-
1
&&
expression
[
pos
+
1
]
==
'-'
)
pos
++
;
continue
;
}
break
;
}
return
ParseToken
(
expression
.
substr
(
start
,
pos
-
start
),
ParseToken
::
Number
);
}
// A variable, function, or left parenthesis
for
(
int
pos
=
start
;
pos
<
expression
.
size
();
pos
++
)
{
c
=
expression
[
pos
];
if
(
c
==
'('
)
return
ParseToken
(
expression
.
substr
(
start
,
pos
-
start
+
1
),
ParseToken
::
Function
);
if
(
Operators
.
find
(
c
)
!=
string
::
npos
||
c
==
','
||
c
==
')'
)
return
ParseToken
(
expression
.
substr
(
start
,
pos
-
start
),
ParseToken
::
Variable
);
}
return
ParseToken
(
expression
.
substr
(
start
,
string
::
npos
),
ParseToken
::
Variable
);
}
vector
<
ParseToken
>
Parser
::
tokenize
(
string
expression
)
{
vector
<
ParseToken
>
tokens
;
int
pos
=
0
;
while
(
pos
<
expression
.
size
())
{
ParseToken
token
=
getNextToken
(
expression
,
pos
);
if
(
token
.
getType
()
!=
ParseToken
::
Whitespace
)
tokens
.
push_back
(
token
);
pos
+=
token
.
getText
().
size
();
}
return
tokens
;
}
ParsedExpression
Parser
::
parse
(
string
expression
)
{
vector
<
ParseToken
>
tokens
=
tokenize
(
expression
);
int
pos
=
0
;
ExpressionTreeNode
result
=
parsePrecedence
(
tokens
,
pos
,
0
);
if
(
pos
!=
tokens
.
size
())
throw
Exception
(
"Parse error: unexpected text at end of expression"
);
return
ParsedExpression
(
result
);
}
ExpressionTreeNode
Parser
::
parsePrecedence
(
const
vector
<
ParseToken
>&
tokens
,
int
&
pos
,
int
precedence
)
{
if
(
pos
==
tokens
.
size
())
throw
Exception
(
"Parse error: unexpected end of expression"
);
// Parse the next value (number, variable, function, parenthesized expression)
ParseToken
token
=
tokens
[
pos
];
ExpressionTreeNode
result
;
if
(
token
.
getType
()
==
ParseToken
::
Number
)
{
double
value
;
stringstream
(
token
.
getText
())
>>
value
;
result
=
ExpressionTreeNode
(
new
Operation
::
Constant
(
value
));
pos
++
;
}
else
if
(
token
.
getType
()
==
ParseToken
::
Variable
)
{
Operation
*
op
=
new
Operation
::
Variable
(
token
.
getText
());
result
=
ExpressionTreeNode
(
op
);
pos
++
;
}
else
if
(
token
.
getType
()
==
ParseToken
::
LeftParen
)
{
pos
++
;
result
=
parsePrecedence
(
tokens
,
pos
,
0
);
if
(
pos
==
tokens
.
size
()
||
tokens
[
pos
].
getType
()
!=
ParseToken
::
RightParen
)
throw
Exception
(
"Parse error: unbalanced parentheses"
);
pos
++
;
}
else
if
(
token
.
getType
()
==
ParseToken
::
Function
)
{
pos
++
;
vector
<
ExpressionTreeNode
>
args
;
bool
moreArgs
;
do
{
args
.
push_back
(
parsePrecedence
(
tokens
,
pos
,
0
));
moreArgs
=
(
pos
<
tokens
.
size
()
&&
tokens
[
pos
].
getType
()
==
ParseToken
::
Comma
);
if
(
moreArgs
)
pos
++
;
}
while
(
moreArgs
);
if
(
pos
==
tokens
.
size
()
||
tokens
[
pos
].
getType
()
!=
ParseToken
::
RightParen
)
throw
Exception
(
"Parse error: unbalanced parentheses"
);
pos
++
;
result
=
ExpressionTreeNode
(
getFunctionOperation
(
token
.
getText
(),
args
.
size
()),
args
);
}
else
if
(
token
.
getType
()
==
ParseToken
::
Operator
&&
token
.
getText
()
==
"-"
)
{
pos
++
;
ExpressionTreeNode
toNegate
=
parsePrecedence
(
tokens
,
pos
,
2
);
result
=
ExpressionTreeNode
(
new
Operation
::
Negate
(),
toNegate
);
}
else
throw
Exception
(
"Parse error: unexpected token"
);
// Now deal with the next binary operator.
while
(
pos
<
tokens
.
size
()
&&
tokens
[
pos
].
getType
()
==
ParseToken
::
Operator
)
{
token
=
tokens
[
pos
];
int
op
=
Operators
.
find
(
token
.
getText
());
int
opPrecedence
=
Precedence
[
op
];
if
(
opPrecedence
<
precedence
)
return
result
;
pos
++
;
ExpressionTreeNode
arg
=
parsePrecedence
(
tokens
,
pos
,
LeftAssociative
[
op
]
?
opPrecedence
+
1
:
opPrecedence
);
result
=
ExpressionTreeNode
(
getOperatorOperation
(
token
.
getText
()),
result
,
arg
);
}
return
result
;
}
Operation
*
Parser
::
getOperatorOperation
(
const
std
::
string
&
name
)
{
switch
(
OperationId
[
Operators
.
find
(
name
)])
{
case
Operation
::
ADD
:
return
new
Operation
::
Add
();
case
Operation
::
SUBTRACT
:
return
new
Operation
::
Subtract
();
case
Operation
::
MULTIPLY
:
return
new
Operation
::
Multiply
();
case
Operation
::
DIVIDE
:
return
new
Operation
::
Divide
();
case
Operation
::
POWER
:
return
new
Operation
::
Power
();
default:
throw
Exception
(
"Parse error: unknown operator"
);
}
}
Operation
*
Parser
::
getFunctionOperation
(
const
std
::
string
&
name
,
int
arguments
)
{
static
map
<
string
,
Operation
::
Id
>
opMap
;
if
(
opMap
.
size
()
==
0
)
{
opMap
[
"sqrt"
]
=
Operation
::
SQRT
;
opMap
[
"exp"
]
=
Operation
::
EXP
;
opMap
[
"log"
]
=
Operation
::
LOG
;
opMap
[
"sin"
]
=
Operation
::
SIN
;
opMap
[
"cos"
]
=
Operation
::
COS
;
opMap
[
"sec"
]
=
Operation
::
SEC
;
opMap
[
"csc"
]
=
Operation
::
CSC
;
opMap
[
"tan"
]
=
Operation
::
TAN
;
opMap
[
"cot"
]
=
Operation
::
COT
;
opMap
[
"asin"
]
=
Operation
::
ASIN
;
opMap
[
"acos"
]
=
Operation
::
ACOS
;
opMap
[
"atan"
]
=
Operation
::
ATAN
;
}
string
trimmed
=
name
.
substr
(
0
,
name
.
size
()
-
1
);
map
<
string
,
Operation
::
Id
>::
const_iterator
iter
=
opMap
.
find
(
trimmed
);
if
(
iter
==
opMap
.
end
())
return
new
Operation
::
Custom
(
trimmed
,
arguments
);
switch
(
iter
->
second
)
{
case
Operation
::
SQRT
:
return
new
Operation
::
Sqrt
();
case
Operation
::
EXP
:
return
new
Operation
::
Exp
();
case
Operation
::
LOG
:
return
new
Operation
::
Log
();
case
Operation
::
SIN
:
return
new
Operation
::
Sin
();
case
Operation
::
COS
:
return
new
Operation
::
Cos
();
case
Operation
::
SEC
:
return
new
Operation
::
Sec
();
case
Operation
::
CSC
:
return
new
Operation
::
Csc
();
case
Operation
::
TAN
:
return
new
Operation
::
Tan
();
case
Operation
::
COT
:
return
new
Operation
::
Cot
();
case
Operation
::
ASIN
:
return
new
Operation
::
Asin
();
case
Operation
::
ACOS
:
return
new
Operation
::
Acos
();
case
Operation
::
ATAN
:
return
new
Operation
::
Atan
();
default:
throw
Exception
(
"Parse error: unknown function"
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment