3

Myself and a few others have been tasked with creating a Truth Table Generator for our first year project. We have a vast majority of the work done, save for a few things, most important of which being the function that actually converts statements (Ex: p V q) into boolean truth values.

Is it possible to convert a string statement with proper c++ argument syntax, such as "(p || !q)" (p and q being pre-defined variables with respective values) directly into a condition?

We've considered the route of many conditional statements based on what we can find via string analysis and operating on the variables based on findings, but I was wondering if there was a much more efficient way to actually code this. The code is designed to take pretty much any input for a truth table statement, convert it into proper c++ syntax, and separate the statement into components. That being said, there are quite a few options to account for if we were to do this via finding certain elements and operating on them with if-then or switch statements. If there is a more efficient route, I am open to suggestions and welcome any criticism of our process.

As a visual demonstration, this is what we were thinking of:

bool p=1, q=0;
string test= "(!p || q)"; // would supposedly return 0 if analyzed as a conditional statement

cout << endl << "Truth Table Generator Test" << endl;
cout << "p = " << p << endl << "q = " << q << endl;
cout << test << " = " << truthVal(test) // Used to signify the conversion from string to condition

Supposed output:


Truth Table Generator Test
p = 1
q = 0
(!p || q) = 0
  • 1
    If you used a C string (const char*) you could parse it with templates to generate C++ code. Quite an undertaking. Can't do that with a string. At least currently. You might also look at Jason Turner's ChaiScript for ideas. – doug Apr 20 '19 at 21:44
  • 3
    No. This is not possible. You need to implement a parser, which I strongly suspect is the whole point of this project :-) – Nikos C. Apr 20 '19 at 21:54
  • 2
    When you say you want to convert your string to "proper C++ syntax", does that mean you intend to write actual C++ code somewhere? If so, where exactly do you imagine this code will be written and how is it going to be compiled? I assume this is supposed to work with a string given at runtime rather than one specified a compiletime? If the latter were to be the case, you might as well just write the stuff in "proper C++ syntax" directly!? Sounds like you're going to have to write a parser. Unfortunately, that means the statement "We have a vast majority of the work done" is probably false… ;) – Michael Kenzel Apr 20 '19 at 21:54
  • 2
    Of course, if the string is already given in a way that would be proper C++ syntax when placed in a C++ program, rather than parse and evaluate the string yourself, you could just generate C++ code that does what you'd want it to do with the given string put directly somewhere into that C++ code, invoke a C++ compiler to generate a binary, and then run that binary to get the result… – Michael Kenzel Apr 20 '19 at 21:58
  • 2
    C++ is not typically implemented as a “dynamic” or “scripting” language that has an `eval` function to interpret a string as if it had been written in the source nearby. – Davis Herring Apr 20 '19 at 22:26
  • "We have a vast majority of the work done" What have you actually done? It sounds like you're saying "I'm almost done with my truth table generator. I just need to make the part that generates the truth tables". – Indiana Kernick Apr 21 '19 at 00:11
  • This might help for retrieving the variable names as strings from the compiled code - [c++ names via typeid(var).name() and demangling](https://stackoverflow.com/questions/6622962/generic-way-to-print-out-variable-name-in-c) – estabroo Apr 21 '19 at 14:43
  • I suppose I should've specified "Vast majority" as "Everything except the actual parser". There were several other elements to this project not specifically related to this portion of the code, but I realize that this is the most complicated part and shouldn't be underselling it, so I apologize on that end. Yes, the string provided is simply used as an example, as the actual string for analysis is taken at runtime and undergoes a series of conversions and validations before being sent to the truthVal function for parsing. – Garrett Griffiths Apr 22 '19 at 00:56
  • @Michael Kenzel could you elaborate on what you mean with your solution? The string is not pre-provided, but it is converted into proper c++ argument syntax (The user is afforded several options that are converted before display). Is your solution still possible if this string is placed into a file? I'm not terribly experienced with C++ as this is my first year using it. – Garrett Griffiths Apr 22 '19 at 00:57
  • I'm afraid I have to honestly say that, based on the description in your question above, I'm really not sure what your task actually is. All I can say is that I have a feeling that the task must be either much simpler than it appears to me, or much harder than it appears to you. I have no idea what "proper c++ argument syntax" is supposed to mean in this context. I think what we'll need to be able to even attempt to help at all, is a proper description of what *exactly* your input looks like and what *exactly* you're supposed to do with it. – Michael Kenzel Apr 22 '19 at 03:02

2 Answers2

2

No. C++ at run time has zero access to compile time variable names, outside of some symbol mangling in some compilers.

Even "constexpr runtime" has no access to it.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
2

It's not possible to do in C++ when called like this:

cout << test << " = " << truthVal(test) 

However, rearranging slightly, it becomes possible:

bool p=1, q=0;
char test[]= "(!p || q)"; // would supposedly return 0 if analyzed as a conditional statement

cout << endl << "Truth Table Generator Test" << endl;
cout << "p = " << p << endl << "q = " << q << endl;
cout << test << " = " << truthVal(test, 'p', p, 'q', q)

The reason this is possible is because of 2 critical changes. test is now a constant char array. As such it can be parsed with template metaprogramming. Note that different test arrays can produce unique function instantiations. This is done, for instance, in Boost's printf library. Since template metaprogramming is Turing complete, an interpreter can be implemented that will test the p and q, or any extra number of variables at run time. You also need to define a convention to link the variables passed with those in the char array. I have done this here by supplying the variable name as a char but it could be done in other ways. You can even do type checking on the passed variables. But you cannot access variables that aren't passed in the function call. Essentially, you are implementing a compile time interpreter.

However, the template metaprogramming is a significant task. But doable.

doug
  • 3,840
  • 1
  • 14
  • 18
  • As far as my understanding of what the question is trying to ask goes, the input the code should operate on is presented at run time, not at compile time. I'm not sure how template metaprogramming is supposed to help here. Even if it would, your answer neither explains how it could actually be done nor at least links to a resource that would explain how it could be done. It merely states that, in theory, it could be done. Given the fact that this is a homework assignment, it's kinda safe to assume that the task can actually be solved. So, at least to me, this doesn't seem all that helpful… – Michael Kenzel Apr 22 '19 at 02:53
  • @MichaelKenzel The OP asked: "but I was wondering if there was a much more efficient way to actually code this" template meta programming is the most efficient way to do this. I provided an approach that would allow it since it is not possible with or without template programming in the original form. But I'm not going to write the code which is a bit outside the scope of questions here. – doug Apr 22 '19 at 03:17