Author: Gerd Isenberg
Date: 06:32:07 02/05/05
Go up one level in this thread
On February 05, 2005 at 04:51:35, Uri Blass wrote:
>I want to have a loop on all the legal FEN of tablebases positions (at least fen
>of 4 pieces) in order to debug my code to use tablebases and also to debug the
>function that I plan to write that should check if a FEN is legal.
>
>I gave the source code of movei to Dann Corbit and he wrote for me a function
>that does part of it that is not based on the rest of the code of movei but it
>does not check things like if the side to move can capture the opponent king and
>I find the program hard to understand because for some reason Dann used a lot of
>char ** that I never use in movei.
>
>It may be because of my lack of knowledge in programming but I see no reason to
>use ** for tasks like that and I see no advantage in it and it only cause
>problems in understanding such a code.
>
>I understand that ** should be pointer to pointer but not more than it and
>I have no experience with code like that.
>
>I think simply to read the FEN string char after char and collect information
>when I never need to go backward in the string when Dann's code does not do it
>and in order to check if there is a single king it simply count K in the
>relevant part of the string that is called piece_placement
>
>It is used as char ** in one function tokenize_position_string and as char * in
>another function setup that calls tokenize_position_string(I guess that the
>computer simply translate char* to char **)
>
>
>I still do not fully understand the code that Dann wrote for me at this
>moment(note that this code has nothing to do with the moves of the engine and it
>is only about checking the FEN that the program does not use during games) and I
>feel that I spend too much time about trying to understand things that are not
>relevant to the playing strength.
>
>I think that I will write my own code for that task instead of Dann's code and
>I already started with it.
>
>I wonder if you do it.
>
>Uri
Hi Uri,
char** is quite common in C syntax parsers.
You may have a char* pointer to the string to be parsed.
This char* is incremented during the process, but you may have several
(recursive) instances of routines using the pointer, eg. expression, sum and
product for a simple const-expression syntax parser. Therefore you have to pass
a reference (or pointer) to the char* pointer to the routines.
The problem in C is, if you want to avoid globals, there is no way to share a
pointer between instances of several functions other than passing a pointer or
reference of a pointer as paramter around.
In C++ one may encapsulate the char* and all functions working on it inside a
class or struct.
Following on the fly bnf-parser to make that clear.
(to keep it simple no white space handling and only +|* operators)
exp ::= sum [ "+" sum]...
sum ::= pro [ "*" pro]...
pro ::= const | "(" exp ")"
const ::= digit [digit]...
digit ::= "0"..."9"
int exp (char **pptr)
{
int e = sum (pptr);
char* ptr = *pptr; // get current pointer
while (*ptr == '+')
{
ptr++;
pptr = &ptr;
e += sum (pptr);
ptr = *pptr;
}
pptr = &ptr; // current pointer back
return e;
}
int sum (char **pptr)
{
int s = pro (pptr);
char* ptr = *pptr; // get current pointer
while (*ptr == '*')
{
ptr++;
pptr = &ptr;
s *= pro (pptr);
ptr = *pptr;
}
pptr = &ptr; // current pointer back
return s;
}
int pro (char **pptr)
{
int r;
char* ptr = *pptr; // get current pointer
if ( *ptr == '(')
{
ptr++;
pptr = &ptr;
r = exp(pptr);
ptr = *pptr;
if (*ptr != ')')
throw syntaxError;
ptr++;
pptr = &ptr; // current pointer back
}
else
{
if ( !isDigit(*ptr))
throw syntaxError;
r = 0;
do
{
r = r*10 + *ptr - '0'; // ascii2int
ptr++;
}
while (isDigit(*ptr));
pptr = &ptr; // current pointer back
}
return r;
}
// same with a C++ class
class CMySimpleParser
{
char* m_ptr;
...;
int exp ()
{
int e = sum ();
while (*m_ptr == '+')
{
m_ptr++;
e += sum ();
}
return e;
}
int sum ()
{
int s = pro ();
while (*m_ptr == '*')
{
m_ptr++;
s *= pro ();
}
return s;
}
int pro ()
{
int r;
if ( *m_ptr == '(')
{
m_ptr++;
r = exp();
if (*m_ptr != ')')
throw syntaxError;
m_ptr++;
}
else
{
if ( !isDigit(*m_ptr))
throw syntaxError;
r = 0;
do
{
r = r*10 + *m_ptr - '0'; // ascii2int
m_ptr++;
}
while (isDigit(*m_ptr));
}
return r;
}
}; // class
Cheers,
Gerd
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.