1 # Copyright (C) 2019 Nick Downing <nick@ndcode.org>
2 # SPDX-License-Identifier: GPL-2.0-with-bison-exception
4 # This program is free software; you can redistribute it and/or modify it under
5 # the terms of the GNU General Public License as published by the Free Software
6 # Foundation; version 2.
8 # This program is distributed in the hope that it will be useful, but WITHOUT
9 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 # You should have received a copy of the GNU General Public License along with
14 # this program; if not, write to the Free Software Foundation, Inc., 51
15 # Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
17 # As a special exception, you may create a larger work that contains part or
18 # all of the piyacc parser skeleton and distribute that work under terms of
19 # your choice, so long as that work isn't itself a parser generator using the
20 # skeleton or a modified version thereof as a parser skeleton. Alternatively,
21 # if you modify or redistribute the parser skeleton itself, you may (at your
22 # option) remove this special exception, which will cause the skeleton and the
23 # resulting piyacc output files to be licensed under the GNU General Public
24 # License without this special exception.
27 #import xml.etree.ElementTree
28 from ndcode.piyacc import element
29 from ndcode.piyacc import lex_yy
31 # this can be redefined in SECTION1
40 self.first_line = first_line
41 self.first_column = first_column
42 self.last_line = last_line
43 self.last_column = last_column
52 def YYLLOC_DEFAULT(current, stack, n):
54 current.first_line = stack[-n][2].first_line
55 current.first_column = stack[-n][2].first_column
56 current.last_line = stack[-1][2].last_line
57 current.last_column = stack[-1][2].last_column
59 current.first_line = current.last_line = stack[-1][2].last_line
60 current.first_column = current.last_column = stack[-1][2].last_column
76 yy_element_stack = None
80 def yyparse(factory, *args, **kwargs):
81 global yystack, yychar, yyval, yyloc, yylval, yylloc, yy_element_stack
83 # GENERATE INITIALACTION
86 yystack = [(-1, yylval, yylloc.copy())] # kludge for bison compatibility
90 #print('state', state, 'yystack', yystack)
91 reduce = yy_lr1dfa_states[state][4]
94 yychar = lex_yy.yylex()
95 #print('yychar', yychar, 'yylval', yylval, 'yylloc', yylloc, 'lex_yy.yytext', lex_yy.yytext)
96 #print('lex_yy.yy_element_space')
97 #xml.etree.ElementTree.dump(lex_yy.yy_element_space)
98 #print('lex_yy.yy_element_token')
99 #xml.etree.ElementTree.dump(lex_yy.yy_element_token)
100 action = yy_lr1dfa_states[state][1][
101 bisect.bisect_right(yy_lr1dfa_states[state][0], yychar)
104 yyerror(yylloc, 'syntax error')
105 assert False # error recovery is not implemented yet
106 if (action & 1) == 0:
107 yystack.append((state, yylval, yylloc.copy()))
109 # push space then AST element contiguously onto yy_element_stack
110 # even numbered elements are spaces, odd numbered elements are AST
111 yy_element_stack.extend(
112 [lex_yy.yy_element_space, lex_yy.yy_element_token]
116 #print('shift', state)
120 #print('reduce', reduce)
121 len_symbols, ref_data = yy_lr1dfa_productions[reduce]
122 # GENERATE YYLLOC_DEFAULT BEGIN
123 YYLLOC_DEFAULT(yyloc, yystack, len_symbols)
125 base = len(yystack) - len_symbols
126 yystack.append((state, None, None)) # only has effect if len_symbols == 0
127 state, yyval, _ = yystack[base]
133 yystack.append((state, yyval, yyloc.copy()))
135 # action creates empty space in yy_element_stack[base * 2] if needed
136 assert len(yy_element_stack) >= base * 2 - 1
138 # concatenate yy_element_stack[base * 2 - 1:] to a single AST element
139 yy_element_stack[base * 2 - 1:] = [
141 yy_element_stack[base * 2 - 1:],
146 state = yy_lr1dfa_states[state][3][
147 bisect.bisect_right(yy_lr1dfa_states[state][2], reduce)
151 # return space then AST then space in the user's choice of element type
152 yy_element_stack.append(lex_yy.yy_element_space)
153 return element.concatenate(yy_element_stack, factory, *args, **kwargs)