How to list all keys of a generic yaml by yaml-cpp - yaml-cpp

If a yaml document contains a mix of sequences and maps and scalars, and those collection types are themselves multi-level deep, is there a built-in function or an easy way to list all the keys, but not the final value at the leaf? Assuming the keys are strings.

You'll have to recurse on the nodes in your document, checking the type of each:
switch (node.Type()) {
case Null: // ...
case Scalar: // ...
case Sequence:
for (auto it = node.begin(); it != node.end(); ++it) {
auto element = *it;
// recurse on "element"
}
break;
case Map:
for (auto it = node.begin(); it != node.end(); ++it) {
auto key = it->first;
auto value = it->second;
// recurse on "key" and "value"
// if you're sure that "key" is a string, just grab it here
}
break;
case Undefined: // ...
}

Related

Find a subsequence in a list

Lets assume that we are looking for a sequence in a list and this sequence should satisfy some conditions, for example I have a series of numbers like this:
[1,2,4,6,7,8,12,13,14,15,20]
I need to find the largest sequence so that its consecutive elements have a difference of 1, So what I expected to get is:
[12,13,14,15]
I'm curious if there is any way to get in Kotlin Sequence or inline functions like groupBy or something else.
PS: I know how to create sequences, the question is how to evaluate and extract some sequences with given conditions.
There is no built in functionality for this "sequence" recognition, but you could solve it with the fold operation:
val result = listOf(1, 2, 3, 12, 13, 14, 15)
.distinct() // remove duplicates
.sorted() // by lowest first
.fold(mutableListOf<Int>() to mutableListOf<List<Int>>()) { (currentList, allLists), currentItem ->
if (currentList.isEmpty()) { // Applies only to the very first item
mutableListOf(currentItem) to allLists
} else {
if (currentItem - currentList.max()!! == 1) { // Your custom sequence recognition 'difference of 1'
currentList.apply { add(currentItem) } to allLists
} else {
mutableListOf(currentItem) to allLists.apply { add(currentList) } // Next
}
}
}
.let { it.second.apply { add(it.first) } } // Add last list
.maxBy { it.size } // We need the longest pattern - which will take first of the stack - it could be multiple.
// If you need more precise list, sort them by your criteria

Specman/e constraint (for each in) iteration

Can I iterate through only a part of a list in e, in a constraint.
For example, this code will go through the whole layer_l list:
<'
struct layer_s {
a : int;
keep soft a == 3;
};
struct layer_gen_s {
n_layers : int;
keep soft n_layers == 8;
layer_l : list of layer_s;
keep layer_l.size() == read_only(n_layers);
};
extend sys {
layer_gen : layer_gen_s;
run() is also {
messagef(LOW, "n_layers = %0d", layer_gen.n_layers);
for each in layer_gen.layer_l{
messagef(LOW, "layer[%2d]: a = %0d", index, it.a);
};
};
};
-- this will go through all layer_l
extend layer_gen_s {
keep for each (layer) using index (i) in layer_l {
layer.a == 7;
};
};
But, I would like to only iterate the for each in through, for example, 2 items. I tried the code below, but it doesn't work:
-- this produces an error
extend layer_gen_s {
keep for each (layer) using index (i) in [layer_l.all(index < 2)] {
layer.a == 7;
};
};
Also I don't want to use implication, so this is not what I want:
-- not what I want, I want to specify directly in iterated list
extend layer_gen_s {
keep for each (layer) using index (i) in layer_l {
(i < 2) => {
layer.a == 7;
};
};
};
Using the list slicing operator doesn't work either, because the path in a for..each constraint is limited to a simple path (e.g. a list variable). The following doesn't work either:
keep for each (layer) using index (i) in layer_l[0..2] {
//...
};
This is a Specman limitation.
To force looping over a sub-list your only bet is to create that sub-list as a separate variable:
layer_subl: list of layer_s;
keep layer_subl.size() == 3;
keep for each (layer) using index (i) in layer_subl {
layer == layer_l[i];
};
Now you can loop on only the first 3 elements within your for..each constraint:
keep for each (layer) in layer_subl {
layer.a == 7;
};
This avoids using implication inside the constraint. Whether this is worth is for you to decide. Also note that the lists will contain the same objects (this is good). No extra struct objects get created.
Creation of the sub-list like this is boilerplate code that could be handled by the tool itself. This would make the code much more concise and readable. You could contact your vendor and request this feature.

Building a linked list in yacc with left recursive Grammar

I want to build a linked list of data in yacc.
My Grammar reads like this:
list: item
| list ',' item
;
I have put the appropriate structures in place in the declarations section. But I am not able to figure out a way to get a linked list out of this data. I have to store the recursively obtained data and then redirect it for other purposes.
Basically I am looking for a solution like this one:
https://stackoverflow.com/a/1429820/5134525
But this solution is for right recursion and doesn't work with left.
It depends heavily on how you implement your linked list, but once you have that, it is straight-forward. Something like:
struct list_node {
struct list_node *next;
value_t value;
};
struct list {
struct list_node *head, **tail;
};
struct list *new_list() {
struct list *rv = malloc(sizeof(struct list));
rv->head = 0;
rv->tail = &rv->head;
return rv; }
void push_back(struct list *list, value_t value) {
struct list_node *node = malloc(sizeof(struct list_node));
node->next = 0;
node->value = value;
*list->tail = node;
list->tail = &node->next; }
allows you to write your yacc code as:
list: item { push_back($$ = new_list(), $1); }
| list ',' item { push_back($$ = $1, $3); }
;
of course, you should probably add checks for running out of memory, and exit gracefully in that case.
If you use a left recursive rule, then you need to push the new item at the end of the list rather than the beginning.
If your linked list implementation doesn't support push_back, then push the successive items at the front and reverse the list when its finished.
Very simple.
list
: item
{
$$ = new MyList<SomeType>();
$$.add($1);
}
| list ',' item
{
$1.add($3);
$$ = $1;
}
;
assuming you are using C++, which you didn't state, and assuming you have some MyList<T> class with an add(T) method.

