I would like to create simple C++ calculator using bison and flex. Please note I'm new to the creating parsers. I already found few examples in bison/flex but they were all written in C.
My goal is to create C++ code, where classes would contain nodes of values, operations, funcs - to create AST (evaluation would be done just after creating whole AST - starting from the root and going forward).
For example:
my_var = sqrt(9 ** 2 - 32) + 4 - 20 / 5
my_var * 3
Would be parsed as:
=
/ \
my_var +
/ \
sqrt -
| / \
- 4 /
/ \ / \
** 32 20 5
/ \
9 2
and the second AST would look like:
*
/ \
my_var 3
Then following pseudocode reflects AST:
ast_root = create_node('=', new_variable("my_var"), exp)
where exp is:
exp = create_node(OPERATOR, val1, val2)
but NOT like this:
$$ = $1 OPERATOR $3
because this way I directly get value of operation instead of creation the Node.
I believe the Node should contain type (of operation), val1 (Node), val2 (Node). In some cases val2 would be NULL, like above mentioned sqrt which takes in the end one argument. Right?
It will be nice if you can propose me C++ skeleton (without evaluation) for above described problem (including *.y file creating AST) to help me understand the way of creating/holding Nodes in AST. Code can be snipped, just to let me get the idea.
I'll also be grateful if you point me to an existing (possibly simple) example if you know any.
Thank you all for your time and assistance!
http://www.progtools.org/compilers/tutorials/cxx_and_bison/cxx_and_bison.html is a mini-tutorial which should create something like what you want.
Related
Using sympy how do I keep fractions separate from variables
Mul(Fraction(3,5), Pow(K, Integer(2)))
2
3⋅K
────
5
to
3 2
─ K
5
I know this simplified version is not too bad, but when i have really big equations, it gets messy
I'm not very familiar with pretty printing or LaTeX printing but I managed to come up with something. Put UnevaluatedExpr in each of the arguments of Mul:
from sympy import *
from fractions import Fraction
K = symbols("K")
expr1 = Mul(UnevaluatedExpr(Fraction(3,5)), UnevaluatedExpr(Pow(K, Integer(2))))
expr2 = Mul(UnevaluatedExpr(pi/5), UnevaluatedExpr(Pow(K, Integer(2))))
expr3 = ((UnevaluatedExpr(S(1)*3123456789/512345679) * UnevaluatedExpr(Pow(K, Integer(2)))))
pprint(expr1)
pprint(expr2)
pprint(expr3)
Produces:
2
3/5⋅K
π 2
─⋅K
5
1041152263 2
──────────⋅K
170781893
I couldn't find a way to make it print a stacked fraction for the slashed fraction 3/5. Longer fractions seem to work though. If you are printing in LaTeX however, the documentation suggests something like latex(expr1, fold_frac_powers=False) to correct this.
Too bad I couldn't find an elegant solution like putting init_printing(div_stack_symbols=False) at the top of the document.
To elaborate on Maelstrom's Answer, you need to do 2 things to make this work like you want:
Create the separate fraction you want as its own expression.
Prevent the numerator or denominator from being modified when the expression is combined with other expressions.
What Maelstrom showed will work, but it's much more complicated than what's actually needed. Here's a much cleaner solution:
from sympy import *
K = symbols("K")
# Step 1: make the fraction
# This seems to be a weird workaround to prevent fractions from being broken
# apart. See the note after this code block.
lh_frac = UnevaluatedExpr(3) / 5
# Step 2: prevent the fraction from being modified
# Creating a new multiplication expression will normally modify the involved
# expressions as sympy sees fit. Setting evaluate to False prevents that.
expr = Mul(lh_frac , Pow(K, 2), evaluate=False)
pprint(expr)
gives:
3 2
-*K
5
Important Note:
Doing lh_frac = UnevaluatedExpr(3) / 5 is not how fractions involving 2 literal numbers should typically be created. Normally, you would do:
lh_frac = Rational(3, 5)
as shown in the sympy docs. However, that gives undesirable output for our use case right now:
2
3*K
----
5
This outcome is surprising to me; setting evaluate to False inside Mul should be sufficient to do what we want. I have an open question about this.
In fact, I'm trying to implement the very simple model formulation:
min sum_i(y_i*f_i) + sum_i(sum_j(x_ij*c_ij))
s.t. sum_i(x_ij) = 1 for all j
x_ij <= y_i for all i,j
x_ij, y_i are binary
But I simply cannot figure out how the Python API works. They suggest creating variables like this:
model.variables.add(obj = fixedcost,
lb = [0] * num_facilities,
ub = [1] * num_facilities,
types = ["B"] * num_facilities)
# Create one binary variable for each facility/client pair. The variables
# model whether a client is served by a facility.
for c in range(num_clients):
model.variables.add(obj = cost[c],
lb = [0] * num_facilities,
ub = [1] * num_facilities,
types = ["B"] * num_facilities)
# Create corresponding indices for later use
supply = []
for c in range(num_clients):
supply.append([])
for f in range(num_facilities):
supply[c].append((c+1)*(num_facilities)+f)
# Constraint no. 1:
for c in range(num_clients):
assignment_constraint = cplex.SparsePair(ind = [supply[c][f] for f in \
range(num_facilities)],
val = [1] * num_facilities)
model.linear_constraints.add(lin_expr = [assignment_constraint],
senses = ["L"],
rhs = [1])
For this constraints I have no idea how the variables from above are refered to since it only mentions an auxiliary list of lists. Can anyone explain to me how that should work? The problem is easy, I also know how to do it in C++ but the Python API is a closed book to me.
The problem is the uncapacitated facility location problem and I want to adapt the example file facility.py
EDIT: One idea for constraint no.2 is to create one-dimensional vectors and use vector addition to create the final constraint. But that tells me that this is an unsupported operand for SparsePairs
for f in range(num_facilities):
index = [f]
value = [-1.0]
for c in range(num_clients):
open_constraint = cplex.SparsePair(ind = index, val = value) + cplex.SparsePair(ind = [supply[c][f]], val = [1.0])
model.linear_constraints.add(lin_expr=[open_constraint],
senses = ["L"],
rhs = [0])
The Python API is closer to the C Callable Library in nature than the C++/Concert API. Variables are indexed from 0 to model.variables.get_num() - 1 and can be referred to by index, for example, when creating constraints. They can also be referred to by name (the add method has an optional names argument). See the documentation for the VariablesInterface here (this is for version 12.5.1, which I believe you are using, given your previous post).
It may help to start looking at the most simple examples like lpex1.py (and read the comments). Finally, I highly recommend playing with the Python API from the interactive Python prompt (aka the REPL). You can read the help there and type things in to see what they do.
You also might want to take a look at the docplex package. This is a modeling layer built on top of the CPLEX Python API (or which can solve on the cloud if you don't have a local installation of CPLEX installed).
I would like to estimate the following function by nonlinear least squares using Stata:
I am testing the results of another papper and would like to use Stata since it is the same software/solver as they used in the paper I am replicating and because it should be easier to do than using GAMS, for example.
My problem is that I cannot find any way to write out the sum part of the equation above. In my data all i's have are a single observation with the values for the j's in separate variables. I could write out the whole expression in the following manner (for three observations/i's):
nl (ln_wage = {alpha0} + {alpha0}*log( ((S_over_H_1)^{alpha2})*exp({alpha3}*distance_1) + ((S_over_H_2)^{alpha2})*exp({alpha3}*distance_2) + ((S_over_H_1)^{alpha2})*exp({alpha3}*distance_1) ))
Is there a simple way to tell Stata to sum over an expression/variables for a given set of numbers, like in GAMS where you can write:
lnwage(i) = alpha0 + alpha1*ln(sum((j), power(S_over_H(i,j),alpha2) * exp(alpha3 * distance(i,j))))
There is no direct equivalent in Stata of the GAMS notation you cite, but you could do this
forval j = 1/3 {
local call `call' S_over_H_`j'^({alpha2}) * exp({alpha3} * distance_`j')
}
nl (ln_wage = {alpha0} + {alpha1} * ln(`call')
P.S. please explain what GAMS is.
Scala noob i'm afraid:
I have the following declared class variable which will the objects I read from the database:
val options = mutable.LinkedList[DivisionSelectOption]()
I then use JPA to get a List of all rows from a table:
val divisionOptions = em.createNamedQuery("SelectOption.all", classOf[SelectOption]) getResultList
/* Wrap java List in Scala List */
val wrappedOptions = JListWrapper.apply(divisionOptions)
/* Store the wrappedOptions in the class variable */
options += wrappedOptions
However, the last line has an error:
Type Expected: String, actual JListWrapper[SelectOption]
Can anyone help with what I am doing wrong? I'm just trying to populate the options object with the result of the DB call.
Thanks
What (probably) is happening is that a JlistWrapper[SelectOption] isn't a DivisionSelectOption, so the method += isn't applicable to it. That being the case, it is trying other stuff, and giving a final error on this:
options = options + wrappedOptions
That is a rewriting Scala can do to make things like x += 1 work for var x. The + method is present on all objects, but it takes a String as parameter -- that's so one can write stuff like options + ":" and have that work as in Java. But since wrappedOptions isn't a String, it complains.
Roundabout and confusing, I know, and even Odersky regrets his decision with regards to +. Let that be a lesson: if you thing of adding a method to Any, think really hard before doing it.
I need to parse input text file as custom language that i should interpret it's commands (line by line) and execute it, that's the input i should expect:
#Some variables
myInt = 2
myFloat = 2.5
myString = “Hello”
#Lists
myList = (myInt, myFloat, myInt + myFloat)
myOtherList = (myFloat + myFloat, myInt+ myInt)
subList = myList[:1]
completeList = myList + myOtherList + subList
#This should have no effect (it is ok if it is being calculated)
2+4
#Now some printing
print(myString)
print(“World”)
print(completeList)
print(completeList[3])
#Some syntax errors
b = “hello, this string is not enclosed right
c = myString + completeList
d = myInt + SOME_VARIABLE_I_HAVENT_DEFINED_YET
#First string to appear makes everything a string
print(1 + 2 + 15.5 + 2.2 + “Hi” + 3 + 4 + 6)
print(1 + 2 + 15.5 + 2.2 + 3 + 4 + 6 + “hi”)
print((1,2))
So I already have a first checking function, now I know when it's print/assign/comment/bad syntax command or whatever. I now should parse what inside the print function and the assign commands, I should ignore white spaces, they also might not be as delimiters to count on.
Please guide me a bit, what string functions i should use and how in order to to make it work, I mean how you can cut to tokens and also identify the mathematical signs? I'm guessing it should use some stack to follow the parentheses of the list type and quotation signs, no? Any general and more detailed information will be appreciated, thanks(:
p.s.
That's the output for this code:
Hello
World
(2, 2.5, 4.5, 5.0, 4, 2, 2.5)
5.0
InvalidSyntax : b = “hello, this string is not enclosed right
InvalidSyntax : c = myString + completeList
UndefinedVariableName : SOME_VARIABLE_I_HAVENT_DEFINED_YET
20.7Hi346
33.7hi
(1,2)
I already have all the overloading operators for what I need, I only need to parse it right and send it to my already built functions.
So you haven't had a chance to read the Dragon Book...
How do you think about embedding Lua or Python interpreter into your product, instead of inventing your own language? They are more common and full-fledged programming languages. Moreover Google will help you find lots of tutorials on how to embed them, such as:
http://docs.python.org/extending/embedding.html
http://www.ibm.com/developerworks/linux/library/l-embed-lua/
The disadvantage of inventing your own language is that: even after you successfully parsed your own language, you need to define semantics for it. Parsing only deals with the syntax, which is a different thing from the semantics. I don't know your situation but both of them usually require too long time to learn for just a single software project.
As for Boost Spirit: I don't recommend to use it which was written by people who just wanted to show their smartness by writing it (but in the end showed their ignorance about what is practical software design.)
A wonderful C++ library exists for that : SPIRIT