New child language - (Function member address (structure))

Pages: 1... 678910... 20
Yeah, but it is because you're converting double to int, you should cast the pointer (unsafely let me say) to understand its real unsigned int value:

1
2
3
double Val = 123456.0;
cout << Val << endl;
cout << *(unsigned int *)(&Val) << endl;


And well, double to int in the built-in way is the fastest way.
Thinking in low-level operations, this isn't really fast, but it's the only way through.

Anyways let me show you the format of double and floating point values in the IEEE (common) format: http://steve.hollasch.net/cgindex/coding/ieeefloat.html
You have the table at the beggining of the "Storage Layout" section.
Last edited on
Ok, Hi everyone again, thanks all people, now I have to finish....!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! I'm going to come back someday...Pray... :)

Ok, Here're things I've done :
1
2
3
4
5
6
7
8
9
10
11
12
13
Basic operators (+); (-); (*); (/); (%); (=); (^); //power operator
Basic comparsion operators (>[=]); (<[=]); (==); (!=);
Unary expression (!)
Type cast [unsigned signed int double bool]
And - Or expression (&& - ||)
Parentheses ()
'char' to value
operator (expression) ? value : value
Fixed space ignoring...
Fixed bad memory allocation...
Fixed bad parsing method...

Speed : 3.000.000 characters per second (= three million)

Now I can write :
1
2
3
4
5
6
x = 10 + [unsigned int] 5 * 3 / 5 * 
(!(20 % 5) ? ((10 < 15) && (15 <= 20) || (20 > 2)) ? !(5 != 5) + 100)+
1+(1+(1+(1+(1+(1+(1+(8 = 10 ^5)-1)-1)-1)-1)-1)-1) / (2.5 * 3.14) =
1.05 / 5.00 +(1-(2 == 2) * 'h' - 'e' - 'l' - 'l' - 'o' + '  ' + 
'w' - 'o' - 'r' - 'l' - 'd') !!= 
('B' - 'y' - 'e' - ',' - 'p' - 'e' - 'o' - 'p' - 'l' - 'e' - '!' - '!' - '!')

=???
Last edited on
Ok, Hi everybody again, let's come back to helios's code :
Actually in my opinion It's really useful, although it doesn't run properly...
It gives me lots of knowledge and some new C++ things.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#include <cctype>
#include <cstdarg>
#include <cmath>
#include <iostream>
#include <sstream>
#include <stack>
#include <vector>

struct Token{
	enum TokenType{
		null=0,
		END=1,
		INTEGER='0',
		PLUS='+',
		MINUS='-',
		MUL='*',
		DIV='/',
		POW='^',
		LPAREN='(',
		RPAREN=')',
		expr=128
	} type;
	double intValue;
	Token(TokenType type=END):type(type),intValue(0){}
	Token(long val):type(INTEGER),intValue(val){}
	Token(char character){
		this->type=(TokenType)character;
	}
};

struct Rule{
	Token reduces_to;
	std::vector<Token> constraints;
	Token lookahead;
	Rule(const Token &to,const Token &la,unsigned constraints,...){
		this->reduces_to=to;
		this->lookahead=la;
		va_list list;
		va_start(list,constraints);
		this->constraints.reserve(constraints);
		for (unsigned a=0;a<constraints;a++)
			this->constraints.push_back(va_arg(list,Token::TokenType));
	}
	bool matches(const std::vector<Token> &stack,const Token &lookahead){
		if (stack.size()<this->constraints.size() ||
				this->lookahead.type!=Token::null && this->lookahead.type!=lookahead.type)
			return 0;
		const Token *array=&stack[stack.size()-this->constraints.size()];
		for (unsigned a=0,size=this->constraints.size();a<size;a++)
			if (array[a].type!=this->constraints[a].type)
				return 0;
		return 1;
	}
};

