I try to create simple DSL with Python SLY . But, I can't get the result as I expected because the parser can't read it properly. So here the code :
Lexer
from sly import Lexer
class ConfigLexer(Lexer):
tokens = { ANIMALS, BLOOD, SKIN, BREATHE, ANIMAL_NAME, VALUE, ASSIGN }
ignore = " \t\r"
ignore_newline = r'\n+'
ANIMALS = "ANIMALS"
BLOOD = "BLOOD"
SKIN = "SKIN"
BREATHE = "BREATHE"
ANIMAL_NAME = r'\{[a-zA-Z_][a-zA-Z0-9_]*\}'
VALUE = r'[a-zA-Z_][a-zA-Z0-9_,.: ]*'
ASSIGN = r'\='
Parser
from sly import Parser
class ConfigParser(Parser):
tokens = ConfigLexer.tokens
def __init__(self):
self.config = dict()
self.dict_attribute = dict()
self.animal_name = ""
@_("ANIMALS animaldetails")
def animals(self, p):
pass
@_("ANIMAL_NAME animalnamedetails")
def animaldetails(self, p):
self.animal_name = p.ANIMAL_NAME.replace("{", "").replace("}","")
if self.animal_name not in self.config:
self.config[self.animal_name] = self.dict_attribute
@_("BLOOD ASSIGN VALUE")
def animalnamedetails(self, p):
if p.BLOOD not in self.dict_attribute:
self.dict_attribute[p.BLOOD] = p.VALUE
@_("SKIN ASSIGN VALUE")
def animalnamedetails(self, p):
if p.SKIN not in self.dict_attribute:
self.dict_attribute[p.SKIN] = p.VALUE
@_("BREATHE ASSIGN VALUE")
def animalnamedetails(self, p):
if p.BREATHE not in self.dict_attribute:
self.dict_attribute[p.BREATHE] = p.VALUE
def get_config(self):
return self.config
but when I run it.
import json
import ConfigLexer
import ConfigParser
if __name__ == '__main__':
lexer = ConfigLexer()
parser = ConfigParser()
long_string = """ANIMALS
{MAMMALS}
BLOOD = WARM
SKIN = FUR
BREATHE = LUNGS
{FISH}
BLOOD = COLD
SKIN = SCALY
BREATHE = GILLS"""
result = parser.parse(lexer.tokenize(long_string))
cfg = parser.get_config()
data_json = json.dumps(cfg, indent=3)
print(data_json)
as I expected, the result would be like this.
data_json = {
'MAMMALS': {'BLOOD': 'WAMR': 'SKIN': 'FUR OR HAIR', 'BREATHE': 'LUNGS'},
'FISH': {'BLOOD': 'COLD', 'SKIN': 'SCALY', 'BREATHE': 'GILLS'}
}
but I only get something like this.
data_json = {
'MAMMALS': {
'BLOOD': 'WARM'
}
}
result of executing :
sly: Syntax error at line 1, token=SKIN
{
"MAMMALS": {
"BLOOD": "WARM"
}
}
I guess I have to edit the Parser, but I can't think how, and would appreciate any pointers you can give me.