mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 06:58:05 +02:00
anv/grl: Add a GRL file parser
Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com> Acked-by: Caio Oliveira <caio.oliveira@intel.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16970>
This commit is contained in:
parent
5f948503e4
commit
37663438f7
1 changed files with 586 additions and 0 deletions
586
src/intel/vulkan/grl/grl_parser.py
Normal file
586
src/intel/vulkan/grl/grl_parser.py
Normal file
|
|
@ -0,0 +1,586 @@
|
|||
#!/bin/env python
|
||||
COPYRIGHT = """\
|
||||
/*
|
||||
* Copyright 2021 Intel Corporation
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sub license, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the
|
||||
* next paragraph) shall be included in all copies or substantial portions
|
||||
* of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
|
||||
* IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
|
||||
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import ply.lex as lex
|
||||
import ply.yacc as yacc
|
||||
|
||||
# Libraries
|
||||
|
||||
libraries = {}
|
||||
|
||||
# LEXER
|
||||
|
||||
keywords = {
|
||||
'__debugbreak': 'KW_DEBUGBREAK',
|
||||
'alignas': 'KW_ALIGNAS',
|
||||
'args': 'KW_ARGS',
|
||||
'atomic': 'KW_ATOMIC',
|
||||
'atomic_return': 'KW_ATOMIC_RETURN',
|
||||
'const': 'KW_CONST',
|
||||
'control': 'KW_CONTROL',
|
||||
'define': 'KW_DEFINE',
|
||||
'dispatch': 'KW_DISPATCH',
|
||||
'dispatch_indirect': 'KW_DISPATCH_INDIRECT',
|
||||
'goto': 'KW_GOTO',
|
||||
'if': 'KW_IF',
|
||||
'kernel': 'KW_KERNEL',
|
||||
'kernel_module': 'KW_KERNEL_MODULE',
|
||||
'import': 'KW_IMPORT',
|
||||
'library': 'KW_LIBRARY',
|
||||
'links': 'KW_LINKS',
|
||||
'load_dword': 'KW_LOAD_DWORD',
|
||||
'load_qword': 'KW_LOAD_QWORD',
|
||||
'metakernel': 'KW_METAKERNEL',
|
||||
'module': 'KW_MODULE',
|
||||
'not': 'KW_NOT',
|
||||
'offsetof': 'KW_OFFSETOF',
|
||||
'postsync': 'KW_POSTSYNC',
|
||||
'print': 'KW_PRINT',
|
||||
'semaphore_wait': 'KW_SEMAPHORE_WAIT',
|
||||
'shiftof': 'KW_SHIFTOF',
|
||||
'sizeof': 'KW_SIZEOF',
|
||||
'store_dword': 'KW_STORE_DWORD',
|
||||
'store_qword': 'KW_STORE_QWORD',
|
||||
'store_timestamp': 'KW_STORE_TIMESTAMP',
|
||||
'struct': 'KW_STRUCT',
|
||||
'unsigned': 'KW_UNSIGNED',
|
||||
'while': 'KW_WHILE'
|
||||
}
|
||||
|
||||
ops = {
|
||||
'&&': 'OP_LOGICAL_AND',
|
||||
'||': 'OP_LOGICAL_OR',
|
||||
'==': 'OP_EQUALEQUAL',
|
||||
'!=': 'OP_NOTEQUAL',
|
||||
'<=': 'OP_LESSEQUAL',
|
||||
'>=': 'OP_GREATEREQUAL',
|
||||
'<<': 'OP_LSHIFT',
|
||||
'>>': 'OP_RSHIFT'
|
||||
}
|
||||
|
||||
tokens = [
|
||||
'INT_LITERAL',
|
||||
'STRING_LITERAL',
|
||||
'OP',
|
||||
'IDENTIFIER'
|
||||
] + list(keywords.values()) + list(ops.values())
|
||||
|
||||
def t_INT_LITERAL(t):
|
||||
r'(0x[a-fA-F0-9]+|\d+)'
|
||||
if t.value.startswith('0x'):
|
||||
t.value = int(t.value[2:], 16)
|
||||
else:
|
||||
t.value = int(t.value)
|
||||
return t
|
||||
|
||||
def t_OP(t):
|
||||
r'(&&|\|\||==|!=|<=|>=|<<|>>)'
|
||||
t.type = ops.get(t.value)
|
||||
return t
|
||||
|
||||
def t_IDENTIFIER(t):
|
||||
r'[a-zA-Z_][a-zA-Z_0-9]*'
|
||||
t.type = keywords.get(t.value, 'IDENTIFIER')
|
||||
return t
|
||||
|
||||
def t_STRING_LITERAL(t):
|
||||
r'"(\\.|[^"\\])*"'
|
||||
t.value = t.value[1:-1]
|
||||
return t
|
||||
|
||||
literals = "+*/(){};:,=&|!~^.%?-<>[]"
|
||||
|
||||
t_ignore = ' \t'
|
||||
|
||||
def t_newline(t):
|
||||
r'\n+'
|
||||
t.lexer.lineno += len(t.value)
|
||||
|
||||
def t_error(t):
|
||||
print("WUT: {}".format(t.value))
|
||||
t.lexer.skip(1)
|
||||
|
||||
LEXER = lex.lex()
|
||||
|
||||
# PARSER
|
||||
|
||||
precedence = (
|
||||
('right', '?', ':'),
|
||||
('left', 'OP_LOGICAL_OR', 'OP_LOGICAL_AND'),
|
||||
('left', '|'),
|
||||
('left', '^'),
|
||||
('left', '&'),
|
||||
('left', 'OP_EQUALEQUAL', 'OP_NOTEQUAL'),
|
||||
('left', '<', '>', 'OP_LESSEQUAL', 'OP_GREATEREQUAL'),
|
||||
('left', 'OP_LSHIFT', 'OP_RSHIFT'),
|
||||
('left', '+', '-'),
|
||||
('left', '*', '/', '%'),
|
||||
('right', '!', '~'),
|
||||
('left', '[', ']', '.')
|
||||
)
|
||||
|
||||
def p_module(p):
|
||||
'module : element_list'
|
||||
p[0] = p[1]
|
||||
|
||||
def p_element_list(p):
|
||||
'''element_list : element_list element
|
||||
| element'''
|
||||
if len(p) == 2:
|
||||
p[0] = [p[1]]
|
||||
else:
|
||||
p[0] = p[1] + [p[2]]
|
||||
|
||||
def p_element(p):
|
||||
'''element : kernel_definition
|
||||
| kernel_module_definition
|
||||
| library_definition
|
||||
| metakernel_definition
|
||||
| module_name
|
||||
| struct_definition
|
||||
| const_definition
|
||||
| import_definition'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_module_name(p):
|
||||
'module_name : KW_MODULE IDENTIFIER ";"'
|
||||
p[0] = ('module-name', p[2])
|
||||
|
||||
def p_kernel_module_definition(p):
|
||||
'kernel_module_definition : KW_KERNEL_MODULE IDENTIFIER "(" STRING_LITERAL ")" "{" kernel_definition_list "}"'
|
||||
p[0] = ('kernel-module', p[2], p[4], p[7])
|
||||
|
||||
def p_kernel_definition(p):
|
||||
'kernel_definition : KW_KERNEL IDENTIFIER optional_annotation_list'
|
||||
p[0] = ('kernel', p[2], p[3])
|
||||
|
||||
def p_library_definition(p):
|
||||
'library_definition : KW_LIBRARY IDENTIFIER "{" library_definition_list "}"'
|
||||
p[0] = ('library', p[2], p[4])
|
||||
|
||||
def p_library_definition_list(p):
|
||||
'''library_definition_list :
|
||||
| library_definition_list IDENTIFIER STRING_LITERAL ";"'''
|
||||
if len(p) < 3:
|
||||
p[0] = []
|
||||
else:
|
||||
p[0] = p[1]
|
||||
p[0].append((p[2], p[3]))
|
||||
|
||||
def p_import_definition(p):
|
||||
'import_definition : KW_IMPORT KW_STRUCT IDENTIFIER STRING_LITERAL ";"'
|
||||
p[0] = ('import', p[4], 'struct', p[3])
|
||||
|
||||
def p_links_definition(p):
|
||||
'links_definition : KW_LINKS IDENTIFIER'
|
||||
|
||||
# Process a library include like a preprocessor
|
||||
global libraries
|
||||
|
||||
if not p[2] in libraries:
|
||||
raise "Not able to find library {0}".format(p[2])
|
||||
p[0] = libraries[p[2]]
|
||||
|
||||
def p_metakernel_definition(p):
|
||||
'metakernel_definition : KW_METAKERNEL IDENTIFIER "(" optional_parameter_list ")" optional_annotation_list scope'
|
||||
p[0] = ('meta-kernel', p[2], p[4], p[6], p[7])
|
||||
|
||||
def p_kernel_definition_list(p):
|
||||
'''kernel_definition_list :
|
||||
| kernel_definition_list kernel_definition ";"
|
||||
| kernel_definition_list links_definition ";"'''
|
||||
if len(p) < 3:
|
||||
p[0] = []
|
||||
else:
|
||||
p[0] = p[1]
|
||||
p[0].append(p[2])
|
||||
|
||||
def p_optional_annotation_list(p):
|
||||
'''optional_annotation_list :
|
||||
| "<" ">"
|
||||
| "<" annotation_list ">"'''
|
||||
if len(p) < 4:
|
||||
p[0] = {}
|
||||
else:
|
||||
p[0] = p[2]
|
||||
|
||||
def p_optional_parameter_list(p):
|
||||
'''optional_parameter_list :
|
||||
| parameter_list'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_annotation_list(p):
|
||||
'''annotation_list : annotation'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_annotation_list_append(p):
|
||||
'''annotation_list : annotation_list "," annotation'''
|
||||
p[0] = {**p[1], **p[3]}
|
||||
|
||||
def p_annotation(p):
|
||||
'''annotation : IDENTIFIER "=" INT_LITERAL
|
||||
| IDENTIFIER "=" IDENTIFIER
|
||||
| IDENTIFIER "=" STRING_LITERAL'''
|
||||
p[0] = {p[1]: p[3]}
|
||||
|
||||
def p_parameter_list(p):
|
||||
'''parameter_list : parameter_definition'''
|
||||
p[0] = [p[1]]
|
||||
|
||||
def p_parameter_list_append(p):
|
||||
'''parameter_list : parameter_list "," parameter_definition'''
|
||||
p[0] = p[1]
|
||||
p[0].append(p[3])
|
||||
|
||||
def p_parameter_definition(p):
|
||||
'parameter_definition : IDENTIFIER IDENTIFIER'
|
||||
p[0] = (p[1], p[2])
|
||||
|
||||
def p_scope(p):
|
||||
'''scope : "{" optional_statement_list "}"'''
|
||||
p[0] = p[2]
|
||||
|
||||
def p_optional_statement_list(p):
|
||||
'''optional_statement_list :
|
||||
| statement_list'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_statement_list(p):
|
||||
'''statement_list : statement'''
|
||||
p[0] = [p[1]]
|
||||
|
||||
def p_statement_list_append(p):
|
||||
'''statement_list : statement_list statement'''
|
||||
p[0] = p[1]
|
||||
p[0].append(p[2])
|
||||
|
||||
def p_statement(p):
|
||||
'''statement : definition_statement ";"
|
||||
| assignment_statement ";"
|
||||
| load_store_statement ";"
|
||||
| dispatch_statement ";"
|
||||
| semaphore_statement ";"
|
||||
| label
|
||||
| goto_statement ";"
|
||||
| scope_statement
|
||||
| atomic_op_statement ";"
|
||||
| control_statement ";"
|
||||
| print_statement ";"
|
||||
| debug_break_statement ";"'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_definition_statement(p):
|
||||
'definition_statement : KW_DEFINE IDENTIFIER value'
|
||||
p[0] = ('define', p[2], p[3])
|
||||
|
||||
def p_assignemt_statement(p):
|
||||
'assignment_statement : value "=" value'
|
||||
p[0] = ('assign', p[1], p[3])
|
||||
|
||||
def p_load_store_statement_load_dword(p):
|
||||
'''load_store_statement : value "=" KW_LOAD_DWORD "(" value ")"'''
|
||||
p[0] = ('load-dword', p[1], p[5])
|
||||
|
||||
def p_load_store_statement_load_qword(p):
|
||||
'''load_store_statement : value "=" KW_LOAD_QWORD "(" value ")"'''
|
||||
p[0] = ('load-qword', p[1], p[5])
|
||||
|
||||
def p_load_store_statement_store_dword(p):
|
||||
'''load_store_statement : KW_STORE_DWORD "(" value "," value ")"'''
|
||||
p[0] = ('store-dword', p[3], p[5])
|
||||
|
||||
def p_load_store_statement_store_qword(p):
|
||||
'''load_store_statement : KW_STORE_QWORD "(" value "," value ")"'''
|
||||
p[0] = ('store-qword', p[3], p[5])
|
||||
|
||||
def p_dispatch_statement(p):
|
||||
'''dispatch_statement : direct_dispatch_statement
|
||||
| indirect_dispatch_statement'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_direct_dispatch_statement(p):
|
||||
'''direct_dispatch_statement : KW_DISPATCH IDENTIFIER "(" value "," value "," value ")" optional_kernel_arg_list optional_postsync'''
|
||||
p[0] = ('dispatch', p[2], (p[4], p[6], p[8]), p[10], p[11])
|
||||
|
||||
def p_indirect_dispatch_statement(p):
|
||||
'''indirect_dispatch_statement : KW_DISPATCH_INDIRECT IDENTIFIER optional_kernel_arg_list optional_postsync'''
|
||||
p[0] = ('dispatch', p[2], None, p[3], p[4])
|
||||
|
||||
def p_optional_kernel_arg_list(p):
|
||||
'''optional_kernel_arg_list :
|
||||
| KW_ARGS "(" value_list ")"'''
|
||||
p[0] = p[3]
|
||||
|
||||
def p_value_list(p):
|
||||
'''value_list : value'''
|
||||
p[0] = [p[1]]
|
||||
|
||||
def p_value_list_append(p):
|
||||
'''value_list : value_list "," value'''
|
||||
p[0] = p[1]
|
||||
p[0].append(p[3])
|
||||
|
||||
def p_optional_postsync(p):
|
||||
'''optional_postsync :
|
||||
| postsync_operation'''
|
||||
if len(p) > 1:
|
||||
p[0] = p[1]
|
||||
|
||||
def p_postsync_operation(p):
|
||||
'''postsync_operation : postsync_write_dword
|
||||
| postsync_write_timestamp'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_postsync_write_dword(p):
|
||||
'''postsync_write_dword : KW_POSTSYNC KW_STORE_DWORD "(" value "," value ")"'''
|
||||
p[0] = ('postsync', 'store-dword', p[4], p[6])
|
||||
|
||||
def p_postsync_write_timestamp(p):
|
||||
'''postsync_write_timestamp : KW_POSTSYNC KW_STORE_TIMESTAMP "(" value ")"'''
|
||||
p[0] = ('postsync', 'timestamp', p[4])
|
||||
|
||||
def p_semaphore_statement(p):
|
||||
'''semaphore_statement : KW_SEMAPHORE_WAIT KW_WHILE "(" "*" value "<" value ")"
|
||||
| KW_SEMAPHORE_WAIT KW_WHILE "(" "*" value ">" value ")"
|
||||
| KW_SEMAPHORE_WAIT KW_WHILE "(" "*" value OP_LESSEQUAL value ")"
|
||||
| KW_SEMAPHORE_WAIT KW_WHILE "(" "*" value OP_GREATEREQUAL value ")"
|
||||
| KW_SEMAPHORE_WAIT KW_WHILE "(" "*" value OP_EQUALEQUAL value ")"
|
||||
| KW_SEMAPHORE_WAIT KW_WHILE "(" "*" value OP_NOTEQUAL value ")"'''
|
||||
p[0] = ('sem-wait-while', p[5], p[6], p[7])
|
||||
|
||||
def p_atomic_op_statement(p):
|
||||
'''atomic_op_statement : KW_ATOMIC IDENTIFIER IDENTIFIER "(" value_list ")"'''
|
||||
p[0] = ('atomic', p[2], p[3], p[5])
|
||||
|
||||
def p_atomic_op_statement_return(p):
|
||||
'''atomic_op_statement : KW_ATOMIC_RETURN IDENTIFIER IDENTIFIER "(" value_list ")"'''
|
||||
p[0] = ('atomic-return', p[2], p[3], p[5])
|
||||
|
||||
def p_label(p):
|
||||
'''label : IDENTIFIER ":"'''
|
||||
p[0] = ('label', p[1])
|
||||
|
||||
def p_goto_statement(p):
|
||||
'''goto_statement : KW_GOTO IDENTIFIER'''
|
||||
p[0] = ('goto', p[2])
|
||||
|
||||
def p_goto_statement_if(p):
|
||||
'''goto_statement : KW_GOTO IDENTIFIER KW_IF "(" value ")"'''
|
||||
p[0] = ('goto-if', p[2], p[5])
|
||||
|
||||
def p_goto_statement_if_not(p):
|
||||
'''goto_statement : KW_GOTO IDENTIFIER KW_IF KW_NOT "(" value ")"'''
|
||||
p[0] = ('goto-if-not', p[2], p[6])
|
||||
|
||||
def p_scope_statement(p):
|
||||
'''scope_statement : scope'''
|
||||
p[0] = (p[1])
|
||||
|
||||
def p_control_statement(p):
|
||||
'''control_statement : KW_CONTROL "(" id_list ")"'''
|
||||
p[0] = ('control', p[3])
|
||||
|
||||
def p_print_statement(p):
|
||||
'''print_statement : KW_PRINT "(" printable_list ")"'''
|
||||
p[0] = ('print', p[3])
|
||||
|
||||
def p_printable_list(p):
|
||||
'''printable_list : printable'''
|
||||
p[0] = [p[1]]
|
||||
|
||||
def p_printable_list_append(p):
|
||||
'''printable_list : printable_list "," printable'''
|
||||
p[0] = p[1]
|
||||
p[0].append(p[3])
|
||||
|
||||
def p_printable_str_lit(p):
|
||||
'''printable : STRING_LITERAL'''
|
||||
p[0] = '"{}"'.format(p[1])
|
||||
|
||||
def p_printable_value(p):
|
||||
'''printable : value'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_printable_str_lit_value(p):
|
||||
'''printable : STRING_LITERAL value'''
|
||||
p[0] = ('"{}"'.format(p[1]), p[2])
|
||||
|
||||
def p_debug_break_statement(p):
|
||||
'''debug_break_statement : KW_DEBUGBREAK'''
|
||||
p[0] = ('debug-break')
|
||||
|
||||
def p_id_list(p):
|
||||
'''id_list : IDENTIFIER'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_id_list_append(p):
|
||||
'''id_list : id_list "," IDENTIFIER'''
|
||||
p[0] = p[1]
|
||||
p[0].append(p[3])
|
||||
|
||||
def p_value(p):
|
||||
'''value : IDENTIFIER
|
||||
| INT_LITERAL'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_value_braces(p):
|
||||
'''value : "(" value ")"'''
|
||||
p[0] = (p[2])
|
||||
|
||||
def p_value_member(p):
|
||||
'''value : value "." IDENTIFIER'''
|
||||
p[0] = ('member', p[1], p[3])
|
||||
|
||||
def p_value_idx(p):
|
||||
'''value : value "[" value "]"'''
|
||||
p[0] = ('index', p[1], p[3])
|
||||
|
||||
def p_value_binop(p):
|
||||
'''value : value "+" value
|
||||
| value "-" value
|
||||
| value "*" value
|
||||
| value "/" value
|
||||
| value "%" value
|
||||
| value "&" value
|
||||
| value "|" value
|
||||
| value "<" value
|
||||
| value ">" value
|
||||
| value "^" value
|
||||
| value OP_LESSEQUAL value
|
||||
| value OP_GREATEREQUAL value
|
||||
| value OP_EQUALEQUAL value
|
||||
| value OP_NOTEQUAL value
|
||||
| value OP_LOGICAL_AND value
|
||||
| value OP_LOGICAL_OR value
|
||||
| value OP_LSHIFT value
|
||||
| value OP_RSHIFT value'''
|
||||
p[0] = (p[2], p[1], p[3])
|
||||
|
||||
def p_value_uniop(p):
|
||||
'''value : "!" value
|
||||
| "~" value'''
|
||||
p[0] = (p[1], p[2])
|
||||
|
||||
def p_value_cond(p):
|
||||
'''value : value "?" value ":" value'''
|
||||
p[0] = ('?', p[1], p[3], p[5])
|
||||
|
||||
def p_value_funcop(p):
|
||||
'''value : KW_OFFSETOF "(" offset_expression ")"
|
||||
| KW_SHIFTOF "(" IDENTIFIER ")"
|
||||
| KW_SIZEOF "(" IDENTIFIER ")"'''
|
||||
p[0] = (p[1], p[3])
|
||||
|
||||
def p_offset_expression(p):
|
||||
'''offset_expression : IDENTIFIER'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_offset_expression_member(p):
|
||||
'''offset_expression : offset_expression "." IDENTIFIER'''
|
||||
p[0] = ('member', p[1], p[3])
|
||||
|
||||
def p_offset_expression_idx(p):
|
||||
'''offset_expression : offset_expression "[" INT_LITERAL "]"'''
|
||||
p[0] = ('index', p[1], p[3])
|
||||
|
||||
def p_struct_definition(p):
|
||||
'''struct_definition : KW_STRUCT optional_alignment_specifier IDENTIFIER "{" optional_struct_member_list "}" ";"'''
|
||||
p[0] = ('struct', p[3], p[5], p[2])
|
||||
|
||||
def p_optional_alignment_specifier(p):
|
||||
'''optional_alignment_specifier :
|
||||
| KW_ALIGNAS "(" INT_LITERAL ")"'''
|
||||
if len(p) == 1:
|
||||
p[0] = 0
|
||||
else:
|
||||
p[0] = p[3]
|
||||
|
||||
def p_optional_struct_member_list(p):
|
||||
'''optional_struct_member_list :
|
||||
| struct_member_list'''
|
||||
if len(p) == 1:
|
||||
p[0] = {}
|
||||
else:
|
||||
p[0] = p[1]
|
||||
|
||||
def p_struct_member_list(p):
|
||||
'''struct_member_list : struct_member'''
|
||||
p[0] = [p[1]]
|
||||
|
||||
def p_struct_member_list_append(p):
|
||||
'''struct_member_list : struct_member_list struct_member'''
|
||||
p[0] = p[1] + [p[2]]
|
||||
|
||||
def p_struct_member(p):
|
||||
'''struct_member : struct_member_typename IDENTIFIER ";"'''
|
||||
p[0] = (p[1], p[2])
|
||||
|
||||
def p_struct_member_array(p):
|
||||
'''struct_member : struct_member_typename IDENTIFIER "[" INT_LITERAL "]" ";"'''
|
||||
'''struct_member : struct_member_typename IDENTIFIER "[" IDENTIFIER "]" ";"'''
|
||||
p[0] = {p[1]: p[2], 'count': p[4]}
|
||||
|
||||
def p_struct_member_typename(p):
|
||||
'''struct_member_typename : IDENTIFIER'''
|
||||
p[0] = p[1]
|
||||
|
||||
def p_struct_member_typename_unsigned(p):
|
||||
'''struct_member_typename : KW_UNSIGNED IDENTIFIER'''
|
||||
p[0] = ('unsigned', p[2])
|
||||
|
||||
def p_struct_member_typename_struct(p):
|
||||
'''struct_member_typename : KW_STRUCT IDENTIFIER'''
|
||||
p[0] = ('struct', p[2])
|
||||
|
||||
def p_const_definition(p):
|
||||
'''const_definition : KW_CONST IDENTIFIER "=" INT_LITERAL ";"'''
|
||||
p[0] = ('named-constant', p[2], p[4])
|
||||
|
||||
PARSER = yacc.yacc()
|
||||
|
||||
# Shamelessly stolen from some StackOverflow answer
|
||||
def _remove_comments(text):
|
||||
def replacer(match):
|
||||
s = match.group(0)
|
||||
if s.startswith('/'):
|
||||
return " " # note: a space and not an empty string
|
||||
else:
|
||||
return s
|
||||
pattern = re.compile(
|
||||
r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',
|
||||
re.DOTALL | re.MULTILINE
|
||||
)
|
||||
return re.sub(pattern, replacer, text)
|
||||
|
||||
def parse_grl_file(grl_fname, libs):
|
||||
global libraries
|
||||
|
||||
libraries = libs
|
||||
with open(grl_fname, 'r') as f:
|
||||
return PARSER.parse(_remove_comments(f.read()))
|
||||
Loading…
Add table
Reference in a new issue