class Parser{
	std::stringstream stream;
	std::vector<Token> stack;
	bool result;
	std::vector<Rule> rules;
	Token read(){
		char character;
		while (!this->stream.eof() && isspace(character=this->stream.peek()))
			this->stream.get();
		if (this->stream.eof())
			return Token::END;
		character=this->stream.peek();
		if (isdigit(character)){
			std::string str;
		
			
			long temp=atol(str.c_str());
			return temp;
		}
		return (char)this->stream.get();
	}
	bool reduce(const Token &lookahead){
		long rule_index=-1;
		unsigned max=0;
		for (unsigned a=0;a<this->rules.size();a++){
			if (this->rules[a].matches(this->stack,lookahead) && this->rules[a].constraints.size()>max){
				rule_index=a;
				max=this->rules[a].constraints.size();
			}
		}
		if (rule_index<0 || this->rules[rule_index].reduces_to.type==Token::null)
			return 0;
		Rule &rule=this->rules[rule_index];
		Token new_token(rule.reduces_to);
		Token *redex=&this->stack[this->stack.size()-rule.constraints.size()];
		switch (rule_index){
			case 0: //expr <- INTEGER
				new_token.intValue=redex[0].intValue;
				break;
			case 1: //expr <- '(' expr ')'
			case 2: //expr <- '+' expr
				new_token.intValue=redex[1].intValue;
				break;
			case 3: //expr <- '-' expr
				new_token.intValue=-redex[1].intValue;
				break;
			case 4: //impossible
			case 5: //expr <- expr '^' expr
				new_token.intValue=pow((double)redex[0].intValue,(double)redex[2].intValue);
				break;
			case 6: //expr <- expr '*' expr
				new_token.intValue=redex[0].intValue*redex[2].intValue;
				break;
			case 7: //expr <- expr '/' expr
				new_token.intValue=redex[0].intValue/redex[2].intValue;
				break;
			case 8: //impossible
			case 9: //impossible
			case 10: //expr <- expr '+' expr
				new_token.intValue=redex[0].intValue+redex[2].intValue;
				break;
			case 11: //impossible
			case 12: //impossible
			case 13: //expr <- expr '-' expr
				new_token.intValue=redex[0].intValue-redex[2].intValue;
				break;
		}
		for (unsigned b=0;b<rule.constraints.size();b++)
			this->stack.pop_back();
		this->stack.push_back(new_token);
		return 1;
	}
	bool run_state(){
		Token next_token=this->read();
		while (this->reduce(next_token));
		switch (next_token.type){
			case Token::END:
				this->result=(this->stack.size()==1);
				return 0;
			case Token::INTEGER:
			case Token::PLUS:
			case Token::MINUS:
			case Token::MUL:
			case Token::DIV:
			case Token::RPAREN:
			case Token::LPAREN:
			case Token::POW:
				this->stack.push_back(next_token);
				return 1;
			default:
				this->result=0;
				return 0;
		}
	}
	void initializeRules(){
		this->rules.clear();
		/*rule 0*/	this->rules.push_back(Rule(	Token::expr,	Token::null,	1,	Token::INTEGER	));

		/*rule 1*/	this->rules.push_back(Rule(	Token::expr,	Token::null,	3,	Token::LPAREN,	Token::expr,	Token::RPAREN	));

		/*rule 2*/	this->rules.push_back(Rule(	Token::expr,	Token::null,	2,	Token::PLUS,	Token::expr	));
		/*rule 3*/	this->rules.push_back(Rule(	Token::expr,	Token::null,	2,	Token::MINUS,	Token::expr	));

		/*rule 4*/	this->rules.push_back(Rule(	Token::null,	Token::POW,		3,	Token::expr,	Token::POW,	Token::expr	));
		/*rule 5*/	this->rules.push_back(Rule(	Token::expr,	Token::null,	3,	Token::expr,	Token::POW,	Token::expr	));

		/*rule 6*/	this->rules.push_back(Rule(	Token::expr,	Token::null,	3,	Token::expr,	Token::MUL,	Token::expr	));

		/*rule 7*/	this->rules.push_back(Rule(	Token::expr,	Token::null,	3,	Token::expr,	Token::DIV,	Token::expr	));

		/*rule 8*/	this->rules.push_back(Rule(	Token::null,	Token::MUL,		3,	Token::expr,	Token::PLUS,	Token::expr	));
		/*rule 9*/	this->rules.push_back(Rule(	Token::null,	Token::DIV,		3,	Token::expr,	Token::PLUS,	Token::expr	));
		/*rule 10*/	this->rules.push_back(Rule(	Token::expr,	Token::null,	3,	Token::expr,	Token::PLUS,	Token::expr	));

		/*rule 11*/	this->rules.push_back(Rule(	Token::null,	Token::MUL,		3,	Token::expr,	Token::MINUS,	Token::expr	));
		/*rule 12*/	this->rules.push_back(Rule(	Token::null,	Token::DIV,		3,	Token::expr,	Token::MINUS,	Token::expr	));
		/*rule 13*/	this->rules.push_back(Rule(	Token::expr,	Token::null,	3,	Token::expr,	Token::MINUS,	Token::expr	));
	}
public:
	Parser(const std::string &str)
			:stream(str){
		this->result=0;
		this->initializeRules();
	}
	bool eval(double &res){
		while (this->run_state());
		if (this->result)
			res=this->stack.front().intValue;
		else
			this->stack.clear();
		return this->result;
	}
};

