Flex and Lemon Parser - lex

I'm trying to learn flex and lemon, in order to parse a (moderately) complex file format. So far, I have my grammar and lex file and I believe it is correctly parsing an example file. Right now, I want to pass the token text scanned with flex to lemon.
The flex YYSTYPE is defined as
#define YYSTYPE char*
The lemon token type is
%token_type {char *}
However, if I have a set of rules in lemon:
start ::= MATDEF IDENTIFIER(matName) LEFT_CURLY_BRACE(left) materialDefinitionBody(mBody) RIGHT_CURLY_BRACE(right) .
{
std::string r = std::string(matName) + std::string(left) + mBody + std::string(right);
std::cout << "result " << r << std::endl;
}
materialDefinitionBody(r) ::= techniqueList .
{
r = "a";
}
the output will be
result a
when it should be something like
mat1 { a }
My main parsing loop is:
void parse(const string& commandLine) {
// Set up the scanner
yyscan_t scanner;
yylex_init(&scanner);
YY_BUFFER_STATE bufferState = yy_scan_string(commandLine.c_str(), scanner);
// Set up the parser
void* shellParser = ParseAlloc(malloc);
yylval = new char[512];
int lexCode;
do {
yylval[0] = 0;
lexCode = yylex(scanner);
cout << lexCode << " : " << yylval << std::endl;
Parse(shellParser, lexCode, yylval);
}
while (lexCode > 0);
if (-1 == lexCode) {
cerr << "The scanner encountered an error.\n";
}
// Cleanup the scanner and parser
yy_delete_buffer(bufferState, scanner);
yylex_destroy(scanner);
ParseFree(shellParser, free);
}
The cout line is printing the correct lexCode/yylval combination.
What is the best way? I can't find anything that works.

You need to have
yylval = new char[512];
inside the do-while loop.

Related

runtime error with mongocxx::options::find

It works fine when I do query without option
document condition;
condition << "age" << 22;
auto cursor = collection_.find(condition.view());
for (auto&& doc : cursor)
{
std::cout << bsoncxx::to_json(doc) << std::endl;
}
but once I use mongocxx::options::find opts
document condition;
condition << "age" << 22;
mongocxx::options::find opts{};
opts.limit(1);
auto cursor = collection_.find(condition.view(), opts);
for (auto&& doc : cursor)
{
std::cout << bsoncxx::to_json(doc) << std::endl;
}
read access permission conflicts error occured
enter image description here
I recompiled mongocxx and built a new project, the error didn't appear. Maybe there is something wrong with my previous environment.

Access to OS functions from CAPL

I'm doing a script using CAPL and am stuck for a solution to grep the login ID from Windows. Could some please help show how to get Windows user login ID from within a CAPL program code, if this is possible?
For example, if the Windows user login ID is 'kp21ml' , I want to read this ID from a CAPL function, as shown below.
byte UserIdCheck()
{
char uid[10];
byte CanMessageTrasmission;
strncpy(uid, xxxx(), 6); // where xxxx() is the unknown OS or system function that could return the login ID ?
if (strncmp(uid, "kp21ml") != 0)
{
write("Access denied!"); // Message to CANoe's Write window
CanMessageTrasmission = 0;
}
else
{
// Access ok
CanMessageTrasmission = 1;
}
return CanMessageTrasmission;
}
I use this CAPL book as my reference guide, which is very good:
http://docplayer.net/15013371-Programming-with-capl.html
But I couldn't find anything to do with system access. I would appreciate your help.
Thanks
Juno
I'm afraid you won't be able to do that directly from a CAPL script.
I generally create a CAPL-DLL and include that in my CANoe project when I need to access some OS level functionality. Though I use it mostly for accessing an external device (e.g. USB) or to interact with another program using sockets over local host, the principle is the same.
You can find more information in CANoe's documentation with examples but the CAPL-DLL source code provided in CANoe samples is a little difficult to understand.
I've attempted to strip some of the "unnecessary" parts in the following code sample; this example will create a CAPL-DLL which "exposes" the multiplyBy10 function and basically allows you to call multiplyBy10 from you CAPL script):
#define USECDLL_FEATURE
#define _BUILDNODELAYERDLL
#pragma warning( disable : 4786 )
#include "cdll.h"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <map>
char moduleName[_MAX_FNAME];
HINSTANCE moduleHandle;
unsigned int
CAPLEXPORT far CAPLPASCAL multiplyBy10 (unsigned char value)
{
unsigned int result = value * 10;
freopen("CONOUT$", "w", stdout);
std::cout << "multiplyBy10() - value: " << int(value) << ", result: " << result << std::endl;
return (result);
}
CAPL_DLL_INFO4 table[] =
{
{CDLL_VERSION_NAME, (CAPL_FARCALL)CDLL_VERSION, "", "", CAPL_DLL_CDECL, 0xABD, CDLL_EXPORT},
{"multiplyBy10", (CAPL_FARCALL)multiplyBy10, "CAPL_DLL", "This is a demo function", 'L', 1, "D", "", { "value"}},
{0, 0}
};
CAPLEXPORT CAPL_DLL_INFO4 far * caplDllTable4 = table;
bool
WINAPI DllMain(HINSTANCE handle, DWORD reason, void*)
{
static FILE * stream;
switch (reason)
{
case DLL_PROCESS_ATTACH:
{
moduleHandle = handle;
char path_buffer[_MAX_PATH];
DWORD result = GetModuleFileName(moduleHandle, path_buffer, _MAX_PATH);
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath_s(path_buffer, drive, dir, fname, ext);
strcpy_s(moduleName, fname);
AllocConsole();
freopen_s(&stream, "conout$", "w", stdout);
std::cout << "DLL_PROCESS_ATTACH" << std::endl;
return 1;
}
case DLL_PROCESS_DETACH:
{
std::cout << "DLL_PROCESS_DETACH" << std::endl;
FreeConsole();
fclose(stream);
return 1;
}
}
return 1;
}

unordered_map::find() and two iterators

Having a class with a private member
std::unordered_map<std::string, size_t> myMap;
and the corresponding getter
std::unordered_map<std::string, size_t> getMyMap() const {return myMap;}
I observe strange behaviour by applying std::unordered_map::find() two times, each time saving the returned iterator, e.g.
auto pos1 = test.getMyMap().find("a");
auto pos2 = test.getMyMap().find("a");
Altough I look for the same key "a" the iterator points to different elements. The following sample code illustrates the problem:
#include <iostream>
#include <unordered_map>
#include <vector>
#include <string>
class MyMap{
public:
MyMap(){
myMap= {
{"a", 1},
{"b", 2}
};
}
std::unordered_map<std::string, size_t> getMyMap() const {return myMap;}
private:
std::unordered_map<std::string, size_t> myMap;
};
int main(){
MyMap test;
auto pos1 = test.getMyMap().find("a");
auto pos2 = test.getMyMap().find("a");
std::cout << pos1->first << "\t" << pos1->second << std::endl;
std::cout << pos2->first << "\t" << pos2->second << std::endl;
}
Compiling with g++ -std=c++11 and running gives
b 2
a 1
where the first line is unexpected. It should be "a 1".
Changing the code to
auto pos3 = test.getMyMap().find("a");
std::cout << pos3->first << "\t" << pos3->second << std::endl;
auto pos4 = test.getMyMap().find("a");
std::cout << pos4->first << "\t" << pos4->second << std::endl;
results in the correct output
a 1
a 1
Furthermore just creating an unordered_map in the main file and applying find() works. It seems the problem is connected to the getter-method, maybe to return-value-optimisation. Do you have any explanations for this phenomena?
It's because you have undefined behavior in your code. The getMyMap returns a copy of the map, a copy that is destructed once the expression test.getMyMap().find("a") is done.
This means you have two iterators that are pointing to no longer existing maps.
The solution is very simple: Make getMyMap return a constant reference instead:
std::unordered_map<std::string, size_t> const& getMyMap() const;
That it seems to work in the latter case, is because that's a pitfall of undefined behavior, it might sometime seem like it works, when in reality it doesn't.
test.getMyMap().find("a"); does find on a copy of original myMap which is destructed after the expression is complete, making the iterators pos1 and pos2 to non-existing map, invoking an undefined behaviour
Instead you can play around like following :
auto mymap = test.getMyMap() ; // Store a copy
auto pos1 = mymap.find("a"); // Then do stuff on copy
auto pos2 = mymap.find("a");

