Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes quotes strings inside of metadata #30

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions py010parser/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def parse_file(filename, use_cpp=True, cpp_path='cpp', cpp_args='',
)

def parse_string(text, parser=None, filename="<string>", optimize=True, predefine_types=True,
use_cpp=True, cpp_path='cpp', cpp_args='', keep_scopes=False):
use_cpp=True, cpp_path='cpp', cpp_args='', keep_scopes=False, debuglevel=0):

if use_cpp:
tempfile_path = ''
Expand All @@ -134,5 +134,6 @@ def parse_string(text, parser=None, filename="<string>", optimize=True, predefin
text,
filename,
predefine_types = predefine_types,
keep_scopes = keep_scopes
keep_scopes = keep_scopes,
debuglevel = debuglevel,
)
20 changes: 4 additions & 16 deletions py010parser/c_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,26 +528,14 @@ def children(self):
attr_names = ('name',)

class Metadata010(Node):
metadata010 = r'<((\w+)=(.*?))(,\s*(\w+)=(.*))*>'

def __init__(self, value, coord=None):
self.value = value
def __init__(self, values, coord=None):
self.values = values
self.coord = coord

match = re.match(self.metadata010, value)
kvs = {}

# split into groups of three
for full,k,v in zip(*(iter(match.groups()),) * 3):
if full is not None:
kvs[k] = v

self.keyvals = kvs

def children(self):
return tuple([])
return self.values

attr_names = ('keyvals')
attr_names = ('values')

class IdentifierType(Node):
def __init__(self, names, coord=None):
Expand Down
40 changes: 27 additions & 13 deletions py010parser/c_lexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ def _make_tok_location(self, token):
'PPHASH', # '#'

# 010-metadata
'METADATA010',
#'METADATA010',
)

##
Expand All @@ -236,6 +236,20 @@ def _make_tok_location(self, token):
# typedef ushort FIXEDPT <read=FIXEDPTRead, write=FIXEDPTWrite>;
# etc.
#metadata010 = r'<((\w+)=([^\s]+))(,\s*((\w+)=([^\s]+)))*>'

# Official reference:
# https://www.sweetscape.com/010editor/manual/TemplateVariables.htm
#
# < format=hex|decimal|octal|binary,
# fgcolor=<color>,
# bgcolor=<color>,
# comment="<string>"|<function_name>,
# name="<string>"|<function_name>,
# open=true|false|suppress,
# hidden=true|false,
# read=<function_name>,
# write=<function_name>
# size=<number>|<function_name> >
metadata010 = r'<((\w+)=(.*?))(,(\w+)\s*=(.*))*>'

hex_prefix = '0[xX]'
Expand Down Expand Up @@ -530,19 +544,19 @@ def t_ID(self, t):
t.type = "TYPEID"
return t

@TOKEN(metadata010)
def t_METADATA010(self, t):
match = re.match(self.metadata010, t.value)
kvs = {}

# split into groups of three
#for full,k,v in zip(*(iter(match.groups()),) * 3):
#if full is not None:
#kvs[k] = v
# @TOKEN(metadata010)
# def t_METADATA010(self, t):
# match = re.match(self.metadata010, t.value)
# kvs = {}
#
#t.keyvals = kvs

return t
# # split into groups of three
# #for full,k,v in zip(*(iter(match.groups()),) * 3):
# #if full is not None:
# #kvs[k] = v
##
# #t.keyvals = kvs
#
# return t

def t_error(self, t):
msg = 'Illegal character %s' % repr(t.value[0])
Expand Down
36 changes: 30 additions & 6 deletions py010parser/c_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
class CParser(PLYParser):
def __init__(
self,
lex_optimize=True,
lex_optimize=False,
lextab='py010parser.lextab',
yacc_optimize=True,
yacc_optimize=False,
yacctab='py010parser.yacctab',
yacc_debug=False):
yacc_debug=True):
""" Create a new CParser.

Some arguments for controlling the debug/optimization
Expand Down Expand Up @@ -91,6 +91,7 @@ def __init__(
'type_qualifier_list',
'struct_declarator_list',
'metadata010',
'metadata_assignment_list',
'enum_type'
]

Expand Down Expand Up @@ -1586,12 +1587,35 @@ def p_block_item_list(self, p):
p[0] = p[1] if (len(p) == 2 or p[2] == [None]) else p[1] + p[2]

def p_metadata010(self, p):
""" metadata010 : METADATA010
""" metadata010 : LT metadata_assignment_list GT
"""
meta = c_ast.Metadata010(p[1])

meta = c_ast.Metadata010(p[2])
p[0] = meta

def p_metadata_assignment_list_1(self, p):
""" metadata_assignment_list : metadata_assignment
| metadata_assignment_list COMMA
| metadata_assignment_list COMMA metadata_assignment
"""
if isinstance(p[1], list) and isinstance(p[1][0], list) and len(p[1]) == 1:
res = p[1]
vals = p[3:]
else:
res = []
vals = p[1:]

while len(vals) > 0:
res.append(vals[0])
vals = vals[2:]

p[0] = res

def p_metadata_assignment(self, p):
""" metadata_assignment : ID EQUALS constant
| ID EQUALS STRING_LITERAL
"""
p[0] = [p[1], p[3]]

def p_compound_statement_1(self, p):
""" compound_statement : brace_open block_item_list_opt brace_close """
p[0] = c_ast.Compound(
Expand Down
10 changes: 10 additions & 0 deletions tests/test_basic_parse.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ def test_metadata(self):
local int a <hidden=true>;
""", optimize=True)

def test_metadata_with_quoted_strings(self):
res = parse_string("""
local int asdfsdf <comment="Hello > there">;
""", optimize=True, predefine_types=False)

node = res.children()[0][1]
self.assertEqual(len(node.metadata.values), 1)
self.assertEqual(node.metadata.values[0][0], "comment")
self.assertEqual(node.metadata.values[0][1], '"Hello > there"')

def test_typedef(self):
res = parse_string("""
typedef unsigned int UINT2;
Expand Down