int main(){
	//Parser evaluator("2^2^2");// Original - Failed
	Parser evaluator("2+2+2"); //Failed
	double res=0;
	system("pause"); //Block code
	std::cout <<(evaluator.eval(res)?"ACCEPT":"ABORT")<<std::endl; //The loop goes here...
	std::cout <<res<<std::endl; // Is never reached 
	return 0;
}

Something I can see :
- Infinite loop (First)
- CPU : Always 99%
- Memory - 27mB -> 43Mb -> 75Mb -> 143 Mb- > 274 Mb... (Continuously grows up)...

Hey, but I don't really understand :

expr=128
//impossible (Why?)

rule.reduces_to //(variable)?
if (this->stream.eof()) //File?

va_list list;
va_start(list,constraints); //What is this? Function parameters?
Updated version: http://pastebin.com/rubzJBDR
Just adds a couple rules to give ^ the correct precedence, gets rid of variadic functions, and adds a read-eval-print loop.

Also, no. It doesn't not run properly.
Ok, thanks! I'll take them.
It works correctly. Thanks you!

My time measuring code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define HowMany 10000000 //10.000.000 //You can change it at any time

int nProgress = -1;
unsigned int t = clock();
///////////////////////////////////////////////////////////////
for(volatile unsigned int i = 0;i < HowMany;i++)
{
if(i % (Times / 100) == 0)
printf("Progress  : %d\n", ++nProgress);
//Commands...
// Parser evaluator ("2^2^2");
// double res=0;
// evaluator.eval(res);

}
///////////////////////////////////////////////////////////////
printf("Time : %.3f\n", (clock() - t) / 1000.0f);

Please, let's me know your CPU speed and the maximum-minimum speed that the Parser has ever reached with its duration.

First of all, a little thing about your code :

- How do you think about your code? In my point of view, it's quite difficult to continue developing next important features (Comparison, string detector, Hex value etc)...
- How many rules that the Parser in future will have? And.. super rules...???

Some trivial things I can see :) :
1
2
3
4
5
6
7
8
9
10
11
12
13
enum TokenType{
		null=0,
		END=1,
		INTEGER='0',
		PLUS='+',
		MINUS='-',
		MUL='*',
		DIV='/',
		POW='^',
		LPAREN='(',
		RPAREN=')',
		expr=128
	} type;


Please note that these characters have a very high value, and certainly they cause the program performs slower than normal at all...

1
2
3
4
5
6
7
8
9
10
11
12
enum TokenType{
		null=0,
		END=1,
		INTEGER=0,
		PLUS=1,
		//MINUS=2, //I think I should get rid of "minus"
		MUL=3,
		DIV=4,
		POW=5,
		LPAREN=6,
		RPAREN=7
	} type;


expr=128
That is the maximum number of expressions that the Parser can hold right?

Size(of) (Parser) : 176 - Rule size : (48) - Token size : (16)

Honestly, OH MY GOD!!! Why your parser needs so much memory..???

isdigit(character)

Actually, I don't really know about its speed, but the better one :
1
2
if(chr >= '0' && chr <= '9') //Instant result
chr -= '0';//Then... 
Last edited on
Finally, the Ultra-fast comparison method has been found!!!!!!!!!!!!!!

I have the code (which I made before) :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
char *IntToBit(long long int x, char *str, char *Temp){
	int nCount = 0;
	while(x)
	{
   if (x&1)
      str[nCount] = '1';
    else
      str[nCount] = '0';

	  nCount++;
    
    x>>=1;  
  }

  str[nCount] = 0;

	for(int i =0;i < nCount;i++)
	Temp[i] = str[nCount - 1 - i]; //Reverse order
	Temp[nCount] = 0;

	return Temp;
}


Now, I want to know the number binary bits (such as : '(')
The code gives :
101000


Then, use the formula l & (1 << i) to get the i'th bit.
Instead of :
if(56 == 40)

1st
1|1|1|0|0|0|
1|0|1|0|0|0|

2nd
1|1|1|0|0|
1|0|1|0|0|

3rd
1|1|1|0|
1|0|1|0|

4th
1|1|1|
1|0|1|

5th
1|1 //Wrong !!!
1|0 //Wrong !!!

6th
return 0;


So I'll only need to check a few bits, because I'm not going to hunt all characters. My targets are operators, so if my guess is right, it'll increase the parsing speed at least... 2x Faster!!!

