You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

271 lines
6.5 KiB

%{
//
// conf_parser.yxx
//
// This syntax analyzer is used to parse ht://Dig config
// files.
//
// Part of the ht://Dig package <http://www.htdig.org/>
// Copyright (c) 1999-2004 The ht://Dig Group
// For copyright details, see the file COPYING in your distribution
// or the GNU Library General Public License (LGPL) version 2 or later
// <http://www.gnu.org/copyleft/lgpl.html>
//
// $Id: conf_parser.yxx,v 1.8 2004/06/10 14:48:39 angusgb Exp $
//
#ifdef HAVE_CONFIG_H
#include "htconfig.h"
#endif /* HAVE_CONFIG_H */
/* Bison version > 1.25 needed */
/* TODO:
1. Better error handling
2. ?
*/
#include <stdio.h> /* for debug */
#include <stdlib.h>
#ifdef HAVE_STD
#include <iostream>
#ifdef HAVE_NAMESPACES
using namespace std;
#endif
#else
#include <iostream.h>
#endif /* HAVE_STD */
#include "HtConfiguration.h"
#include "htString.h"
/*#define YYDEBUG 1*/
#define YYPARSE_PARAM aConf
int yyerror(char *s);
int yylex(void);
#undef DEBUG
#ifdef DEBUG
int sn_debug=3;
#endif
%}
%union {
char *str;
ConfigDefaults *ConfLine;
HtConfiguration *ConfLines;
}
%token NUM T_DELIMITER T_NEWLINE T_RIGHT_BR T_LEFT_BR T_SLASH
%token <str> T_STRING T_KEYWORD T_NUMBER
%type <str> list
%type <ConfLine> simple_expression
%type <ConfLines> simple_expression_list
/* Grammar follows */
%%
input:
| input block { /* Whole config file */ }
;
block: simple_expression {
// name: value
((HtConfiguration *)aConf)->AddParsed($1->name,$1->value);
#ifdef DEBUG
if (sn_debug>=2) {
cout<<"Added to conf: "<<$1->name<<":"<<$1->value<<endl;
}
#endif
delete [] $1->name;
delete [] $1->value;
delete $1;
}
| complex_expression {
// <server www.gc.lviv.ua>
// server_max_docs: 456
// ... : ...
// </server>
}
| T_NEWLINE { /* Ignore empty lines */ }
;
simple_expression: T_KEYWORD T_DELIMITER T_STRING T_NEWLINE {
// locale: uk_UA.KOI8-U
//
// We can't do inserting into config
// here because we don't know if it's
// in complex expression or not.
$$=new ConfigDefaults;
$$->name = $1; $$->value=$3;
}
| T_KEYWORD T_DELIMITER T_NUMBER T_NEWLINE {
// max_head_length: 300000
//
$$=new ConfigDefaults;
$$->name = $1; $$->value=$3;
}
| T_KEYWORD T_DELIMITER list T_NEWLINE {
// bad_extensions: .XLS .xls .pdf .PDF .doc .DOC
//
$$=new ConfigDefaults;
$$->name = $1; $$->value=$3;
}
| T_KEYWORD T_DELIMITER T_NEWLINE {
// excude_urls:
//
$$=new ConfigDefaults;
$$->name = $1;
$$->value=new char[1];
*$$->value='\0';
}
;
complex_expression: T_LEFT_BR T_KEYWORD T_DELIMITER T_STRING T_RIGHT_BR T_NEWLINE simple_expression_list T_LEFT_BR T_SLASH T_KEYWORD T_RIGHT_BR T_NEWLINE {
// check if "<param> ... </param>" are equal
if (strcmp($2,$10)!=0) {
// todo: setup error string, return with error.
// Inform about line number
cerr<<"Brackets mismatch: Opened: "<<$2<<" Closed: "<<$10<<endl;
// exit(1);
}
// Oll right. Append set of parameters to object($2)
((HtConfiguration *)aConf)->Add($2,$4,$7);
#ifdef DEBUG
if (sn_debug >= 2) {
cout<<"Added to conf: "<<$2<<":"<<$4<<":"<<$7<<endl;
}
#endif
delete $2;
delete $4;
delete [] $10;
}
;
simple_expression_list: simple_expression {
//aaa: nnn
//bbb: ccc
// ...
//
// First entry. We need to create conf to store it.
HtConfiguration *expressionList=new HtConfiguration();
expressionList->AddParsed($1->name,$1->value);
$$=expressionList;
#ifdef DEBUG
if (sn_debug>=2) {
cout<<"Create list of properties: "<<expressionList<<endl;
}
#endif
delete $1->name;
delete $1->value;
delete $1;
}
| simple_expression_list simple_expression {
$1->AddParsed($2->name,$2->value);
#ifdef DEBUG
if (sn_debug>=2) {
cout<<$2->name<<":"<<$2->value<<" added to "<<$1<<endl;
}
#endif
delete $2->name;
delete $2->value;
delete $2;
//$$=$1; //I think $$==$1
}
| T_NEWLINE { /* Ignore empty lines */ }
;
list: T_STRING T_STRING {
// Paste 2 components. Reallocate memory for 2 components.
if (($$=new char[strlen($1)+strlen($2)+1+1])==NULL) {
fprintf(stderr,"Can't allocate memory\n");
exit(1);
}
strcpy($$,$1);
strcat($$," "); // Delimiter in list
strcat($$,$2);
delete [] $1;
delete [] $2;
}
| T_NUMBER T_STRING {
// Paste 2 components. Reallocate memory for 2 components.
if (($$=new char[strlen($1)+strlen($2)+1+1])==NULL) {
fprintf(stderr,"Can't allocate memory\n");
exit(1);
}
strcpy($$,$1);
strcat($$," "); // Delimiter in list
strcat($$,$2);
delete [] $1;
delete [] $2;
}
| T_STRING T_NUMBER {
// Paste 2 components. Reallocate memory for 2 components.
if (($$=new char[strlen($1)+strlen($2)+1+1])==NULL) {
fprintf(stderr,"Can't allocate memory\n");
exit(1);
}
strcpy($$,$1);
strcat($$," "); // Delimiter in list
strcat($$,$2);
delete [] $1;
delete [] $2;
}
| T_NUMBER T_NUMBER {
// Paste 2 components. Reallocate memory for 2 components.
if (($$=new char[strlen($1)+strlen($2)+1+1])==NULL) {
fprintf(stderr,"Can't allocate memory\n");
exit(1);
}
strcpy($$,$1);
strcat($$," "); // Delimiter in list
strcat($$,$2);
delete [] $1;
delete [] $2;
}
| list T_STRING {
char *old=$$;
if (($$=new char [strlen($$)+strlen($2)+1+1])==NULL) {
fprintf(stderr,"Can't reallocate memory\n");
exit(1);
}
strcpy($$,old);
delete [] old;
strcat($$," ");
strcat($$,$2);
delete [] $2;
}
| list T_NUMBER {
char *old=$$;
if (($$=new char [strlen($$)+strlen($2)+1+1])==NULL) {
fprintf(stderr,"Can't reallocate memory\n");
exit(1);
}
strcpy($$,old);
delete [] old;
strcat($$," ");
strcat($$,$2);
delete [] $2;
}
;
%%
int
yyerror (char *s) /* Called by yyparse on error */
{
extern int yylineno;
extern int include_stack_ptr;
extern String *name_stack[];
HtConfiguration* config= HtConfiguration::config();
String str;
if (include_stack_ptr > 0)
str = *name_stack[include_stack_ptr-1];
else // still at top level config
str = config->getFileName();
//fprintf (stderr, "%s\nIn line %d\n",s,yylineno);
fprintf(stderr,"Error in file %s line %d: %s\n",str.get(),yylineno,s);
// exit(1);
return -1;
}