Le code pour la présentation du 7 mai sur Sly et Numba.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

109 lines
2.4 KiB

from sly import Lexer, Parser
import pprint
"""
Implementation with SLY of a very simple JSON parser.
Little reminder: here's the grammar
json := object | array
object := '{' members '}'
members := pair | pair ',' members
array := '[' elements ']'
elements := value | value "," elements
pair := STRING ':' value
value := STRING | INTEGER | FLOAT | object | array
"""
class JsonLexer(Lexer):
tokens = {STRING, NUMBER, TRUE, FALSE, NULL}
ignore = ' \t\n\r'
literals = {'{', '}', '[', ']', ':', ','}
@_(r'-?(0|[1-9][0-9]*)(\.[0-9]+)?([Ee][+-]?[0-9]+)?')
def NUMBER(self, t):
t.value = float(t.value)
return t
@_(r'"([ !#-\[\]-\U0010ffff]+|\\(["\/\\bfnrt]|u[0-9A-Fa-f]{4}))*"')
def STRING(self, t):
t.value = json_unescape(t.value)
return t
@_(r'true')
def TRUE(self, t):
t.value = True
return t
@_(r'false')
def FALSE(self, t):
t.value = False
return t
@_(r'null')
def NULL(self, t):
t.value = None
return t
class JsonParser(Parser):
tokens = JsonLexer.tokens
start = 'value'
@_(r'"{" [ pairs ] "}"')
def value(self, p):
if p.pairs:
return dict(p.pairs)
else:
return {}
@_(r'pair { "," pair }')
def pairs(self, p):
return [p.pair0] + p.pair1
@_(r'STRING ":" value')
def pair(self, p):
return (p.STRING, p.value)
@_(r'"[" [ items ] "]"')
def value(self, p):
if p.items:
return p.items
else:
return []
@_(r'value { "," value }')
def items(self, p):
return [p.value0] + p.value1
@_('STRING',
'NUMBER',
'TRUE',
'FALSE',
'NULL')
def value(self, p):
return p[0]
def error(self, p):
raise ValueError("Parsing error at token %s" % str(p))
if __name__ == "__main__":
lexer = JSONLexer()
parser = JSONParser()
json_text = """{"menu": {
"id": "file",
"value": "File",
"popup": {
"menuitem": [
{"value": "New", "onclick": "CreateNewDoc()"},
{"value": "Open", "onclick": "OpenDoc()"},
{"value": "Close", "onclick": "CloseDoc()"}
],
"delay" : 1.5
}
}}
"""
result = parser.parse(lexer.tokenize(json_text))
pprint.pprint(result)