Lex code:
identifier [\._a-zA-Z0-9\/]+
comment "//"
<*>{comment} {
cout<<"Comment\n";
char c;
while((c= yyinput()) != '\n')
{
}
}
<INITIAL>{s}{e}{t} {
BEGIN(SAMPLE_STATE);
return SET;
}
<SAMPLE_STATE>{identifier} {
strncpy(yylval.str, yytext,1023);
yylval.str[1023] = '\0';
return IDENTIFIER;
}
In the above lex code, there is no error when "// set name" is parsed. Please notice the space after "//" in the sentence parsed. However, when "//set name" is parsed, there is an error reported. Could you point to where I am going wrong? Thanks.
The error is caught by yyerror and reports
SampleParser.y:43: int CMTSTapTestSeq_yyerror(char*): Assertion `0 && "Error parsing Sample file\n"' failed.
This assertion is added by me.
I think you have made a mistake in simplifying your example, as the code you supplied works fine and does not have the fault you indicated. I coded it up and tested it (I used C instead of C++ for convenience). However, I see you posted a later question with more code that explained the problem better. I answered that one also.
s s
e e
t t
identifier [\._a-zA-Z0-9\/]+
comment "//"
%s SAMPLE_STATE
%{
//#include <iostream>
//using namespace std;
#include <stdio.h>
#define SET 1
#define IDENTIFIER 2
#define yyinput input
%}
%%
<*>{comment} {
// cout<<"Comment\n";
printf("Comment\n");
char c;
while((c= yyinput()) != '\n')
{
}
}
<INITIAL>{s}{e}{t} {
BEGIN(SAMPLE_STATE);
//return SET;
printf("SET\n");
}
<SAMPLE_STATE>{identifier} {
//strncpy(yylval.str, yytext,1023);
//yylval.str[1023] = '\0';
//return IDENTIFIER;
printf("identifier");
}
The accepts both:
//set name
// set name
Related
I am using CreateNamedPipe. It returns 0XFFFFFFFF but when I call GetLastError and perror I get "NO ERROR".
I have checked https://learn.microsoft.com/en-us/windows/win32/ipc/multithreaded-pipe-server and I heve coded very similar.
I coded this using an example provided here: https://stackoverflow.com/questions/47731784/c-createnamedpipe-error-path-not-found-3#= and he says it means ERROR_PATH_NOT_FOUND (3). But my address is "\\.\pipe\pipe_com1. Note that StackOverflow seems to remove the extra slashes but you will see them in the paste of my code.
I followed the example here: Create Named Pipe C++ Windows but I still get the error. Here is my code:
// Create a named pipe
// It is used to test TcpToNamedPipe to be sore it it is addressing the named pipe
#include <windows.h>
#include <stdio.h>
#include <process.h>
char ch;
int main(int nargs, char** argv)
{
if (nargs != 2)
{
printf("Usage pipe name is first arg\n");
printf("press any key to exit ");
scanf("%c", &ch);
return -1;
}
char buffer[1024];
HANDLE hPipe;
DWORD dwRead;
sprintf(buffer, "\\\\.\\pipe\\%s", argv[1]);
hPipe = CreateNamedPipe((LPCWSTR)buffer,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists...
1,
1024*16,
1024*16,
NMPWAIT_USE_DEFAULT_WAIT,
NULL);
if (hPipe == INVALID_HANDLE_VALUE)
{
//int errorno = GetLastError();
//printf("error creating pipe %d\n", errorno);
perror("");
printf("press any key to exit ");
scanf("%c", &ch);
return -1;
}
while (hPipe != INVALID_HANDLE_VALUE)
{
if (ConnectNamedPipe(hPipe, NULL) != FALSE) // wait for someone to connect to the pipe
{
while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE)
{
/* add terminating zero */
buffer[dwRead] = '\0';
/* do something with data in buffer */
printf("%s", buffer);
}
}
DisconnectNamedPipe(hPipe);
}
return 0;
}
I'm guessing that the pointer to the address may be wrong and CreateNamedPipe is not seeing the name of the pipe properly. So I used disassembly and notice that the address is in fact a far pointer. Here is that disassembly:
00CA1A45 mov esi,esp
00CA1A47 push 0
00CA1A49 push 0
00CA1A4B push 4000h
00CA1A50 push 4000h
00CA1A55 push 1
00CA1A57 push 0
00CA1A59 push 3
00CA1A5B lea eax,[buffer]
00CA1A61 push eax
00CA1A62 call dword ptr [__imp__CreateNamedPipeW#32 (0CAB00Ch)]
Can someone spot my problem?
I'm trying to create a simple program using Lex that checks if a given email address is valid or not. This is how I'm actually trying to achieve this:
Declarations section
%{
#include <stdio.h>
#include <string>
int correct = 0;
string email;
void write_data(string email, int correct);
/* Alias section */
name [a-zA-Z]
special [-_%+-]
digit [0-9]
domain [a-z]\.[a-z]{2,5}
email {name}+({digit} | {special})*#{domain}{1}
%}
Rules section
%%
{email} {correct = 1;}
%%
Programs section
int main(int argc, char* argv[])
{
if(argc == 2){
yyin = fopen(argv[1], "r");
email = yyin.getline();
if(yyin == NULL){
printf("Couldn't open %s file\n", argv[1]);
exit(-1);
}
}
else{
yyin = stdin;
email = yytext;
}
correct = 0;
yylex();
write_data(email, correct);
return 0;
}
void write_data(string email, int correct)
{
if(correct == 1)
printf("Email %s is correct\n", correo);
else
printf("Email %s is not correct\n", correo);
}
I'm trying to invoke the Lex tool using
lex template.l
And I'm getting the following error:
template.h:40: undefined definition {email}
I've been trying for a while already but I couldn't even run Lex on it so I don't know what could be wrong.
I figured it out for anyone interested. You MUST place the aliases out of the first %{%} section. The result of the Declaration section is as follows:
%{
#include <stdio.h>
#include <string>
int correct = 0;
string email;
void write_data(string email, int correct);
%}
/* Alias section */
name [a-zA-Z]
special [-_%+-]
digit [0-9]
domain [a-z]\.[a-z]{2,5}
email {name}+({digit} | {special})*#{domain}{1}
#include "pch.h"
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <stdio.h>
using namespace std;
class LetterDistribution
{
public: char district, trace;
public: int random_num;
public : LetterDistribution(){}
public: LetterDistribution(char dis)
{
district = dis;
trace = 'Z';
}
public: string LetterNumbers()
{
random_num = rand();
string letter_no ( district + " " + random_num);
return letter_no;
}
};
int main()
{
srand(time(0));
cout << "Enter district\n"<<endl;
char dis ;
cin >> dis;
LetterDistribution ld(dis);
cout << ld.LetterNumbers();
return 0;}
I am getting error in second last line inside main "cout << ld.LetterNumbers();". I am new to c++ , I have been working on C# earlier. I shall be thankful if someone could help me .
You have 2 issues in LetterNumbers function:
You can't add to string a number, you should convert the number to string first. you can do so by std::to_string(random_num)
You can't start concatenate string with a character, since character is like number in c++, and adding anything to number is a number. You should start from a string, even an empty one.
So the whole function can be something like:
string LetterNumbers()
{
random_num = rand();
string letter_no ( std::string("") + district + " " + std::to_string(random_num));
return letter_no;
}
Another issues: (but not errors!)
in c++ you can specify public: once, and everything after it is still public, until you change it. same thing for private and protected.
instead of <stdio.h> you should use <cstdio> which is the c++ wrapper for the c header.
I use tcl shellicon command to extract icons, as it mentioned on wiki page below, there are some international character problems in it, then I write some code to test but it doesn't work, could anyone to help me correct it.
/*
* testdll.c
* gcc compile: gcc testdll.c -ltclstub86 -ltkstub86 -IC:\Users\L\tcc\include -IC:\Users\L\tcl\include -LC:\Users\L\tcl\lib -LC:\Users\L\tcc\lib -DUSE_TCL_STUBS -DUSE_TK_STUBS -shared -o testdll.dll
*/
#include <windows.h>
#include <tcl.h>
#include <stdlib.h>
int TestdllCmd(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]) {
char * path;
Tcl_DString ds;
if (objc > 2) {
Tcl_SetResult(interp, "Usage: testdll ?path?",NULL);
return TCL_ERROR;
}
if (objc == 2) {
path = Tcl_GetString(objv[objc-1]);
path = Tcl_TranslateFileName(interp, path, &ds);
if (path != TCL_OK) {
return TCL_ERROR;
}
}
Tcl_AppendResult(interp, ds, NULL);
return TCL_OK;
}
int DLLEXPORT Testdll_Init(Tcl_Interp *interp) {
if (Tcl_InitStubs(interp, "8.5", 0) == NULL) {
return TCL_ERROR;
}
Tcl_CreateObjCommand(interp, "testdll", TestdllCmd, NULL, NULL);
Tcl_PkgProvide(interp, "testdll", "1.0");
return TCL_OK;
}
I compile it with:
gcc compile: gcc testdll.c -ltclstub86 -ltkstub86 -IC:\Users\USERNAME\tcc\include -IC:\Users\USERNAME\tcl\include -LC:\Users\USERNAME\tcl\lib -LC:\Users\USERNAME\tcc\lib -DUSE_TCL_STUBS -DUSE_TK_STUBS -shared -o testdll.dll
windows cmd shell run: tclsh testdll.tcl
load testdll
puts [testdll C:/Users/L/桌面]
the output is:
// This line isn't in the output, just to show the first line of output is a *EMPTY LINE*
while executing
"testdll 'C:/Users/L/桌面'"
invoked from within
"puts [testdll 'C:/Users/L/桌面']"
(file "testdll.tcl" line 2)
In fact, I want to print a line, whose content is "C:/Users/L/桌面"
I write this dll to debug how to replace Tcl_GetString,Tcl_TranslateFileName with Tcl_FSGetNormalizedPath, Tcl_FSGetNativePath, I wonder if it's clear?
Thank you!
Remove this:
if (path != TCL_OK) {
return TCL_ERROR;
}
You are comparing a char * to an int.
The manual page for Tcl_TranslateFileName says:
However, with the advent of the newer Tcl_FSGetNormalizedPath
and Tcl_FSGetNativePath, there is no longer any need to use this
procedure.
You should probably switch to more modern API call.
I'm currently writing a program that reads numbers from sets of 2 numbers from a text file and prints them out. I'd like to use the numbers to determine a GCD later, but I have to be able to scan them from the file first. The text file looks like this:
24 72
25 50
31 89
...
Tab is pressed between each number in the first row and each number in the second.
I've come up with this so far (commented out section is to be used for determining the GCD):
/*
File name: euclid.cpp
This program find the largest common multiple of two numbers using the Euclid method.
*/
#include <stdio.h>
#include "genlib.h"
#include "simpio.h"
int main()
{
FILE *input;
long num1=0, num2=0, orinum2=0, rem=0, gcd=0;
int i=0, size=0;
char temp;
input=fopen("Euclid.txt", "r");
while((temp=getc(input))!=EOF)
{
if(temp=='\n') size++;
}
size++;
while(i<size)
{
fscanf(input, "%d\t%d%[^\n]", &num1, &num2);
printf("%d\t%d\n", num1, num2);
orinum2=num2;
/* while (true)
{
rem=num1%num2;
if (rem==0)
{
gcd=num2; break;
}
else
{
num1=num2;
num2=rem;
}
}
printf("The GCD of %d and %d is %d.\n", num1, orinum2, gcd);
*/ i++;
}
fclose(input);
}
Every single webpage and resource I have checked dictates that this should work, but for some reason it just isn't.
fscanf will "return the number of input items successfully matched and assigned":
#include <stdio.h>
int main()
{
FILE *input = fopen("input.txt", "r"); ;
int num1, num2;
while(fscanf(input, "%d %d", &num1, &num2) > 0)
printf("%d\t%d\n", num1, num2);
fclose(input);
}
The pattern ("%d %d") will match and assign two integers, separated by any number of whitespace characters.
Whitespace characters include your tab (\t), and newline (\n).