-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBinaryProductions.C
135 lines (94 loc) · 2.78 KB
/
BinaryProductions.C
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
/****************************************************************
BinaryProductions.C
Copyright (C)2014 William H. Majoros ([email protected]).
This is OPEN SOURCE SOFTWARE governed by the Gnu General Public
License (GPL) version 3, as described at www.opensource.org.
****************************************************************/
#include <iostream>
#include "BinaryProductions.H"
using namespace std;
using namespace BOOM;
const HASH_SIZE=499;
BinaryProductions::BinaryProductions()
{
// ctor
}
BinaryProductions::BinaryProductions(SCFG &G,Alphabet &alpha)
{
init(G,alpha);
}
void BinaryProductions::initNonTermMap(HashMap<GrammarSymbol,int> &
nonterminalMap,SCFG &G)
{
GrammarAlphabet &nonterminals=G.getNonterminals();
numNonterminals=nonterminals.size();
for(int i=0 ; i<numNonterminals ; ++i)
nonterminalMap[*nonterminals[i]]=i;
}
void BinaryProductions::init(SCFG &G,Alphabet &alpha)
{
terminals=alpha;
HashMap<GrammarSymbol,int> nonterminalMap(HASH_SIZE);
initNonTermMap(nonterminalMap,G);
startSymbol=nonterminalMap[*G.getStart()];
processGrammar(G,nonterminalMap);
}
void BinaryProductions::processGrammar(SCFG &G,HashMap<GrammarSymbol,int>
&nonterminalMap)
{
const int numTerms=terminals.size();
terminalProbs.resize(numTerms);
Vector<Production*> &rawProds=G.getProductions();
Vector<BinaryProduction> V;
for(Vector<Production*>::iterator cur=rawProds.begin(), end=rawProds.end() ;
cur!=end ; ++cur) {
Production &rawProd=**cur;
GrammarSymbol *lhs=rawProd.getLHS();
const int lhsID=nonterminalMap[*lhs];
Vector<GrammarSymbol*> &rhs=rawProd.getRHS();
const float P=rawProd.getProbability();
if(rhs.size()==1) {
int term=terminals.lookup(rhs[0]->getLexeme()[0]);
NonterminalProb ntProb(lhsID,P);
terminalProbs[term].push_back(ntProb);
}
else {
if(rhs.size()!=2) throw "Grammar is not in CNF";
const int rhs1=nonterminalMap[*rhs[0]];
const int rhs2=nonterminalMap[*rhs[1]];
productions.push_back(BinaryProduction(lhsID,rhs1,rhs2,P));
}
}
}
int BinaryProductions::numProductions() const
{
return productions.size();
}
BinaryProduction &BinaryProductions::production(int i)
{
return productions[i];
}
Vector<NonterminalProb> &BinaryProductions::terminal(int terminalID)
{
return terminalProbs[terminalID];
}
Vector<BinaryProduction>::const_iterator BinaryProductions::begin() const
{
return productions.begin();
}
Vector<BinaryProduction>::const_iterator BinaryProductions::end() const
{
return productions.end();
}
int BinaryProductions::getNumNonterminals() const
{
return numNonterminals;
}
int BinaryProductions::getStartSymbol() const
{
return startSymbol;
}
Alphabet &BinaryProductions::getTerminals()
{
return terminals;
}