How to match enum types with clang-query - abstract-syntax-tree

Consider the following C source:
$ cat type.c
enum a {
b
};
int v1;
enum a v2;
How do I match the enumeration type with a clang AST matcher query?
I can match built-in types like this:
$ clang-query type.c --
clang-query> match varDecl(hasType(builtinType()))
Match #1:
/Users/stm/Documents/CTEST/type.c:6:1: note: "root" binds here
int v1;
^~~~~~
1 match.
But it doesn't work when I try to match the variable that is declared with the enum type:
$ clang-query type.c --
clang-query> match varDecl(hasType(enumType()))
0 matches.
I'm using clang 11.0.0 for these tests.

I cannot explain why this is necessary, but by trial and error I found that wrapping the enumType() matcher inside hasUnqualifiedDesugaredType() gives the desired result:
$ clang-query type.c --
clang-query> match varDecl(hasType(hasUnqualifiedDesugaredType(enumType())))
Match #1:
/Users/stm/Documents/CTEST/type.c:7:1: note: "root" binds here
enum a v2;
^~~~~~~~~
1 match.

Related

Return multiple nested dictionaries from Tcl

I have a Tcl proc that creates two dictionaries from a large file. It is something like this:
...
...
proc makeCircuitData {spiceNetlist} {
#read the spiceNetlist file line by line
# create a dict with multilevel nesting called elementMap that will have the following structure:
# elementMap key1 key2 value12
# elementMap keyA keyB valueAB
# and so on
# ... some other code here ...
# create another dict with multilevel nesting called cktElementAttr that will have the following structure:
# cktElementAttr resistor leftVoltageNode1 rightVoltageNode1 resValue11
# cktElementAttr resistor leftVoltageNode2 rightVoltageNode2 resValue12
# cktElementAttr inductor leftVoltageNode2 rightVoltageNode2 indValue11
# cktElementAttr inductor leftVoltageNode2 rightVoltageNode2 indValue12
# cktElementAttr capacitor leftVoltageNode2 rightVoltageNode2 capValue11
# ... so on...
}
I want to return these two nested dictionaries:
cktElementAttr and elementMap from the above types of procedures as these two dictionaries get used by other parts of my program.
What is the recommended way to return two dictionaries from Tcl procs?
Thanks.
This should work:
return [list $cktElementAttr $elementMap]
Then, at the caller, you can assign the return value to a list:
set theDictionaries [makeCircuitData ...]
or assign them to different variables:
lassign [makeCircuitData ...] cEltAttr elmMap
In Tcl 8.4 or older (which are obsolete!), you can (ab)use foreach to do the job of lassign:
foreach {cEltAttr elmMap} [makeCircuitData ...] break
Documentation:
break,
foreach,
lassign,
list,
return,
set

How does one specify multi-line strings in Typesafe Config?

I have the following configuration file that I want to use from Scala applying this library:
P11 {
yes="0.0"
no="1.0"
}
P12 {
yes="0.01"
no="0.99"
}
P13 {
id = "123 567 \
T 0: \
If (f 23 <= 0.0)"
}
This is how I do it:
import com.typesafe.config.ConfigFactory
val configFileName = "/usr/develop/tests/config.conf"
val parsedConfigMCF = ConfigFactory.parseFile(new File(configFileName))
val confMCF = ConfigFactory.load(parsedConfigMCF)
Then I get the error:
Expecting a value but got wrong token: 'newline' (backslash followed by 'newline', this is not a valid escape sequence
It looks like it does not like \ (backslash), but I need to put several lines for id in P13.
From official documentation of Typesafe Config:
multi-line strings with triple quotes as in Python or Scala
so:
P13 {
id = """123 567
T 0:
If (f 23 <= 0.0)"""
}

r check if string contains special characters

I am checking if a string contains any special characters. This is what I have, and its not working,
if(grepl('^\\[:punct:]', val))
So if anybody can tell me what I am missing, that will be helpful.
Special characters
~ ` ! ## $ % ^ & * | : ; , ." |
As #thelatemail pointed out in the comments you can use:
grepl('[^[:punct:]]', val)
which will result in TRUE or FALSE for each value in your vector. You can add sum() to the beginning of the statement to get the total number of these cases.
You can also use:
grepl('[^[:alnum:]]', val)
which will check for any value that is not a letter or a number.

Pyparsing - name not starting with a character

I am trying to use Pyparsing to identify a keyword which is not beginning with $ So for the following input:
$abc = 5 # is not a valid one
abc123 = 10 # is valid one
abc$ = 23 # is a valid one
I tried the following
var = Word(printables, excludeChars='$')
var.parseString('$abc')
But this doesn't allow any $ in var. How can I specify all printable characters other than $ in the first character position? Any help will be appreciated.
Thanks
Abhijit
You can use the method I used to define "all characters except X" before I added the excludeChars parameter to the Word class:
NOT_DOLLAR_SIGN = ''.join(c for c in printables if c != '$')
keyword_not_starting_with_dollar = Word(NOT_DOLLAR_SIGN, printables)
This should be a bit more efficient than building up with a Combine and a NotAny. But this will match almost anything, integers, words, valid identifiers, invalid identifiers, so I'm skeptical of the value of this kind of expression in your parser.

Get the first letter of a make variable

Is there a better way to get the first character of a GNU make variable than
FIRST=$(shell echo $(VARIABLE) | head -c 1)
(which is not only unwieldy but also calls the external shell)?
This is pretty horrible, but at least it doesn't invoke shell:
$(eval REMAINDER := $$$(VAR)) # variable minus the first char
FIRST := $(subst $(REMAINDER),,$(VAR)) # variable minus that
The GNU Make Standard Library provides a substr function
substr
Arguments: 1: A string
2: Start offset (first character is 1)
3: Ending offset (inclusive)
Returns: Returns a substring
I haven't tested it, but $(call substr,$(VARIABLE),1,1) should work
Since I came across this in my own search and didn't find what I was looking for here is what I ended up using to parse a hex number that could be applied to any known set of characters
letters := 0 1 2 3 4 5 6 7 8 9 a b c d e f
nextletter = $(strip $(foreach v,$(letters),$(word 2,$(filter $(1)$(v)%,$(2)) $v)))
then
INPUT := 40b3
firstletter := $(call nextletter,,$(INPUT))
secondletter := $(call nextletter,$(firstletter),$(INPUT))
thirdletter := $(call nextletter,$(firstletter)$(secondletter),$(INPUT))
etc.
It's ugly but it's shell agnostic

Resources