Created
November 11, 2014 09:24
-
-
Save volkovasystems/13b53033d9493c9f6741 to your computer and use it in GitHub Desktop.
Stack algorithm for parsing model text.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Method parseModel | |
* | |
* This will parse the model text and output this structure: | |
* { | |
* "type": "subcircuit" | "model", | |
* "name": "<model name>" | "<subcircuit name>", | |
* "parameterCount": <parameter count> | |
* } | |
* | |
* NOTE: This will always result to an array of this structure. | |
* | |
* The model text may start with a comment and the comment | |
* may contain characters that will conflict with the basic formal pattern. | |
* | |
* So the best way to do this is remove first all the comments on every line. | |
* | |
* Then do a stack based parsing. | |
* @param modelText | |
*/ | |
"parseModel": function parseModel( modelText ){ | |
var modelBlockList = [ ]; | |
var modelBlockStack = [ ]; | |
var stack = [ ]; | |
_.chain( modelText | |
//First we split by new lines. | |
.split( "\n" ) ) | |
//Next we remove the empty lines. | |
.compact( ) | |
//Next we filter out non commented lines. | |
.filter( function onEachLine( lineText ){ | |
return !( /^\*/ ).test( lineText ); | |
} ) | |
//Next we analyze each model line text. | |
.each( function onEachLine( lineText ){ | |
//Case 0: .subckt is the possible start state. | |
if( ( /^\.subckt/i ).test( lineText ) && | |
stack.length == 0 ) | |
{ | |
/** | |
* If the line is a subckt and the stack is empty | |
* push it first. | |
*/ | |
stack.push( lineText ); | |
/** | |
* Push also the line into the model block. | |
* This will be used to contain a single block. | |
*/ | |
modelBlockStack.push( lineText ); | |
}else | |
//Case 1: .ends is the possible end state. | |
if( ( /^\.ends/i ).test( lineText ) ){ | |
/** | |
* If the line is an .ends it means it is closing a .subckt | |
* | |
* If the stack only contains 1 element then this is the last .ends | |
* and the last stack is a .subckt. | |
*/ | |
//Case 1.1: .ends is the last end state. | |
if( stack.length == 1 && | |
( /^\.subckt/i ).test( _.last( stack ) ) ) | |
{ | |
modelBlockStack.push( lineText ); | |
modelBlockList.push( modelBlockStack.join( "\n" ) ); | |
stack = [ ]; | |
modelBlockStack = [ ]; | |
}else | |
//Case 1.2: .ends is not yet the last one. | |
if( ( /^\.subckt/i ).test( _.last( stack ) ) ){ | |
/** | |
* Analyze if the last is a subckt then we just have to pop the last one | |
* and push this to the modelBlockStack. | |
*/ | |
stack.pop( ); | |
modelBlockStack.push( lineText ); | |
} | |
}else | |
//Case 2: other line text is something in between. | |
if( ( /^\.subckt/i ).test( _.last( stack ) ) ){ | |
/** | |
* If the last stack is a subckt then do a normal push. | |
*/ | |
modelBlockStack.push( lineText ); | |
}else | |
//Case 3: .model may be inside the .subckt so this is in this order | |
// When in this case, it means .model is an isolated block. | |
if( ( /^\.model/i ).test( lineText ) ){ | |
/** | |
* If the last stack is a .model it means we need to close that. | |
*/ | |
if( ( /^\.model/i ).test( _.last( stack ) ) ){ | |
modelBlockList.push( modelBlockStack.join( "\n" ) ); | |
stack.pop( ); | |
modelBlockStack = [ ]; | |
} | |
/** | |
* Succeeding .model line will be pushed. | |
*/ | |
stack.push( lineText ); | |
modelBlockStack.push( lineText ); | |
}else if( ( /^\.model/i ).test( _.last( stack ) ) ){ | |
/** | |
* If the last stack is a .model then do a normal push. | |
*/ | |
modelBlockStack.push( lineText ); | |
}else{ | |
//TODO: POSSIBLE ERROR? | |
} | |
} ); | |
//Now it's time to analyze the | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment