I want to delete statements,like "#include" in C source file. Therefore how can I match such statements using clang AST matchers or using clang's provided API for C++ ?
Unfortunately, it's not possible because #includes are preprocessor directives and not statements. They are not part of the AST and that's why AST matchers are of no use.
You might want to use clang's Preprocessor mechanism of callbacks. First you need define your callback, which should be an instance of PPCallbacks, override method InclusionDirective, and register your callback using addPPCallbacks.
I hope this information will be helpful to you in solving your problem. Happy hacking with Clang!
Related
I need to analyse kotlin files code, to detect the keyword "data" and "?".
The issue is I don't find any libs like JavaParser.
I don't need powerfull tools, just something who return me the number of the lines.
Any idea?
I use antlr4 to do it. And I create an open source lib:
https://github.com/sarahBuisson/kotlin-parser
<dependency
<groupId>com.github.sarahbuisson</groupId>
<artifactId>kotlin-parser</artifactId>
</dependency>
Besides the tools mentioned in other answers, here is another one someone may find useful:
https://github.com/kotlinx/ast
You would need to either find a Kotlin parser, or write your own.
For this subset of parsing you may be able to cheat, as data is a keyword, so if you see data with non letters each side you know it is the keyword.
For ?, it depends which meaning you want, the elvis one can be detected by the dot else try the nullable meaning if the ? is next to a letter.
You can try Kastree -- simple library to manipulate Kotlin source code as a set of AST objects.
https://github.com/cretz/kastree
See this [0] Kotlin code parsing related discussion. They talk about using antlr v4 grammar to parse the Kotlin code.
[0] https://discuss.kotlinlang.org/t/kotlin-parser/1728
I have not yet written a Kotlin language grammar for it.
But I have implemented a parser in Kotlin, id that is any use.
It is Kotlin common code, so should work for any target platform.
There is an article about it here, and the code is on github.
https://medium.com/#dr.david.h.akehurst/agl-your-dsl-in-the-web-c9f54595691b
I find Erlang's module arity import /n where n is the number of arguments rather bizarre.
In Java and various other languages you can do something like:
import static com.stuff.Blah.myFunction;
Which will import all overloaded Blay.myFunction(..) regardless of parameters.
Besides I guess being explicit why did the language designers decide this was a good idea (I'm not trying to criticize the language... just curious)?
Does it have to do with code swapping?
Or does it have to do with hiding guard methods for recursion? If so why not allow arity on export but no need for arity on import?
Why would I want to be that explicit? That is import the two argument function but not the the three argument of myFunction?
You should be aware of what importing functions in Erlang really does. It is a pure textual transformation. If I do an -import(foo, [bar/1,baz/2]). it means that when I write a call like bar(5) or baz(a, 3) the compiler transforms these to foo:bar(5) and foo:baz(a, 3). That is all it does, nothing else. It doesn't check anything:
It doesn't check if the module foo contains the functions bar/1 or baz/2.
It doesn't even check if the module foo exists.
Really all it does is hide that you are calling a function in another module. That is why the recommendation from experienced Erlangers is "don't use it". It was a mistake. Unfortunately it is much easier to add stupid things than to get rid of them so we were never able to remove it.
"Does it have to do with code swapping?"
Yes, sort of. The unit of all code handling in Erlang is the module. So you compile modules, load modules, purge and delete modules. This means that there are no inter-module dependencies at all in the system and the compiler makes no assumptions about other modules when it is compiling a module. No assumptions are made that the environment in which a module is compiled will be the same in which it is run. That is why it is at runtime the system checks whether the function you are trying to call in another exists, or even if the module itself exists. That is why the import was a purely textual transformation.
Erlang was originally developed in Prolog.
In Prolog, the arity adds additional meaning to what you consider to be the 'arguments, as I understand from a function' in a procedural programming language. But that model does not apply here.
The so-called clauses 'married(X,Y).' and 'married(X,Y,Z).' imply a different kind of relationship 'married', which can be declared as married/2 and married/3.
In procedural programming, 'add(a,b)' or 'add(a,b,c)' are intended to generate the addition of a different number of arguments. That's not immediately the case in Prolog, where it is possible to have the relationship 'a and b, added' or 'a, b and c, added' mean something else. Needless to say, Prolog allows you to declare 'add' as you would expect a function would do. But it allows for more. More available meaning, means more need to control it.
And as in any module system, selecting what you want to expose to external clients makes sense: hence the declaration of arity.
Does it have to do with code swapping?
Kind of. The modules in Erlang are compiled separately (which is part of what allows code swapping), unlike Java classes, so the compiler doesn't know how many versions of the imported function with different arities exist. It could assume that all calls of a function with the given name come from the same module, of course, but the designers likely decided it wasn't particularly useful.
In fact, you rarely want to use imports at all, at least in my experience, just as you rarely use static imports in Java. Just write module:function, like Class.staticMethod.
Or does it have to do with hiding guard methods for recursion?
No, since not importing functions doesn't hide them in any way.
I have a module using regexp:sh_to_awk and regexp:match.
But when I compile it, the compiler warns me that the regexp module was removed from R15 and recommends me to use the re module instead.
I searched the erlang documentation but I can't find how to replace the two functions.
Can anyone tell me how to fix this?
Indeed, regexp module has been deprecated for a while and has now been removed, replaced by the re module.
The old regexp:match function has been replaced by the re:run functions, which add a lot of functionality, such as returning captured parts as lists or binary (The old way of returning start position and length also remains):
> re:run("Test String","[a-zA-Z]{4}",[{capture,all,list},global]).
{match,[["Test"],["Stri"]]}
Read through the re:run/3 documentation, it's worth it, just as all the other functions of the re module (like compile and replace).
The regexp:sh_to_awk has been removed. You can use the filelib:wildcard functions for matching filenames, if that was your intended use of the old regexp:sh_to_awk/1 function.
I'm using xbase
grammar xolang.Xolang with org.eclipse.xtext.xbase.Xbase
and an
XBlockExpression
where I expect to write my code
When write an expression like
val c = 1 + 1
Then I get the following error
The method +(int) is undefined
The same happens with Strings. In fact it happens with every binary operator: ==, < , >, ... Now I know that xbase supports operator overloading, maybe that has something to do with it? (Maybe I still have to define somewhere that you can add numbers?)
I solved my problem.
You need to add the xbase.lib jarfile (the right version of course) to the buildpath of the project that uses your DSL.
If you wonder how you can easily add the xbase lib in Eclipse: Right Click on your Project that makes use of your DSL, select Build-Path->Add Libraries and choose XTend Library. The XTend Library includes the correct XBase Lib.
I want to have two lexers in one project, and I don't want to run into problems with having multiple yylex functions in the build. Can I make lex output with a different prefix?
You can use the -Pprefix parameter for flex in your makefile. Using flex -Pfoo you would effectively prefix all yy generated functions. Have a look at the manual page for further details.
flex lets you do that. Just define the YY_DECL macro. Dunno about actual Unix(tm) lex(1) though.
You could build a C++ lexer. This means all the state information is held in an object.
Then it is just a matter of using the correct object!