What do you think about this idea? :)
Last edited on
Please note that these characters have a very high value, and certainly they cause the program performs slower than normal at all...


I really think you are trolling. Do you really think 1 + 2 takes longer than 5 + 5?

Honestly, OH MY GOD!!! Why your parser needs so much memory..???


Wat.

Finally, the Ultra-fast comparison method has been found!!!!!!!!!!!!!!


What is this method doing and why are you making the user pass variables for no reason? It doesn't even compare anything.
firedraco wrote:
Do you really think 1 + 2 takes longer than 5 + 5?

I said those are characters....so ('0' == '0') is slower (0 == 0)
Some trivial things I can see :) :

You may ignore this, but moreover, because of the code performance

firedraco wrote:
What is this method doing and why are you making the user pass variables for no reason? It doesn't even compare anything.


if my guess is right,


It works, but reducing the number of checking commands is better, also because of the code performance.
Wait. You're doing what? Am I to understand that you're trying to optimize integer comparison? If so, that's the biggest wastes of time I've ever heard of.

How do you think about your code? In my point of view, it's quite difficult to continue developing next important features (Comparison, string detector, Hex value etc)...
The parser is mostly a learning tool. It was never meant to be used for anything serious.
However, doing these things is not terribly difficult. Just a little more difficult than with, say, Bison.

Please note that these characters have a very high value, and certainly they cause the program performs slower than normal at all...
"Certainly"? How are you so sure?

Size(of) (Parser) : 176 - Rule size : (48) - Token size : (16)

Honestly, OH MY GOD!!! Why your parser needs so much memory..???
What are you talking about? Do you even understand how much memory this is?

Actually, I don't really know about its speed, but the better one :
Define "better".
Last edited on
Ok the first thing that I say...I don't really know much the new C++11 functions & features. Perhaps.
The current problem now is solving the compiling errors :

str.push_back(this->stream.get());
Line (74): error C2039: 'push_back' : is not a member of
 'basic_string<char,struct std::char_traits<char>,class std::allocator<char> >'


I replaced it with :
str += this->stream.get();
But most likely the code may be wrong.


helios wrote:
"Certainly"? How are you so sure?


1
2
3
4
5
for (unsigned a=0;a<this->rules.size();a++){
                            if (this->rules[a].matches(this->stack,lookahead) && this->rules[a].constraints.size()>max){
                                    rule_index=a;
                                    max=this->rules[a].constraints.size();
                            }

Those are 18 rules total (rule_index)...

Some of this :
//impossible ???

Now I have some examples :
1
2
3
//x = PLUS;
//x = '+';
//x = 43 

Maybe making a new specific enum for Token type is better.
Last edited on
NB : This post is redundant.... :)
//////////////////////////////////////////////////////////////////////

Let's versus!!!
I have some test examples :
1
2
3
x = 1+1+1+1+1+1+1+1+1+1
y = 1+(((((((((((((((((((((((((((1 * 10)))))))))))))))))))))))))))
z = (1+1)+((1+1)+(1+1))*10^2 + (1+1)+((1+1)+(1+1))/10^2

Let me know your statistics result. :)

My statistics : (10.000.000 loops)

x = 1+1+1+1+1+1+1+1+1+1

Result : 10
Time : 60.406 sec(s)
Length : 190.000.000
Speed : 165.546 (loops)
Characters per second : 3.166.666 (characters)


y = 1+(((((((((((((((((((((((((((1 * 10)))))))))))))))))))))))))))

Result : 11
Time : 352.184 sec(s)
Length : 620.000.000
Speed : 28.409 (loops)
Characters per second : 1.761.363 (characters)


z = (1+1)+((1+1)+(1+1))*10^2 + (1+1)+((1+1)+(1+1))/10^2

Result : 101.64
Time : 319.556 sec(s)
Length : 510.000.000
Speed : 31.293 (loops)
Characters per second : 1.595.964 (characters)
What are we comparing?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <chrono>
#include <cmath>

