1/* 2 * cdlParser.yy 3 * 4 * Copyright 2014-2018 D. Mitch Bailey cvc at shuharisystem dot com 5 * 6 * This file is part of cvc. 7 * 8 * cvc is free software: you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation, either version 3 of the License, or 11 * (at your option) any later version. 12 * 13 * cvc is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with cvc. If not, see <http://www.gnu.org/licenses/>. 20 * 21 * You can download cvc from https://github.com/d-m-bailey/cvc.git 22*/ 23 24%skeleton "lalr1.cc" 25%require "3.0" 26 27%define parser_class_name {CCdlParser} 28 29%define parse.assert 30 31%code requires { 32#include "Cvc.hh" 33 34#include "CCircuit.hh" 35#include "CDevice.hh" 36 37class CCdlParserDriver; 38 39#define YYDEBUG 1 40} 41 42// The parsing context. 43%param { CCdlParserDriver& driver } { CCircuitPtrList& cdlCircuitList } { bool theCvcSOI } 44 45%locations 46%initial-action 47{ 48// Initialize the initial location. 49@$.initialize(&driver.filename); 50}; 51 52%define parse.trace 53%define parse.error verbose 54 55%code 56{ 57#include "CCdlParserDriver.hh" 58} 59 60%union { string * StringPtr; } 61%union { char * charPtr; } 62 63%token CDL_EOF 0 "END-OF-FILE" 64%token SUBCKT "SUBCKT" 65%token ENDS "ENDS" 66%token <charPtr> SUBCIRCUIT 67%token <charPtr> BIPOLAR 68%token <charPtr> CAPACITOR 69%token <charPtr> DIODE 70%token <charPtr> MOSFET 71%token <charPtr> RESISTOR 72%token <charPtr> INDUCTOR 73%token <charPtr> STRING 74%token EOL "EOL" 75 76%union { void * VoidPtr; } 77%type <VoidPtr> circuitList 78 79%union { CCircuit * CircuitPtr; } 80%type <CircuitPtr> circuit 81 82%union { CTextList * charPtrListPtr; } 83%type <charPtrListPtr> stringList 84%type <charPtrListPtr> interface 85 86%union { CDevicePtrList *DevicePtrListPtr; } 87%type <DevicePtrListPtr> deviceList 88 89%union { CDevice * DevicePtr; } 90%type <DevicePtr> device 91%type <DevicePtr> subcircuit 92%type <DevicePtr> bipolar 93%type <DevicePtr> capacitor 94%type <DevicePtr> diode 95%type <DevicePtr> inductor 96%type <DevicePtr> mosfet 97%type <DevicePtr> resistor 98 99/* 100%printer { yyoutput << $$; } <*>; 101%printer { yyoutput << "\"" << $$->c_str << "\""; } <StringPtr>; 102%printer { yyoutput << "<>"; } <>; 103*/ 104 105%% 106 107%start circuitList; 108 109circuitList[after]: 110 %empty { 111 $after = NULL; 112 }; 113| circuitList[before] circuit { 114 if ( $circuit != NULL ) { 115 // $circuit->Print(); 116 cdlCircuitList.push_back($circuit); 117 cdlCircuitList.circuitNameMap[$circuit->name] = $circuit; 118 } 119 }; 120 121circuit: 122 SUBCKT interface ENDS EOL { 123/**/ 124 $circuit = new CCircuit(); 125 $circuit->name = $interface->front(); 126 $interface->pop_front(); 127 $circuit->AddPortSignalIds($interface); 128/**/ 129 delete $interface; 130// $circuit = NULL; 131 } 132| SUBCKT interface deviceList ENDS EOL { 133 $circuit = new CCircuit(); 134 $circuit->name = $interface->front(); 135 $interface->pop_front(); 136 $circuit->AddPortSignalIds($interface); 137 delete $interface; 138// $circuit->devices = $deviceList; 139 $circuit->LoadDevices($deviceList); 140// delete $deviceList; 141// for (CDeviceList::iterator current = $circuit->devices->begin(); current != $circuit->devices->end(); current++ ) { 142// current->signalIndexVector = $circuit->SetSignalIndexes(current->signals); 143// delete current->signals; 144// } 145 delete $deviceList; 146 }; 147 148interface: 149 stringList EOL; 150 151stringList[after]: 152 STRING { 153 $after = new CTextList(); 154 $after->push_back($STRING); 155 } 156| stringList[before] STRING { 157 $before->push_back($STRING); 158 }; 159 160deviceList[after]: 161 device { 162// $after = new CDevicePtrList(1, *$device); 163 $after = new CDevicePtrList(); 164 if ( $device != NULL ) { 165 if ( $device->IsSubcircuit() ) { 166 $after->subcircuitCount++; 167 } 168 $after->push_back($device); 169 } 170 } 171| deviceList[before] device { 172 if ( $device != NULL ) { 173 if ( $device->IsSubcircuit() ) { 174 $before->subcircuitCount++; 175 } 176 $before->push_back($device); 177 } 178 }; 179 180device: 181 subcircuit {} 182| bipolar {} 183| capacitor {} 184| diode {} 185| inductor {} 186| mosfet {} 187| resistor {}; 188 189subcircuit: 190 SUBCIRCUIT stringList EOL { 191// printf("** NOERROR: found subckt: %s\n", $SUBCIRCUIT); 192 $subcircuit = new CDevice(); 193 $subcircuit->name = $SUBCIRCUIT; 194 char * myString = $stringList->back(); 195 $stringList->pop_back(); 196 CTextList * myParameterList = new CTextList; 197 while( strchr(myString, '=') ) { 198 myParameterList->push_front(myString); 199 myString = $stringList->back(); 200 $stringList->pop_back(); 201 } 202 $subcircuit->masterName = myString; 203 $subcircuit->signalList_p = $stringList; 204 if ( ! myParameterList->empty() ) { 205 myParameterList->push_front(myString); // add box model name 206 $subcircuit->parameters = cdlCircuitList.parameterText.SetTextAddress("X", myParameterList); 207 } 208 delete myParameterList; 209 }; 210 211bipolar: 212 BIPOLAR STRING[collector] STRING[base] STRING[emitter] stringList EOL { 213/* 214 printf("** ERROR: bipolar device not supported: %s\n", $BIPOLAR); 215 cdlCircuitList.errorCount++; 216 $bipolar = NULL; 217*/ 218/**/ 219 $bipolar = new CDevice(); 220 $bipolar->name = $BIPOLAR; 221 $bipolar->signalList_p = new CTextList(); 222 $bipolar->AppendSignal($collector); 223 $bipolar->AppendSignal($base); 224 $bipolar->AppendSignal($emitter); 225 $bipolar->parameters = cdlCircuitList.parameterText.SetTextAddress("Q", $stringList); 226/**/ 227 delete $stringList; 228}; 229 230capacitor: 231 CAPACITOR STRING[plus] STRING[minus] stringList EOL { 232 $capacitor = new CDevice(); 233 $capacitor->name = $CAPACITOR; 234 $capacitor->signalList_p = new CTextList(); 235 $capacitor->AppendSignal($plus); 236 $capacitor->AppendSignal($minus); 237 $capacitor->AppendSignal($stringList->BiasNet(cdlCircuitList.cdlText)); 238/* 239 if ( $stringList->BiasNet(cdlCircuitList.cdlText) ) { 240 printf("** Warning: three terminal capacitor not supported: %s\n", $CAPACITOR); 241 cdlCircuitList.warningCount++; 242 } 243*/ 244 $capacitor->parameters = cdlCircuitList.parameterText.SetTextAddress("C", $stringList); 245 delete $stringList; 246 }; 247 248diode: 249 DIODE STRING[anode] STRING[cathode] stringList EOL { 250 $diode = new CDevice(); 251 $diode->name = $DIODE; 252 $diode->sourceDrainSet = true; 253 $diode->sourceDrainSwapOk = false; 254 $diode->signalList_p = new CTextList(); 255 $diode->AppendSignal($anode); 256 $diode->AppendSignal($cathode); 257 $diode->parameters = cdlCircuitList.parameterText.SetTextAddress("D", $stringList); 258 delete $stringList; 259 }; 260 261inductor: 262 INDUCTOR STRING[plus] STRING[minus] stringList EOL { 263 printf("** ERROR: inductor device not supported: %s\n", $INDUCTOR); 264 cdlCircuitList.errorCount++; 265 $inductor = NULL; 266 /* 267 $inductor = new CDevice(); 268 $inductor->name = $INDUCTOR; 269 $inductor->AppendSignal($plus); 270 $inductor->AppendSignal($minus); 271 $inductor->parameters = cdlCircuitList.parameterText.SetTextAddress($stringList); 272 */ 273 delete $stringList; 274 }; 275 276mosfet: 277 MOSFET STRING[drain] STRING[gate] STRING[source] STRING[bulk] stringList EOL { 278 $mosfet = new CDevice(); 279 $mosfet->name = $MOSFET; 280 $mosfet->signalList_p = new CTextList(); 281 $mosfet->AppendSignal($drain); 282 $mosfet->AppendSignal($gate); 283 $mosfet->AppendSignal($source); 284 if ( ! theCvcSOI ) { 285 $mosfet->AppendSignal($bulk); 286 } 287 $mosfet->parameters = cdlCircuitList.parameterText.SetTextAddress("M", $stringList); 288 delete $stringList; 289 }; 290 291resistor: 292 RESISTOR STRING[plus] STRING[minus] stringList EOL { 293 $resistor = new CDevice(); 294 $resistor->name = $RESISTOR; 295 $resistor->signalList_p = new CTextList(); 296 $resistor->AppendSignal($plus); 297 $resistor->AppendSignal($minus); 298 $resistor->AppendSignal($stringList->BiasNet(cdlCircuitList.cdlText)); 299/* 300 if ( $stringList->BiasNet(cdlCircuitList.cdlText) ) { 301 printf("** Warning: three terminal resistor not supported: %s\n", $RESISTOR); 302 cdlCircuitList.warningCount++; 303 } 304*/ 305 $resistor->parameters = cdlCircuitList.parameterText.SetTextAddress("R", $stringList); 306 delete $stringList; 307 }; 308 309%% 310 311void 312yy::CCdlParser::error (const yy::location& l, const string& m) 313{ 314 driver.error (l, m); 315} 316