Skip to content

Commit

Permalink
Remove * imports from yaml language parsing code (#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
mgeplf authored and pramodk committed Feb 26, 2019
1 parent fd3c6c6 commit a41d669
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 58 deletions.
1 change: 0 additions & 1 deletion src/language/code_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import logging
import os
from pathlib import Path
import shlex
import shutil
import subprocess
import tempfile
Expand Down
18 changes: 9 additions & 9 deletions src/language/node_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
nmodl blocks defining variables, nmodl constructs that define variables
etc. These all data types are defined in this file.
\todo : Other way is to add extra attributes to YAML language definitions.
TODO: Other way is to add extra attributes to YAML language definitions.
YAML will become more verbose but advantage would be that the YAML will be
self sufficien, single definition file instead of hard-coded names here.
self sufficient, single definition file instead of hard-coded names here.
We should properties like is_enum, data_type, is_symbol, is_global etc.
"""

Expand Down Expand Up @@ -103,12 +103,12 @@

# when translating back to nmodl, we need print each statement
# to new line. Those nodes are are used from this list.
STATEMENT_TYPES=["Statement",
"IndependentDef",
"DependentDef",
"ParamAssign",
"ConstantStatement",
"Stepped"]
STATEMENT_TYPES = ["Statement",
"IndependentDef",
"DependentDef",
"ParamAssign",
"ConstantStatement",
"Stepped"]

# data types which have token as an argument to the constructor
LEXER_DATA_TYPES = ["Name",
Expand Down Expand Up @@ -136,7 +136,7 @@
PTR_EXCLUDE_TYPES = ["BinaryOperator", "UnaryOperator", "ReactionOperator"]

# these node names are explicitly added because they are used in ast/visitor
# printer classes. In otder to avoid hardcoding in the printer functions, they
# printer classes. In order to avoid hardcoding in the printer functions, they
# are defined here.
PROGRAM_BLOCK = "Program"
BASE_BLOCK = "Block"
Expand Down
68 changes: 35 additions & 33 deletions src/language/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
is represented by ChildNode.
"""

from node_info import *
import textwrap
from utils import *

import node_info
from utils import to_snake_case


class BaseNode:
Expand All @@ -32,35 +33,35 @@ def __init__(self, args):
self.is_abstract = False

def __lt__(self, other):
return (self.class_name < other.class_name)
return self.class_name < other.class_name

def get_data_type_name(self):
""" return type name for the node """
return DATA_TYPES[self.class_name]
return node_info.DATA_TYPES[self.class_name]

@property
def is_statement_block_node(self):
return self.class_name == STATEMENT_BLOCK_NODE
return self.class_name == node_info.STATEMENT_BLOCK_NODE

@property
def is_statement_node(self):
return self.class_name in STATEMENT_TYPES
return self.class_name in node_info.STATEMENT_TYPES

@property
def is_global_block_node(self):
return self.class_name in GLOBAL_BLOCKS
return self.class_name in node_info.GLOBAL_BLOCKS

@property
def is_prime_node(self):
return self.class_name == PRIME_NAME_NODE
return self.class_name == node_info.PRIME_NAME_NODE

@property
def is_program_node(self):
"""
check if current node is main program container node
:return: True if main program block otherwise False
"""
return self.class_name == PROGRAM_BLOCK
return self.class_name == node_info.PROGRAM_BLOCK

@property
def is_block_node(self):
Expand All @@ -71,73 +72,73 @@ def is_block_node(self):
:return: True or False
"""
return self.class_name in BLOCK_TYPES
return self.class_name in node_info.BLOCK_TYPES

@property
def is_unit_block(self):
return self.class_name == UNIT_BLOCK
return self.class_name == node_info.UNIT_BLOCK

@property
def is_data_type_node(self):
return self.class_name in DATA_TYPES
return self.class_name in node_info.DATA_TYPES

@property
def is_symbol_var_node(self):
return self.class_name in SYMBOL_VAR_TYPES
return self.class_name in node_info.SYMBOL_VAR_TYPES

@property
def is_symbol_helper_node(self):
return self.class_name in SYMBOL_TABLE_HELPER_NODES
return self.class_name in node_info.SYMBOL_TABLE_HELPER_NODES

@property
def is_symbol_block_node(self):
return self.class_name in SYMBOL_BLOCK_TYPES
return self.class_name in node_info.SYMBOL_BLOCK_TYPES

@property
def is_base_type_node(self):
return self.class_name in BASE_TYPES
return self.class_name in node_info.BASE_TYPES

@property
def is_string_node(self):
return self.class_name == STRING_NODE
return self.class_name == node_info.STRING_NODE

@property
def is_integer_node(self):
return self.class_name == INTEGER_NODE
return self.class_name == node_info.INTEGER_NODE

@property
def is_number_node(self):
return self.class_name == NUMBER_NODE
return self.class_name == node_info.NUMBER_NODE

@property
def is_boolean_node(self):
return self.class_name == BOOLEAN_NODE
return self.class_name == node_info.BOOLEAN_NODE

@property
def is_identifier_node(self):
return self.class_name == IDENTIFIER_NODE
return self.class_name == node_info.IDENTIFIER_NODE

@property
def is_name_node(self):
return self.class_name == NAME_NODE
return self.class_name == node_info.NAME_NODE

@property
def is_enum_node(self):
data_type = DATA_TYPES[self.class_name]
return data_type in ENUM_BASE_TYPES
data_type = node_info.DATA_TYPES[self.class_name]
return data_type in node_info.ENUM_BASE_TYPES

@property
def is_pointer_node(self):
return not (self.class_name in PTR_EXCLUDE_TYPES or
return not (self.class_name in node_info.PTR_EXCLUDE_TYPES or
self.is_base_type_node)

@property
def is_ptr_excluded_node(self):
return self.class_name in PTR_EXCLUDE_TYPES
return self.class_name in node_info.PTR_EXCLUDE_TYPES

@property
def requires_default_constructor(self):
return (self.class_name in LEXER_DATA_TYPES or
return (self.class_name in node_info.LEXER_DATA_TYPES or
self.is_program_node or
self.is_ptr_excluded_node)

Expand Down Expand Up @@ -257,22 +258,22 @@ def is_block_scoped_node(self):
Check if node is derived from BASE_BLOCK
:return: True / False
"""
return self.base_class == BASE_BLOCK
return self.base_class == node_info.BASE_BLOCK

def has_parent_block_node(self):
"""
check is base or parent is structured base block
:return: True if parent is BASE_BLOCK otherwise False
"""
return self.base_class == BASE_BLOCK
return self.base_class == node_info.BASE_BLOCK

@property
def is_base_block_node(self):
"""
check if node is Block
:return: True if node type/name is BASE_BLOCK
"""
return self.class_name == BASE_BLOCK
return self.class_name == node_info.BASE_BLOCK

@property
def is_symtab_needed(self):
Expand Down Expand Up @@ -301,13 +302,14 @@ def is_symtab_method_required(self):

if self.has_children():

if self.class_name in SYMBOL_VAR_TYPES or self.class_name in SYMBOL_BLOCK_TYPES:
if(self.class_name in node_info.SYMBOL_VAR_TYPES or
self.class_name in node_info.SYMBOL_BLOCK_TYPES):
method_required = True

if self.is_program_node or self.has_parent_block_node():
method_required = True

if self.class_name in SYMBOL_TABLE_HELPER_NODES:
if self.class_name in node_info.SYMBOL_TABLE_HELPER_NODES:
method_required = True

return method_required
Expand All @@ -317,7 +319,7 @@ def is_base_class_number_node(self):
"""
Check if node is of type Number
"""
return self.base_class == NUMBER_NODE
return self.base_class == node_info.NUMBER_NODE

def ctor_declaration(self):
args = [f'{c.get_typename()} {c.varname}' for c in self.children]
Expand Down
20 changes: 8 additions & 12 deletions src/language/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@

import sys
import yaml

from argument import Argument
from nodes import Node
from node_info import *
import node_info


class LanguageParser:
Expand All @@ -27,17 +28,16 @@ def __init__(self, filename, debug=False):
self.filename = filename
self.debug = debug

@classmethod
def is_token(self, name):
@staticmethod
def is_token(name):
"""check if the name (i.e. class) is a token type in lexer
Lexims returned from Lexer have position and hence token object.
Return True if this node is returned by lexer otherwise False
"""
if name in LEXER_DATA_TYPES or name in SYMBOL_BLOCK_TYPES or name in ADDITIONAL_TOKEN_BLOCKS:
return True
else:
return False
return (name in node_info.LEXER_DATA_TYPES or
name in node_info.SYMBOL_BLOCK_TYPES or
name in node_info.ADDITIONAL_TOKEN_BLOCKS)

def parse_child_rule(self, child):
"""parse child specification and return argument as properties
Expand All @@ -59,7 +59,6 @@ def parse_child_rule(self, child):
# type i.e. class of the variable
args.class_name = properties['type']


if self.debug:
print(('Child {}, {}'.format(args.varname, args.class_name)))

Expand Down Expand Up @@ -125,7 +124,6 @@ def parse_child_rule(self, child):

return args


def parse_yaml_rules(self, nodelist, base_class=None):
abstract_nodes = []
nodes = []
Expand All @@ -148,7 +146,6 @@ def parse_yaml_rules(self, nodelist, base_class=None):
# classes like AST which don't have base class
# are not added (we print AST class separately)
if base_class:

args = Argument()
args.base_class = base_class
args.class_name = class_name
Expand Down Expand Up @@ -203,8 +200,7 @@ def parse_file(self):
with open(self.filename, 'r') as stream:
try:
rules = yaml.load(stream)
# abstract nodes are not used though
abstract_nodes, nodes = self.parse_yaml_rules(rules)
_, nodes = self.parse_yaml_rules(rules)
except yaml.YAMLError as e:
print(("Error while parsing YAML definition file {0} : {1}".format(self.filename, e.strerror)))
sys.exit(1)
Expand Down
8 changes: 5 additions & 3 deletions src/language/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@

import re

# convert string of the form "AabcDef" to "Abc_Def"

def camel_case_to_underscore(name):
"""convert string from 'AaaBbbbCccDdd' -> 'Aaa_Bbbb_Ccc_Ddd'"""
s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name)
typename = re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1)
return typename

# convert string of the form "AabcDef" to "abc_def"

def to_snake_case(name):
return camel_case_to_underscore(name).lower()
"""convert string from 'AaaBbbbCccDdd' -> 'aaa_bbbb_ccc_ddd'"""
return camel_case_to_underscore(name).lower()

0 comments on commit a41d669

Please sign in to comment.