Using this https://github.com/antlr/grammars-v4/tree/master/cpp antlr grammar Im trying to parse C++ code. Below is the same visitor class I'm using, I don't have much visitor function implemented,
#include <iostream>
#include <antlr4-runtime.h>
#include "parser/CPP14Lexer.h"
#include "parser/CPP14BaseVisitor.h"
#include "parser/CPP14Parser.h"
#include "parser/CPP14Visitor.h"
class TREEVisitor : public CPP14BaseVisitor {
public:
virtual antlrcpp::Any TREEVisitor::visitAdditiveExpression(
CPP14Parser::AdditiveExpressionContext *ctx) override
{
std::cout << "AddExpr : " << ctx->getText() << std::endl;
std::vector<CPP14Parser::MultiplicativeExpressionContext *> mulpExprCtx =
ctx->multiplicativeExpression();
for (CPP14Parser::MultiplicativeExpressionContext *mulpExprLp : mulpExprCtx)
{
std::vector<CPP14Parser::PointerMemberExpressionContext *> ptrMbrExprCtx =
mulpExprLp->pointerMemberExpression();
// ptrMbrExprCtx->pointerMemberExpression()->castExpression()->unaryExpression();
// Different parts of an expression
for (CPP14Parser::PointerMemberExpressionContext *ptrMbrExprLp : ptrMbrExprCtx)
{
std::cout << "=> " << ptrMbrExprLp->getText() << std::endl;
}
}
return visitChildren(ctx);
}
};
int main(int argc, char *argv[]) {
std::ifstream stream;
stream.open(argv[1]);
antlr4::ANTLRInputStream input(stream);
CPP14Lexer lexer(&input);
antlr4::CommonTokenStream tokens(&lexer);
CPP14Parser parser(&tokens);
antlr4::tree::ParseTree *tree = parser.translationunit();
// Visitor
auto *visitor = new TREEVisitor();
visitor->visit(tree);
return 0;
}
Im trying to parse the following C++ code,
int ii = a + b - getLength() * 10 / 1;
What I'm trying to achieve here is to get all of the variables that are used to initilize the variable i and their signs. Something like below, where i can relate each sign to the values/variables(for example to know that + as after a.
a
+
b
-
getLength()
*
10
/
1;
So far I can only get an output as follow,
AddExpr : a+b-c*10/1
=> a
=> b
=> getLength()
=> 10
=> 1
I don't seem to be able to get the signs between each operation.
I seem to have something related to the signs in that equation, I had only Star and Mod.
tree::TerminalNode* startTn = mulpExprLp->Star();
So I tried to change the grammar file to get other signs as well. While that gave me the signs in that equation but again... I wasn't ablel to know the position of each sign in the equation.
multiplicativeExpression:
pointerMemberExpression (
(Star | Div | Mod | Plus | Minus) pointerMemberExpression
)*;
I hope I could describe the problem clearly. I basically want to read the each part of an equation and know what is the position of each sign.
Thanks,
Alex
It looks like you need a better understanding of the structure of your parse tree.
I would suggest going back to the original grammar (there are many problems with your multiplcativeExpression, mostly around it not building a proper parse tree.
Viewing the graphical version of your parse tree should be quite useful. This page gives a brief intro to setting up a grun alias to use TestRig. It’s usually a good idea to “play around” a bit with grun and various input to gain a better understanding of what ANTLR produces (token streams, parse trees, etc.) for your grammar.
Take a look at the documentation and how to run the TestRig utility with the -gui command line option. This will give you a graphical representation of your parse tree. Your immediate issue is that, since you only have a visitor for additiveExpression, it won’t include the sub tree for the mutiplicativeExpression that will hold the structure for multiplication and division.
Also, since you’re not finding the operations you need to take a closer look at the cpp14parser::AdditiveExpressionContext generated for your additiveExpression. The operator(s) should be available at one of the indices of your children nodes (the rule is written to allow multiple addition/subtraction in a single context, so they’ll probably be available in some list/array structure (sorry, not intimately familiar with what ANTLR generates for C++)
BTW, you may find that, for your purposes, a listener is easier to use than a visitor. With Listeners a ParseTreeWalker takes care of walking the tree and calling back to your code as nodes are encountered. With Visitors, it’s up to you to navigate the parse Tree (they can be useful when you need more flexibility, and a bit easier to handle things if you want a value returned from visiting a node, but I find Listeners much simpler for most use cases)
Related
So I tried using code from another post around here to see if I could use it, it was a code meant to utilize a potentiometer to move a servo motor, but when I attempted to compile it is gave the error above saying No operator "=" matches these operands in "Servo_Project.cpp". How do I go about fixing this error?
Just in case ill say this, the boards I was trying to compile the code were a NUCLEO-L476RG, the board from the post I mentioned utilized Nucleo L496ZG board and a Tower Pro Micro Servo 9G.
#include "mbed.h"
#include "Servo.h"
Servo myservo(D6);
AnalogOut MyPot(A0);
int main() {
float PotReading;
PotReading = MyPot.read();
while(1) {
for(int i=0; i<100; i++) {
myservo = (i/100);
wait(0.01);
}
}
}
This line:
myservo = (i/100);
Is wrong in a couple of ways. First, i/100 will always be zero - integer division truncates in C++. Second, there's not an = operator that allows an integer value to be assigned to a Servo object. YOu need to invoke some kind of Servo method instead, likely write().
myservo.write(SOMETHING);
The SOMETHING should be the position or speed of the servo you're trying to get working. See the Servo class reference for an explanation. Your code tries to use fractions from 0-1 and thatvisn't going to work - the Servo wants a position/speed between 0 and 180.
You should look in the Servo.h header to see what member functions and operators are implemented.
Assuming what you are using is this, it does have:
Servo& operator= (float percent);
Although note that the parameter is float and you are passing an int (the parameter is also in the range 0.0 to 1.0 - so not "percent" as its name suggests - so be wary, both the documentation and the naming are poor). You should have:
myservo = i/100.0f;
However, even though i / 100 would produce zero for all i in the loop, that does not explain the error, since an implicit cast should be possible - even if clearly undesirable. You should look in the actual header you are using to see if the operator= is declared - possibly you have the wrong file or a different version or just an entirely different implementation that happens to use teh same name.
I also notice that if you look in the header, there is no documentation mark-up for this function and the Servo& operator= (Servo& rhs); member is not documented at all - hence the confusing automatically generated "Shorthand for the write and read functions." on the Servo doc page when the function shown is only one of those things. It is possible it has been removed from your version.
Given that the documentation is incomplete and that the operator= looks like an after thought, the simplest solution is to use the read() / write() members directly in any case. Or implement your own Servo class - it appears to be only a thin wrapper/facade of the PwmOut class in any case. Since that is actually part of mbed rather than user contributed code of unknown quality, you may be on firmer ground.
This code doesn't repeat if I answer a negative number like "-1.01". How can I make it loop so that it will ask again for c?
#include <stdio.h>
main()
{
float c;
do {
printf("O hai! How much change is owed? ");
scanf("%.2f", &c);
} while (c < 0.0);
return(0);
}
The format strings for scanf are subtly different than those for printf. You are only allowed to have (as per C11 7.21.6.2 The fscanf function /3):
an optional assignment-suppressing character *.
an optional decimal integer greater than zero that specifies the maximum field width (in characters).
an optional length modifier that specifies the size of the receiving object.
a conversion specifier character that specifies the type of conversion to be applied.
Hence your format specifier becomes illegal the instant it finds the . character, which is not one of the valid options. As per /13 of that C11 section listed above:
If a conversion specification is invalid, the behaviour is undefined.
For input, you're better off using the most basic format strings so that the format is not too restrictive. A good rule of thumb in I/O is:
Be liberal in what you accept, specific in what you generate.
So, the code is better written as follows, including what a lot of people ignore, the possibility that the scanf itself may fail, resulting in an infinite loop:
#include <stdio.h>
int main (void) {
float c;
do {
printf ("O hai! How much change is owed? ");
if (scanf ("%f", &c) != 1) {
puts ("Error getting a float.");
break;
}
} while (c < 0.0f);
return 0;
}
If you're after a more general purpose input solution, where you want to allow the user to input anything, take care of buffer overflow, handle prompting and so on, every C developer eventually comes up with the idea that the standard ways of getting input all have deficiencies. So they generally go write their own so as to get more control.
For example, here's one that provides all that functionality and more.
Once you have the user's input as a string, you can examine and play with it as much as you like, including doing anything you would have done with scanf, by using sscanf instead (and being able to go back and do it again and again if initial passes over the data are unsuccessful).
scanf("%.2f", &c );
// ^^ <- This seems unnecessary here.
Please stick with the basics.
scanf("%f", &c);
If you want to limit your input to 2 digits,
scanf("%2f", &c);
So I am very confused about the find_conflicts function in CGAL. I thought I knew std::pair, and I thought I knew what was going on in find_conflicts(), but for the life of me, I am not sure how to access the results. I thought that the iterator that is passed to find_conflicts would be enough to then access the values directly. (i.e., I want to get at those facets that I put in the "vector facets,") and it appears as if I'm doing that because I can successfully
typedef std::pair<std::vector<Facet>, std::vector<Cell> > FacetAndCell;
* * *
Cell_handle cell = T.locate(curr_point);
std::vector<Facet> facets;
T.find_conflicts(curr_point, cell, std::back_inserter(facets), CGAL::Emptyset_iterator());
CGAL::First_of_pair_property_map<FacetAndCell> my_p_map();
Delaunay::Finite_facets_iterator ff_iter;
std::vector<Facet>::iterator facet_iter;
// Here, what I'm trying to achieve is figuring out which of the facets
// in conflict are finite. I had wanted to use some kind of test like
// "is_infinite()" on the facet at hand, but this isn't available for
// a facet out of context of the triangulation it's part of.
for(facet_iter = facets.begin(); facet_iter != facets.end(); facet_iter++){
for(ff_iter = T.finite_facets_begin(); ff_iter != T.finite_facets_end(); ff_iter++){
// Since I get an error that facet_iter is actually of type pair, I thought this would work, but it doesn't.
// ERROR!
cout << facet_iter->first << endl;
// This works, which is what led me to believe I was comparing one facet to another facet.
/*
if(*facet_iter == *ff_iter){
cout << "Finite facet!" << endl;
break;
}*/
}
}
In summary:
1) Overall, I want to know which facets from the result of find_conflicts() were finite. If there is an easier way to do this, feel free to let me know.
2) Otherwise, the more specific problem here is that I need to get at that vector of facets that results from find_conflicts() and then get at the vertices of each facet. Am I supposed to be working with the returned "pair" of cells and facets or can I access the vector directly, like I'm trying to do?
Help, please, thanks.
For finiteness testing, use is_infinite(). See http://doc.cgal.org/latest/Triangulation_3/classCGAL_1_1Triangulation__3.html#af024721d3ae4b9327ffe442fb828935c
Otherwise, maybe you are confused because the Facet type is a typedef to a pair (unfortunately).
PS: alternatively, you can use Marc Glisse's suggestion in your other question (using locate(midpoint(p, sphere center))). It might be easier. CGAL Using Locate() to Find Cell on Triangulation Surface
I am trying use ANTLR to analyse a large set of code using full Java grammar. Since ANTLR needs to open all the source files and scan them, I am wondering if it can also return lines of code.
I checked API for Lexer and Parser, it seems they do not return LoC. Is it easy to instrument the grammar rule a bit to get LoC? The full Java rule is complicated, I don't really want to mess a large part of it.
If you have an existing ANTLR grammar, and want to count certain things during parsing, you could do something like this:
grammar ExistingGrammar;
// ...
#parser::members {
public int loc = 0;
}
// ...
someParserRule
: SomeLexerRule someOtherParserRule {loc++;}
;
// ...
So, whenever your oparser encounters a someParserRule, you increase the loc by one by placing {loc++;} after (or before) the rule.
So, whatever your definition of a line of code is, simply place {loc++;} in the rule to increase the counter. Be careful not to increase it twice:
statement
: someParserRule {loc++;}
| // ...
;
someParserRule
: SomeLexerRule someOtherParserRule {loc++;}
;
EDIT
I just noticed that in the title of your question you asked if this can be done during lexing. That won't be possible. Let's say a LoC would always end with a ';'. During lexing, you wouldn't be able to make a distinction between a ';' after, say, an assignment (which is a single LoC), and the 2 ';'s inside a for(int i = 0; i < n; i++) { ... } statement (which wouldn't be 2 LoC).
In the C target the data structure ANTLR3_INPUT_STREAM has a getLine() function which returns the current line from the input stream. It seems the Java version of this is CharStream.getLine(). You should be able to call this at any time and get the current line in the input stream.
Use a visitor to visit the CompilationUnit context, then context.stop.getLine() will give you the last line number of the compilation unit context.
#Override public Integer visitCompilationUnit(#NotNull JAVAParser.CompilationUnitContext ctx) {
return ctx.stop.getLine();
}
I am using PIC18F2550. Programming it with C18 language.
I need a function that converts double to string like below:
void dtoa( char *szString, // Output string
double dbDouble, // Input number
unsigned char ucFPlaces) // Number of digits in the resulting fractional part
{
// ??????????????
}
To be called like this in the main program:
void main (void)
{
// ...
double dbNumber = 123.45678;
char szText[9];
dtoa(szText, dbNumber, 3); // szText becomes "123.456" or rounded to "123.457"
// ...
}
So write one!
5mins, a bit of graph paper and a coffee is all it should take.
In fact it's a good interview question
Tiny printf might work for you: http://www.sparetimelabs.com/tinyprintf/index.html
Generally, the Newlib C library (BSD license, from RedHat, part of Cygwin as well as used in many many "bare-metal" embedded-systems compilers) is a good place to start for usefuls sources for things that would be in the standard C library.
The Newlib dtoa.c sources are in the src/newlib/libc/stdlib subdirectory of the source tree:
Online source browser: http://sourceware.org/cgi-bin/cvsweb.cgi/src/newlib/libc/stdlib/?cvsroot=src#dirlist
Direct link to the current version of the dtoa.c file: http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/src/newlib/libc/stdlib/dtoa.c?rev=1.5&content-type=text/plain&cvsroot=src
The file is going to be a little odd, in that Newlib uses some odd macros for the function declarations, but should be straightforward to adapt -- and, being BSD-licensed, you can pretty much do whatever you want with it if you keep the copyright notice on it.