what is the need of else block in the method "push_links" of the following code?

This code is for Aho-Corasick algorithm which i have refereed from here
I understood this code up to if block of push_links method but i didn't get the use or requirement for the else part of the same method.
More specifically first method is used for the construction of trie. The remaining work is done by second method i.e linking the node to their longest proper suffix which are prefix of some pattern also. This is carried out by the If block then what is the need of else part.
Please help me in this.
const int MAXN = 404, MOD = 1e9 + 7, sigma = 26;
int term[MAXN], len[MAXN], to[MAXN][sigma], link[MAXN], sz = 1;
// this method is for constructing trie
void add_str(string s)
{
// here cur denotes current node
int cur = 0;
// this for loop adds string to trie character by character
for(auto c: s)
{
if(!to[cur][c - 'a'])
{
//here two nodes or characters are linked using transition
//array "to"
to[cur][c - 'a'] = sz++;
len[to[cur][c - 'a']] = len[cur] + 1;
}
// for updating the current node
cur = to[cur][c - 'a'];
}
//for marking the leaf nodes or terminals
term[cur] = cur;
}
void push_links()
{
//here queue is used for breadth first search of the trie
int que[sz];
int st = 0, fi = 1;
//very first node is enqueued
que[0] = 0;
while(st < fi)
{
// here nodes in the queue are dequeued
int V = que[st++];
// link[] array contains the suffix links.
int U = link[V];
if(!term[V]) term[V] = term[U];
// here links for the other nodes are find out using assumption that the
// link for the parent node is defined
for(int c = 0; c < sigma; c++)
// this if condition ensures that transition is possible to the next node
// for input 'c'
if(to[V][c])
{
// for the possible transitions link to the reached node is assigned over
// here which is nothing but transition on input 'c' from the link of the
// current node
link[to[V][c]] = V ? to[U][c] : 0;
que[fi++] = to[V][c];
}
else
{
to[V][c] = to[U][c];
}
}
}
IMO you don't need the else-condition. If there is no children either it's already a link or nothing.
There are some variations of Aho-Corasick algorithm.
Base algorithm assumes that if edge from current node (cur) over symbol (c) is missing, then you go via suffix links to the first node that has edge over c (you make move via this edge).
But your way over suffix links is the same (from the same cur and c), because you don't change automaton while searching. So you can cache it (save result of
// start from node
while (parent of node doesn't have an edge over c) {
node = parent
}
// set trie position
node = to[node][c]
// go to next character
in to[node][c]. So next time you won't do this again. And it transfrom automaton from non-deterministic into deterministic state machine (you don't have to use link array after pushing, you can use only to array).
There are some problems with this implementation. First, you can get an index of string you found (you don't save it). Also, len array isn't used anywhere.
For
means, this algorithm is just checking the existence of the character in the current node link using "link[to[V][c]] = V ? to[U][c] : 0;". should not it verify in the parents link also?
Yes, it's ok, because if to[U][c] is 0, then there are no edges via c from all chain U->suffix_parent->suffix parent of suffix_parent ... -> root = 0. So you should set to[V][c] to zero.

Dictionary in protocol buffers

Is there any way to serialize a dictionary using protocol buffers, or I'll have to use Thrift if I need that?
For future answer seekers, ProtoBuf now supports Maps natively:
message MapMessage
{
map<string, string> MyMap = 1;
}
Protobuf specification now supports dictionaries (maps) natively.
Original answer
People typically write down the dictionary as a list of key-value pairs, and then rebuild the dictionary on the other end.
message Pair {
string key = 1;
string value = 2;
}
message Dictionary {
repeated Pair pairs = 1;
}
You can check the ProtoText package.
Assume you want to serialize a dict person_dict to a pre-defined PersonBuf protobuf object defined in personbuf_pb2 module.
In this case, to use ProtoText,
import ProtoText
from personbuf_pb2 import PersonBuf
obj = PersonBuf()
obj.update(person_dict)
I firstly comment the #Flassari 's answer as it is really convenient.
However, in my case, I needed map<Type, repeated AnyModel> where :
enum Type {
Undefined = 0;
Square = 1;
Circle = 2;
}
message AnyModel {
string Name = 1;
}
Here I just want to return a dictionary that, for each type, contain a list of AnyModel
However, I didn't find a better workaround than the one proposed by #JesperE so I did the following: (as you can't use enum as key in map)
message MyRPCBodyCall {
map<string, AnyModels> Models = 1;
}
enum Type {
Undefined = 0;
Square = 1;
Circle = 2;
}
message AnyModel {
string Name = 1;
}
message AnyModelArray {
repeated AnyModel AnyModels = 1;
}
Here I convert from/to string my enum using my chosen code languages from both server/client side
So both approaches are actually valid answers IMO, depends on your requirements.