Lex : All ways meet error at Rules Section - lex

I started to use Lex for my homework. In my Lex file, I always meet errors when go to first line of Rules Section. I have tested on sample code in books.
Here is the errors that Flex throw :
1 Error: Parse error at line
2 Description: Badly formed macro definition.
And here is my code.
int num_lines = 0, num_chars = 0;
%%
\n ++num_lines; ++num_chars; // error here
. ++num_chars;
%%
main()
{
yylex();
printf( "# of lines = %d, # of chars = %d\n",
num_lines, num_chars );
}
Thanks :)

Try
%{
int num_lines = 0, num_chars = 0;
%}
%%
...

Related

How can I solve "lex program for the pattern that starts with vowel, ends with consonant and might have digits too"

I have tried to solve this question "Write a lex program for the pattern that starts with vowel, ends with consonant and might have digits too."
Here is my code:
%{
#include<stdio.h>
#include<string.h>
int cno=0, wno=0, lno=o;
%}
character [a-zA-z]
digit [0-9]
word({character}|{digit})+
line\n
%%
{line}{cno++;lno++;}
{line}{wno++; cno+=strlen(yytext);}{cno++;}
%%
int main(void)
{
yylex();
print("Count alphanumeric pattern: %d;", cno);
print("Length of string: %d;", wno);
print("Line numbers: %d\n", lno);
return 0;
}
Here is the output:
line 23: unrecognized rule
line 23: fatal parse error
I think the following code will solve your problem.
%{
int valid_patterns = 0, invalid_patterns =0;
%}
PATTERN ([aeiouAEIOU][A-Za-z0-9]*[b-df-hj-np-tv-zB-DF-HJ-NP-TV-Z])*
%%
{PATTERN} {printf("\n\t Pattern Matched: %s", yytext); valid_patterns++;}
[A-Za-z0-9]+ {invalid_patterns++;}
"\n" {
printf("\n\n\t Total Matched Patterns : %d", valid_patterns);
printf("\n\t Total Unmatched Patterns: %d\n", invalid_patterns);
valid_patterns = 0; invalid_patterns = 0;
}
%%
/*** User code section***/
int yywrap(){}
int main(int argc, char **argv[])
{
printf("\n Enter your inputs: \n\n");
yylex();
return 0;
}
Explanation of the first rule for PATTERN as per your questions requirements:
[aeiouAEIOU] make sure a pattern starts with a vowel.
[A-Za-z0-9]* indicates that any alphanumeric character can occur in middle.
[b-df-hj-np-tv-zB-DF-HJ-NP-TV-Z] make sure a pattern ends with a consonant.
(...)* indicates there might be 0 or more occurrence of desire pattern.
The second rule [A-Za-z0-9]+ catches any other input that doesn't match the requirements. And the final rule "\n"takes action when you input a new line, it prints information about your inputs.
An I/O example---
Input: Hello amazing people around the world
Output:
Pattern Matched: amazing
Pattern Matched: around
Total Matched Patterns : 2
Total Unmatched Patterns: 4

Lex program to count number of Vowels and Consonants doesnot to terminate even after end of input

I have written a simple program to count number of vowels and consonants in LEX. But the program does not terminate after I enter input and enters an infinite loop. Here's the program
%{
#include<stdio.h>
int vow_count = 0;
int const_count = 0;
%}
%%
[aeiouAEIOU] {vow_count++;}
[a-zA-Z] {const_count++;}
%%
int yywrap(){return 1;}
int main()
{
printf("Enter a string : ");
yylex();
printf("\n No. of vowels = %d", vow_count);
printf("\n No. of consonants = %d\n", const_count);
return 0;
}
Here's the output
I have tried almost everything, I have tried with "%option noyywrap", without the yywrap() function.
Also the the program works fine when I take input from a file.
Use getch(); after the last printf statement in the main function. Also, after giving your input in the command prompt, press Ctrl+Z. I'm using Windows, it worked for me.
You have to press ctrl + d to terminate.
After pressing ctrl + d you will get the below output.

scanf hangs when copy and paste many line of inputs at a time

