-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpartylist.y
132 lines (97 loc) · 2.78 KB
/
partylist.y
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
%define api.prefix {pl}
%parse-param {const char* filename}
%parse-param {panachage::partylist& pl}
%{
#include "yacc_tools.h"
#include "partylist.cpp"
#define YY_DEFAULT_TEMP_PLNAME ""
#define YY_DEFAULT_TEMP_PLID 1
#define YY_DEFAULT_TEMP_ALV 0
extern int pllex();
static std::string yy_temp_plname = YY_DEFAULT_TEMP_PLNAME;
static panachage::partylist::id_type yy_temp_plid = YY_DEFAULT_TEMP_PLID;
static int yy_temp_alv = YY_DEFAULT_TEMP_ALV;
inline void plerror(const char *filename, panachage::partylist &pl, char const *s)
{
yacc_error(filename, s, "party list", yyin, yylineno, yycolumn, yyleng, yytext);
}
%}
%code requires {
#include "vote.hpp"
#include "partylist.cpp"
#include "lex_utils.h"
namespace panachage {
std::string nameFromFile(const char *filename, const char *ext = ".txt");
partylist parsePartyListFile(const char *filename, const char *ext = ".txt");
}
}
%define parse.error verbose
%union {
char *s;
char c;
int i;
}
%type <i> cand_id cand_votes
%token init_cmd
%token opt_name
%token opt_id
%token opt_alv
%token <s> cand_name
%token <s> text
%token <i> plnumber
%start start
%%
start : options init candidates ;
// Options
options : option
| options option
;
option : opt_name '=' text { yy_temp_plname = $3; }
| opt_id '=' plnumber { yy_temp_plid = $3; }
| opt_alv '=' plnumber { yy_temp_alv = $3; }
;
// Initiator
init : init_cmd { pl = panachage::partylist(yy_temp_plid, yy_temp_plname);
pl.at_large_votes = yy_temp_alv;
}
;
// Candidates
candidates : candidate
| candidates candidate
;
candidate : cand_id cand_name cand_votes { pl.newCandidate($1, $3); }
| cand_id cand_votes { pl.newCandidate($1, $2); }
| cand_id { pl.newCandidate($1); }
;
cand_id : '#' plnumber { $$ = $2; } ;
cand_votes : '+' plnumber { $$ = $2; } ;
%%
namespace panachage {
std::string nameFromFile(const char *filename, const char *ext)
{
char name[strlen(filename)];
strcpy(name, filename);
sanitize_path(name);
if (strstr(filename, ext))
{
int dot_index = strlen(name) - strlen(ext);
name[dot_index] = 0;
}
return std::string(name);
}
partylist parsePartyListFile(const char *filename, const char *ext)
{
yy_temp_plid = YY_DEFAULT_TEMP_PLID;
yy_temp_alv = YY_DEFAULT_TEMP_ALV;
yy_temp_plname = YY_DEFAULT_TEMP_PLNAME;
yy_temp_plname = nameFromFile(filename, ext);
RESET_BUFFER;
yyin = fopen(filename, "r");
partylist pl;
if (!yy_doesFileExist(filename, yyin))
return pl;
plparse(filename, pl);
fclose(yyin);
return pl;
}
}