Skip to content

Instantly share code, notes, and snippets.

@volkovasystems
Created November 11, 2014 09:24
Show Gist options
  • Save volkovasystems/13b53033d9493c9f6741 to your computer and use it in GitHub Desktop.
Save volkovasystems/13b53033d9493c9f6741 to your computer and use it in GitHub Desktop.
Stack algorithm for parsing model text.
/**
* 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