Skip to content

Instantly share code, notes, and snippets.

@niklaskorz
Created August 12, 2013 11:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niklaskorz/6210150 to your computer and use it in GitHub Desktop.
Save niklaskorz/6210150 to your computer and use it in GitHub Desktop.
from __future__ import print_function
from ply import lex, yacc
tokens = (
"LBRACE", "RBRACE", "LBRACKET", "RBRACKET", "COLON",
"STRING", "INT", "FLOAT", "COMMA", "NULL", "TRUE", "FALSE",
"WHITESPACE"
)
t_LBRACE = r"\{"
t_RBRACE = r"\}"
t_LBRACKET = r"\["
t_RBRACKET = r"\]"
t_COLON = r":"
t_INT = r"[0-9]+(\.[0-9]+)?"
t_FLOAT = r"([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)"
t_COMMA = r","
t_NULL = r"null"
t_TRUE = r"true"
t_FALSE = r"false"
def t_ignore_WHITESPACE(t):
r"[ \t\r\n]+"
t.lexer.lineno += t.value.count("\n")
def t_STRING(t):
r'\"([^\\"]|\\(.|\n))*\"'
t.lexer.lineno += t.value.count("\n")
return t
def t_error(t):
print("Lexer error:", t.value)
lexer = lex.lex()
precedence = (
)
def p_object(p):
"object : LBRACE kvpairs RBRACE"
p[0] = p[2]
def p_kvpairs(p):
"""kvpairs : kvpair
| kvpairs COMMA kvpair"""
if len(p) == 4:
p[1].update(p[3])
p[0] = p[1]
def p_kvpair(p):
"kvpair : string COLON value"
p[0] = {p[1]: p[3]}
def p_value(p):
"""value : string
| number
| object
| array
| bool
| null"""
p[0] = p[1]
def p_string(p):
"string : STRING"
p[0] = p[1][1:-1]
def p_number(p):
"""number : int
| float"""
p[0] = p[1]
def p_int(p):
"int : INT"
p[0] = int(p[1])
def p_float(p):
"float : FLOAT"
p[0] = float(p[1])
def p_array(p):
"array : LBRACKET values RBRACKET"
p[0] = p[2]
def p_values(p):
"""values : value
| values COMMA value"""
if len(p) == 4:
p[0] = p[1] + [p[3]]
else:
p[0] = [p[1]]
def p_bool(p):
"""bool : TRUE
| FALSE"""
p[0] = p[1] == "true"
def p_null(p):
"null : NULL"
p[0] = None
def p_error(p):
print("Syntax error '{0.value}' in line {0.lineno}".format(p))
parser = yacc.yacc()
def parse(s):
return parser.parse(s, lexer=lexer)
if __name__ == "__main__":
import sys
assert(len(sys.argv) > 1)
with open(sys.argv[1]) as f:
data = parse(f.read())
print(data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment