之前因为早已遗忘了lex和yacc,所以这次花的时间久了些,废话不多说,直接贴代码。
lex.l
%{
#include "parse.h"
extern "C" {
int yywrap(void);
int yylex(void);
}
extern int context_flag;/* 0 - not in any atom, 1 - in an atom*/
%}
blank [ \n\t\r]*
atom [a-zA-Z0-9_]+
%%
{atom} {
yylval.s=strdup(yytext);
// if(strcmp(yytext, "not") == 0)
// return S_NEGA;
return S_ATOM;
}
"->" {return S_IMPL; }
"~" {return S_NEG; }
"(" {return LPAREN; }
")" {return RPAREN; }
"&" {return S_CONJ; }
"|" {return S_DISJ; }
"." {return PERIOD; }
{blank} {/* skip blankspace */ }
%%
int yywrap()
{
return 1;
}
yacc.y
%{
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <vector>
#include "Vocabulary.h"
#include "structs.h"
#include "Formula.h"
extern "C" {
void yyerror(const char *s);
extern int yylex(void);
}
extern vector<Formula> iniformula;
int id;
void yyerror(const char* s)
{
printf("Parser error: %s\n", s);
}
%}
%union {
char* s;
struct __formula* f;
}
%token <s> S_ATOM
%token <s> S_NEG
%token <s> S_IMPL
%token <s> LPAREN
%token <s> RPAREN
%token <s> S_DISJ
%token <s> S_CONJ
%token <s> PERIOD
%type <s> atom
%type <f> formula
%type <f> term
%left S_IMPL
%left S_DISJ S_CONJ
%%
results
: results formulas {
}
| formulas {
}
;
formulas
: term PERIOD
{
//printf("formulas\n");
Formula fo($1);
iniformula.push_back(fo);
}
term
: formula{
}
| LPAREN term RPAREN{
$$ = $2;
}
| term S_IMPL term{
$$ = (__formula*)malloc(sizeof(_formula));
$$ -> formula_type=IMPL;
$$ -> subformula_l = $1;
$$ -> subformula_r = $3;
//printf("IMPL\n");
}
|
term S_CONJ term{
$$ = (__formula*)malloc(sizeof(_formula));
$$ -> formula_type=CONJ;
$$ -> subformula_l = $1;
$$ -> subformula_r = $3;
//printf("conj\n");
}
| term S_DISJ term{
$$ = (__formula*)malloc(sizeof(_formula));
$$ -> formula_type=DISJ;
$$ -> subformula_l = $1;
$$ -> subformula_r = $3;
//printf("disj\n");
}
formula
: S_NEG atom {
int id = Vocabulary::instance().queryAtom($2);
if(id < 0)
id = Vocabulary::instance().addAtom($2);
$$ = (__formula*)malloc(sizeof(_formula));
$$->predicate_id = id;
$$->formula_type=NEGA;
//printf("s_nega\n");
}
| atom {
int id = Vocabulary::instance().queryAtom($1);
if(id < 0)
id = Vocabulary::instance().addAtom($1);
$$ = (__formula*)malloc(sizeof(_formula));
$$->predicate_id = id;
$$->formula_type=ATOM;
//printf("formalu\n");
}
;
atom
: S_ATOM {
$$ = strdup($1);
//printf("atom\n");
}
;
%%
执行(注:ubantu下开发)
lex -o ../src/lex.cpp lex.l
yacc --defines=../src/parse.h -o ../src/parse.cpp parse.y
structs.h
#ifndef STRUCTS_H
#define STRUCTS_H
#define MAX_ATOM_LENGTH 512
#define MAX_ATOM_NUMBER 1024
#include <map>
#include <set>
#include <vector>
// Type definition
enum FORMULA_TYPE {
ATOM = 0, //atom
NEGA, //negation
CONJ, //conjunction
DISJ, //disjunction
IMPL, //implication
};
// Structures
typedef struct __formula {
FORMULA_TYPE formula_type;
union {
__formula* subformula_l; //NEGA,CONJ,DISJ,IMPL
int predicate_id; //ATOM
};
union {
__formula* subformula_r; //CONJ,DISJ,IMPL
};
}_formula;
#endif
Formula.h
<pre name="code" class="cpp">#include <cstdio>
#include <cstdlib>
#include <vector>
#include "structs.h"
#include "Vocabulary.h"
#ifndef FORMULA_H
#define FORMULA_H
class Formula {
public:
_formula *l;
_formula *r;
int id;
FORMULA_TYPE formula_type;
public:
Formula();
Formula(_formula* fml);
Formula(FORMULA_TYPE fn,_formula* fl,_formula* fr);
~Formula();
Formula& operator = (const Formula& _rhs);
void CONJ_f(_formula* fml);
_formula* convertto_f();
void add_Formula(FORMULA_TYPE ,_formula* );
void outp(int i);
};
#endif /* FORMULA_H */
Formula.cpp
#include <cstdio>
#include <cstdlib>
#include <vector>
#include "structs.h"
#include "Formula.h"
#include "Vocabulary.h"
Formula::Formula()
{
l=NULL;
r=NULL;
formula_type = ATOM;
id=-1;
}
Formula::Formula(_formula* fml)
{
formula_type = fml->formula_type;
switch(formula_type)
{
case ATOM:
case NEGA:
id = fml->predicate_id;
break;
case CONJ:
case DISJ:
case IMPL:
l=fml->subformula_l;
r=fml->subformula_r;
break;
}
}
Formula::Formula(FORMULA_TYPE fn,_formula* fl,_formula* fr)
{
l = fl;
r = fr;
formula_type = fn;
}
Formula::~Formula()
{
id=-1;
}
Formula& Formula::operator = (const Formula& _rhs)
{
formula_type = _rhs.formula_type;
switch(formula_type)
{
case ATOM:
case NEGA:
id = _rhs.id;
break;
case CONJ:
case DISJ:
case IMPL:
l=_rhs.l;
r=_rhs.r;
break;
}
}
_formula* Formula::convertto_f()
{
_formula *f =(__formula*)malloc(sizeof(_formula));
f->formula_type = formula_type;
switch(formula_type)
{
case ATOM:
case NEGA:
f->predicate_id = id;
break;
case CONJ:
case DISJ:
case IMPL:
f->subformula_l= l;
f->subformula_r=r;
break;
}
return f;
}
void Formula::add_Formula(FORMULA_TYPE fn,_formula *fml)
{
formula_type = fn;
switch(formula_type)
{
case ATOM:
case NEGA:
break;
case CONJ:
case DISJ:
case IMPL:
l = convertto_f();
r = fml;
break;
}
}
void Formula::CONJ_f(_formula* fml)
{
add_Formula(CONJ,fml);
}
void Formula::outp(int i)
{
switch(formula_type)
{
case ATOM:
printf( "%d%s", i, Vocabulary::instance().getAtom(id));
break;
case NEGA:
printf( "%d~%s", i, Vocabulary::instance().getAtom(id));
break;
case CONJ:
i++;
Formula(l).outp(i);
printf( " & ");
Formula(r).outp(i);
break;
case DISJ:
i++;
Formula(l).outp(i);
printf( " | ");
Formula(r).outp(i);
break;
case IMPL:
i++;
Formula(l).outp(i);
printf( " -> ");
Formula(r).outp(i);
break;
break;
}
}
main.cpp
#include <cstdlib>
#include <cstdio>
#include <assert.h>
#include "Vocabulary.h"
#include "Formula.h"
#include <set>
#include <iostream>
#include <unistd.h>
#include <fstream>
#include <string>
#include <sstream>
#include <ctime>
using namespace std;
extern FILE* yyin;
extern FILE* yyout;
vector<Formula> iniformula;
extern int yyparse();
int main(int argc, char** argv) {
yyin = fopen("res/input/sample.in", "r");
//yyout = fopen("res/output/sample.out", "w+");
yyparse();
fclose(yyin);
for(int i=0;i<iniformula.size();i++)
{
iniformula[i].outp(0);
cout<<endl;
}
return 0;
}
结束~