This may be a simple question, but I'm new to C, and yet couldn't find any answer. My program is simple, it takes 21 lines of string input in a for loop, and print them after that. The number could be less or greater.
int t = 21;
char *lines[t];
for (i = 0; i < t; i++) {
lines[i] = malloc(100);
scanf("%s", lines[i]);
}
for (int i = 0; i < t; i++) {
printf("%s\n", lines[i]);
free(lines[i]);
}
...
So when I copy & paste the inputs at a time, my program hangs, no error, no crash. It's fine if there's only 20 lines or below. And if I enter by hand line by line, it works normally regardless of number of inputs.
I'm using XCode 5 in Mac OS X 10.10, but I don't think this is the issue.
Update:
I tried to debug it when the program hangs, it stopped when i == 20 at the line below:
0x7fff9209430a: jae 0x7fff92094314 ; __read_nocancel + 20
The issue may be related to scanf, but it's so confused, why the number 20? May be I'm using it the wrong way, great thanks to any help.
Update:
I have tried to compile the program using the CLI gcc. It works just fine. So, it is the issue of XCode eventually. Somehow it prevents user from pasting multiple inputs.
Use fgets when you want to read a string in C , and see this documentation about that function:
[FGETS Function]
So you should use it like this :
fgets (lines[i],100,stdin);
So it'll get the string from the input of the user and you can have a look on these two posts as well about reading strings in C:
Post1
Post2
I hope that this'll help you with your problem.
Edit :
#include <stdio.h>
void main(){
int t = 21;
int i;
char *lines[t];
for (i = 0; i < t; i++) {
lines[i] = malloc(100);
fgets(lines[i],255,stdin);
}
for (i = 0; i < t; i++) {
printf("String %d : %s\n",i, lines[i]);
free(lines[i]);
}
}
This code gives :
As you can see , I got the 21 strings that I entered (From 0 to 20, that's why it stops when i==20).
I tried with your input ,here's the results :
I wrote the same code and ran. It works.
It might contain more than 99 characters (include line feed) per line...
Or it might contain spaces and tabs.
scanf(3)
When one or more whitespace characters (space, horizontal tab \t, vertical tab \v, form feed \f, carriage return \r, newline or linefeed \n) occur in the format string, input data up to the first non-whitespace character is read, or until no more data remains. If no whitespace characters are found in the input data, the scanning is complete, and the function returns.
To avoid this, try
scanf ("%[^\n]%*c", lines[i]);
The whole code is:
#include <stdio.h>
int main() {
const int T = 5;
char lines[T][100]; // length: 99 (null terminated string)
// if the length per line is fixed, you don't need to use malloc.
printf("input -------\n");
for (int i = 0; i < T; i++) {
scanf ("%[^\n]%*c", lines[i]);
}
printf("result -------\n");
for (int i = 0; i < T; i++) {
printf("%s\n", lines[i]);
}
return 0;
}
If you still continue to face the problem, show us the input data and more details. Best regards.

How to search a specific word in lex given a input file?

I am very new to lex. I am trying to develop a parser to search a count of specific word in an given input file...
My code is
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int lnum = 1, fresult = 0, cc=0, wc=0, lc=0, bc=0, sc=0, nc=0, tc=0, result;
char temp[20], str[20], fname[20];
FILE *fp;
#undef yywrap
%}
digit[0-9]+
word [a-zA-Z]+
eol [\n]
blank [ ]
tab [\t]
result [word]
%%
{result} {
if((strstr(temp, str)) != 0)
{
printf(" A match found on line: %d\n", lnum);
fresult++;
wc++;
cc+=yyleng;
}
lnum++;
if(fresult == 0)
{
printf(" Match not found\n");
}
}
{digit} {nc++;}
{word} {wc++; cc+=yyleng;}
{tab} {tc++;}
{blank} {bc++;}
{eol} {lc++;}
. sc++;
%%
int main(int argc, char *argv[])
{
strcpy(fname,argv[1]);
strcpy(str,argv[2]);
fp=fopen(fname,"r+");
yyin=fp;
yylex();
printf(" Total count of the word is :%d\n", fresult);
printf(" Character Count = %d\n", cc);
printf(" Number Count = %d\n", nc);
printf(" Word Count = %d\n", wc);
printf(" Line Count = %d\n", lc);
printf(" Special Character Count = %d\n", sc);
printf(" Blank Count = %d\n", bc);
printf(" Tab Count = %d\n", tc);
return(0);
}
int yywrap()
{
return -1;
}
The word count and others are working perfectly.... But the word search is taking the input but not given the specific count...... How can I improve the code?
Should I need to add anything?
Thanks in Advance...... :)
I have made some changes to your code to help you in the right direction. First, I created a variable to keep track of whether a match is found or not.
Secondly, I am not using strstr() anymore and instead I am using strcmp() because you want to match a word to a word not a word within a sentence and we do not need a pointer returned. strcmp() is nice because we just get an integer.
I see what you were trying to do with result [word] however, as you found out, this will not work. This section of the Flex file is known as the rules section. Here you use the regular expressions that you defined in the above section (definitions) to tell Flex what to do when a rule is matched.
As you can see, I have deleted all occurrences of result[word] - as this will not work. In the rules section, I also deleted the result definition because we no longer have a rule to match it. However, I keep the code for the result definitions and simply apply it to the word definition.
The last major change is adding the <<EOF>> rule which is a special rule that tells Flex what to do when it has encountered the end of the file. In our case, if the match variable is not 1, then we have not found a match and we would like to print this to the screen. We also need to call yyterminate() (definition at the bottom of the page) to stop the lexical analyzer.
Below is the updated code. I hope that helps!
%{
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int lnum = 1, fresult = 0, cc=0, wc=0, lc=0, bc=0, sc=0, nc=0, tc=0, result;
char temp[20], str[20], fname[20];
FILE *fp;
int match = 0;//For keeping track of matches
#undef yywrap
%}
/*Rules*/
digit [0-9]+
word [a-zA-Z]+
eol [\n]
blank [ ]
tab [\t]
/*Definitions*/
%%
{digit} {
nc++;
}
{tab} {
tc++;
}
{blank} {
bc++;
}
{eol} {
lc++;
}
{word} {
if((strcmp(yytext, str)) == 0)//We found a match
{
printf("\n A match found on line: %d\n", lnum);
fresult++;
wc++;
cc+=yyleng;
match = 1;//We have a match
}
else //We found a word, but it was not a match
{
wc++;
}
}
. {
sc++;
}
<<EOF>> {
if(!match)
{
printf(" Match not found\n");
}
yyterminate();
}
%%
int main(int argc, char *argv[])
{
strcpy(fname,argv[1]);
strcpy(str,argv[2]);
fp = fopen(fname,"r+");
yyin = fp;
yylex();
printf("\n\n Total count of the word is :%d\n", fresult);
printf(" Character Count = %d\n", cc);
printf(" Number Count = %d\n", nc);
printf(" Word Count = %d\n", wc);
printf(" Line Count = %d\n", lc);
printf(" Special Character Count = %d\n", sc);
printf(" Blank Count = %d\n", bc);
printf(" Tab Count = %d\n", tc);
fclose(fp);
return(0);
}
int yywrap()
{
return 1;
}
{result} {
if((strstr(temp, str)) != 0)
result [word]
Result is a regex for the characters 'w', 'o', 'r', 'd', which is not what you want. You probably want to match on {word}. In addition, temp will always be null - I think you want to use yytext instead.

How to add character to content of post?

In per posts, there are "oo/x/".
How to add "0" before "x" if length(x) <10 ?
Example:
x=12345678 ; length(x) = 8, so add "00" before x ===> x=0012345678
x=1234567 ; length(x) = 7, so add "000" before x ===> x=0001234567
x=123456789 ; length(x) = 9, so add "0" before x ===> x=0123456789
Do you understand ? Sorry for my poor English ! Thank you very much !
In ANSI C:
#include <stdio.h>
int main()
{
int x = 12345678;
printf("x = %010d\n", x);
return 0;
}
Note the %010d, where % is a format specifier which will be replaced by a following argument, the 0 being a flag which pads 0's, and the maximum number of 0's.
Read more here - printf()
If this is for Java, you can do this using System.out.printf(); in the same way.
EDIT: Now that it's clear on where the problem domain lies (in this case WordPress), then you can use PHP.
See the following barebones example using sprintf() in PHP:
<?php
// ...
$x = 12345678;
$yourString = sprintf(nl2br("x = %010d\n"), $x);
// ...
echo $yourString;
?>
How you are printing out the values depends on how you're retrieving your information and your layout, but this is a simple example that answers the question.