int main() {
   unsigned long long i;
   int x, y;
   double z;
   using std::chrono::duration_cast;
   using std::chrono::milliseconds;
   std::chrono::high_resolution_clock clock;
   
   auto start = clock.now();
   for (i = 0; i < 10000000; i ++)
      x = 1+1+1+1+1+1+1+1+1+1;
      
   auto end = clock.now();
   std::cout << "It took " << duration_cast<milliseconds>(end - start).count()
             << "ms to do " << i << " loops.\n";
   std::cout << "x = " << x << "\n\n";
   
   start = clock.now();
   for (i = 0; i < 10000000; i ++)
      y = 1+(((((((((((((((((((((((((((1 * 10)))))))))))))))))))))))))));
      
   end = clock.now();
   std::cout << "It took " << duration_cast<milliseconds>(end - start).count()
             << "ms to do " << i << " loops.\n";
   std::cout << "y = " << y << "\n\n";
   
   start = clock.now();
   for (i = 0; i < 10000000; i ++)
      z = (1+1)+((1+1)+(1+1))*pow(10, 2.0) + (1+1)+((1+1)+(1+1))/pow(10,2.0);
      
   end = clock.now();
   std::cout << "It took " << duration_cast<milliseconds>(end - start).count()
             << "ms to do " << i << " loops.\n";
   std::cout << "z = " << z << "\n\n";
   return 0;
}


It took 0ms to do 10000000 loops.
x = 10

It took 0ms to do 10000000 loops.
y = 11

It took 0ms to do 10000000 loops.
z = 404.04


Looks like C++ is a little faster...
Processor: 1.6 GHz Intel Atom
Compiler: g++ 4.7.2


Edit: It looks like the math is wrong for z on yours as well.

Edit2: Used cmath's pow function to increase accuracy.
Last edited on
Wow! You are right.
Actually I used a for-loop to multiply number * numbern-1... :)
Thanks you very much. The parser change is going to be applied now...

Edit : Also you should add the attribute word volatile before the definition type name of all testing variables.
Then give back and show me your result. :)
Last edited on
Jackson Marie wrote:
Edit : Also you should add the attribute word volatile before the definition type name of all testing variables.
Then give back and show me your result. :)


Haha, that's me, and I forgot -.-

But here is the same output with all variables as volatile:
It took 62ms to do 10000000 loops.
x = 10

It took 31ms to do 10000000 loops.
y = 11

It took 46ms to do 10000000 loops.
z = 404.04
'push_back' : is not a member of
'basic_string<char,struct std::char_traits<char>,class std::allocator<char> >'
What kind of ancient compiler are you using? push_back() has been part of std::string since C++98.
@helios
Once again, I am still using VS2005.
But, actually that compiler is VS2005 service pack 1 (I see the compiler about box). By that time before got the compiler, I had bought it.

Most likely it's a problem, I'm sure, because certainly it's outdated. :)
Last edited on
@Jackson Marie
Microsoft Visual Studio Express is free for 2010 and 2012. Why not update? At least you will get a more up to date compiler, and a few extra features all at no cost (See: http://www.microsoft.com/visualstudio/eng/downloads (scroll down a bit to Express)).

Or, you could upgrade to g++ (I hate MSVC++ compiler and IDE) and use a different, less cluttered IDE like Code::Blocks, again free.

@helios
I'm curious, what do you use? Text Editor or IDE? Compiler? OS?
Hows all this going miss Jackson Marie?

When can i test it?
I'm curious, what do you use? Text Editor or IDE? Compiler? OS?
It depends on what I'm doing.
For quick tests that I don't expect will need much debugging, I just write in Notepad++ and compile with GCC from the command line. For everything else, I use VC++. On the few occasions I was forced by the circumstances to code/debug on Linux, I used Eclipse. I really like how detailed the configuration is, and it almost makes gdb usable.

I've also tried Clang. I, the particular codebase I tried, didn't notice a significant difference in the performance of the output vs. VC++ or GCC, but the compiler messages are definitely of higher quality. If nothing else, as a static analyzer it's probably the best out there.
@helios
In regards to using N++ with gcc, have you looked into the built in command line features? I don't remember the name of it anymore, but it was perfect for building, compiling, running, etc. You can even type custom commands in it. I mainly used it for compilation with my header files or single files. I had also mapped certain commands to the right click context menu so that once I was happy, I right clicked, selected Compile & Run, which autosaved my file, compiled it, and ran it in the command line at the bottom of N++. It was nifty to test quick examples in an extremely lightweight environment.

In regards to VC++, I hate it. I've used it, it's a memory hog, slow as molasses on my computer, and feels so bloated (great for extremely large projects). Have you ever tried C::B? It defaults to using g++ (since you already have it installed, you just need to add it to the toolchain exes) and feels smoother than N++ and only a little more power hungry, it is a full blown IDE btw.

I used Eclipse once or twice (on Windows) but wasn't found of not being able to compile a small Hello World application. Apparently to get a compiler to work on windows with it took a lot of steps and I just gave up.

That's all just my 2 cents.
Pages: 1... 678910... 20