pselect problems with FD_ISSET on cygwin

I'm running cygwin and use pselect to monitor a socket and filedescriptors for child processes.
According to some example that I found here http://www.linuxprogrammingblog.com/code-examples/using-pselect-to-avoid-a-signal-race and the man pages pselect should return the number of filedescriptors which are set in the mask fields (http://linux.die.net/man/2/pselect).
Now when I connect to my server pselect returns, which is fine. But when I test for the filedescriptors using FD_ISSET they always return true:
FD_ZERO(&readers);
FD_ZERO(&writers);
FD_ZERO(&exceptions);
FD_SET(fileno(stdin), &readers);
FD_SET(socket, &readers);
pret = pselect(FD_SETSIZE, &readers, &writers, &exceptions, NULL, &mSignalMask);
, &readers, &writers, &exceptions, NULL, &mSignalMask);
if(pret <= 0)
{
// ignore for now
continue;
}
if(FD_ISSET(fileno(stdin), &readers))
{
string s;
cin >> s;
cout << "stdin: " << s << endl; // blocks because the code always gets here even when
// pselect returns because of a childsignal without any data.
continue;
}
if(FD_ISSET(socket, &readers))
{
accept(); // blocks because the code always gets here even when
// pselect returns because of a childsignal without any data.
cout << "task created connection from " <<task->getClientHost() << endl;
continue;
}
Found the problem myself. FD_ISSET can ONLY be used if the result from pselect is > 0, otherweise the returnvalue from FD_ISSET is as before the call. So best treat it as undefined when pselect returns <= 0;

error: request for member 'find' in '(cstring name)' which is of non-class type 'char [2000]'

I'm sorry if this is vague I'm still pretty new to programming(also new to forums >_>)
Ok, my code is supposed to read in a number from a file, then use that number to read in that amount of words as dictionary words. I then store those words into an array and keep them for later usage. After the dictionary words in the file comes some paragraph, i read that in and set it to c-string array.(iv got that all down so far) But for the last part of the program i need to go back though that paragraph c-string and count how many times each dictionary word appears. I'm currently trying paragraph.find (word[0]) but i get some error that i don't know how to fix.
error: |40|error: request for member 'find' in 'paragraph', which is of non-class type 'char [2000]'|
code:
#include <iostream>
#include <fstream>
#include <cstring>
#include <windows.h>
using namespace std;
int main()
{
ifstream inStream; //declare ifstream
inStream.open("infile2.txt"); //open my file
int number; // number at the begining of the file that lets the program know
inStream >> number; // how many dictionary words are to be expected.
cout << number << " dictionary word(s)" << endl << endl;
char dict[30];
char text[2000];
char paragraph[2000]; // declareing some stuff
int count;
int position;
string word[5];
for (int i=0; i<number; i++) // using c string to set the 'number' amount of words in the dict array
{
inStream.getline(dict,30,'|');
word[i] = dict;
}
for (int i=0; i<number; i++) // cout so i can see its all set up right.
{
cout << "word " << i+1 << " is: " << word[i] << endl;
}
cout << endl;
inStream.get(paragraph,2000,'|'); // setting the rest of the paragrapg of the txt document to a c string
cout << paragraph; // so it can be searched later using the 'dict' words
position = paragraph.find (word[0]); // trying to find the position of the first word stored in 'dict[0]' but i run into an error
return 0;
}
the infile2.txt looks like this:
3steak|eggs|and|
steak and eggs and eggs and steak, eggs and steak, steak and eggs...
delicious.
c-strings are not classes and do not have a find method (or any other methods for that matter) i.e paragraph.find. You could try using a string or if you need to use c-strings a find method that takes two c strings as parameters.
such as This one