)
else:
assert False
- elif isinstance(i, PYACC.Section2.Rules.RHS.Action):
+ elif isinstance(self[i], PYACC.Section2.Rules.RHS.Action):
assert i == len(self) - 1
- assert isinstance(self[i][0], PYACC.Text)
- pyacc.actions_text.append(self[i][0])
+ assert isinstance(self[i][0], PYACC.BracedCode)
+ pyacc.actions_braced_code.append(self[i][0])
break
else:
- pyacc.actions_text.append('')
+ pyacc.actions_braced_code.append(PYACC.BracedCode())
character_set = pyacc.nonterminal_symbols[lhs_symbol].character_set
character = len(pyacc.grammar)
):
pass
- # GENERATE ELEMENT(list(ref) prologue_text, set(int) characters_used, list(ref) terminal_symbols, list(ref) nonterminal_symbols, ref grammar, list(ref) actions_text) BEGIN
+ # GENERATE ELEMENT(list(ref) prologue_text, set(int) characters_used, list(ref) terminal_symbols, list(ref) nonterminal_symbols, ref grammar, list(ref) actions_braced_code) BEGIN
def __init__(
self,
tag = 'PYACC',
terminal_symbols = [],
nonterminal_symbols = [],
grammar = None,
- actions_text = []
+ actions_braced_code = []
):
element.Element.__init__(
self,
self.terminal_symbols = terminal_symbols
self.nonterminal_symbols = nonterminal_symbols
self.grammar = grammar
- self.actions_text = (
- [element.deserialize_str(i) for i in actions_text.split()]
- if isinstance(actions_text, str) else
- actions_text
+ self.actions_braced_code = (
+ [element.deserialize_str(i) for i in actions_braced_code.split()]
+ if isinstance(actions_braced_code, str) else
+ actions_braced_code
)
def serialize(self, ref_list, indent = 0):
element.Element.serialize(self, ref_list, indent)
)
self.set('grammar', element.serialize_ref(self.grammar, ref_list))
self.set(
- 'actions_text',
- ' '.join([element.serialize_str(i) for i in self.actions_text])
+ 'actions_braced_code',
+ ' '.join([element.serialize_str(i) for i in self.actions_braced_code])
)
def deserialize(self, ref_list):
element.Element.deserialize(self, ref_list)
for i in self.get('nonterminal_symbols', '').split()
]
self.grammar = element.deserialize_ref(self.get('grammar', '-1'), ref_list)
- self.actions_text = [
+ self.actions_braced_code = [
element.deserialize_str(i)
- for i in self.get('actions_text', '').split()
+ for i in self.get('actions_braced_code', '').split()
]
def copy(self, factory = None):
result = element.Element.copy(
result.terminal_symbols = self.terminal_symbols
result.nonterminal_symbols = self.nonterminal_symbols
result.grammar = self.grammar
- result.actions_text = self.actions_text
+ result.actions_braced_code = self.actions_braced_code
return result
def repr_serialize(self, params):
element.Element.repr_serialize(self, params)
params.append(
'grammar = {0:s}'.format(repr(self.grammar))
)
- if len(self.actions_text):
+ if len(self.actions_braced_code):
params.append(
- 'actions_text = [{0:s}]'.format(
- ', '.join([repr(i) for i in self.actions_text])
+ 'actions_braced_code = [{0:s}]'.format(
+ ', '.join([repr(i) for i in self.actions_braced_code])
)
)
def __repr__(self):
self.characters_used = set()
self.terminal_symbols = [
PYACC.Symbol(name = '$end', character_set = [0x100, 0x101]),
- PYACC.Symbol(name = 'error', character_set = [0x101, 0x102]),
- PYACC.Symbol(name = '$undefined', character_set = [0x102, 0x103])
+ PYACC.Symbol(name = 'error', character_set = [0x101, 0x102])
]
self.nonterminal_symbols = []
self.grammar = regex.Grammar(
)
]
)
- self.actions_text = []
+ self.actions_braced_code = []
# variables that won't be serialized
# note: in name_to_symbol, >= 0 is terminal, < 0 is ~nonterminal
- # (we do not bother storing the '$end' and '$undefined' entries)
+ # (we do not bother storing the '$end' entry, it can't be looked up)
name_to_symbol = {'error': 1}
# perform the semantic analysis pass
self,
lr1dfa,
n_terminals,
- undefined_terminal,
translate_terminals,
n_nonterminals,
translate_nonterminals
],
0
)
- print(self.translate)
- print(self.rule_data)
# unpack tables into numpy arrays so we can manipulate them efficiently
# note: the goto table is transposed with respect to the action table,
action_table[mask] = -action_table[mask]
assert numpy.all(goto_table != 0)
goto_table[goto_table == -1] = 0
- print(action_table)
- print(goto_table)
# find out which column the transition to each state occurs in, this
# must be unique and is called the "accessing symbol" for the state
)[numpy.newaxis, numpy.newaxis, :],
0
)
- self.accessing_symbols = numpy.full(
+ self.accessing_symbols = numpy.zeros(
(len(lr1dfa.states),),
- undefined_terminal,
numpy.int16
)
for i in range(1, len(lr1dfa.states)):
self.accessing_symbols[i] = accessing_symbol[0]
else:
assert False
- #print(self.accessing_symbols)
# default_action is yydefact, default_goto is yydefgoto
# find default reduce (most common negative value per action_table row)
# n_productions == self.rule_data.shape[0]
# n_nonterminals == self.goto_pointer.shape[0]
self.n_terminals = n_terminals
- self.undefined_terminal = undefined_terminal
def generate(pyacc, skel_file, out_file):
# generate the tables using an expanded character set, consisting of:
# than the internal way as only the set of lr1dfa.productions[] indices)
# generate translate table for character literals and terminal symbols
- n_terminals = 0
+ n_terminals = 1 # room for "$undefined"
translate_terminals = numpy.zeros(
(lr1dfa.n_terminals,),
numpy.int16
)
- undefined_terminal = len(pyacc.characters_used) + 2
- translate_terminals[:0x100] = undefined_terminal
for i in sorted(pyacc.characters_used):
translate_terminals[i] = n_terminals
n_terminals += 1
bison_lr1dfa = BisonLR1DFA(
lr1dfa,
n_terminals,
- undefined_terminal,
translate_terminals,
n_nonterminals,
translate_nonterminals
''.join([element.get_text(i, 0) for i in pyacc.prologue_text])
)
)
+ elif line == '/* GENERATE TOKENSEQUAL */\n':
+ fout.write(
+ '''/* GENERATE TOKENSEQUAL BEGIN */{0:s}
+/* GENERATE TOKENSEQUAL END*/
+'''.format(
+ ','.join(
+ [
+ '\n {0:s} = {1:d}'.format(
+ pyacc.terminal_symbols[i].name,
+ 0x100 + i
+ )
+ for i in range(2, len(pyacc.terminal_symbols))
+ ]
+ )
+ )
+ )
+ elif line == '/* GENERATE TOKENS */\n':
+ fout.write(
+ '''/* GENERATE TOKENS BEGIN */
+{0:s}/* GENERATE TOKENS END*/
+'''.format(
+ ''.join(
+ [
+ '#define {0:s} {1:d}\n'.format(
+ pyacc.terminal_symbols[i].name,
+ 0x100 + i
+ )
+ for i in range(2, len(pyacc.terminal_symbols))
+ ]
+ )
+ )
+ )
elif line == '/* GENERATE SECTION1SECOND */\n':
fout.write(
'''/* GENERATE SECTION1SECOND BEGIN */
# yytname (textual terminal/nonterminal name) wraps 70 columns
x = 72
yytname_lines = []
- for i in (
+ for i in (
+ ['"$undefined"'] +
+ [
+ '"\'{0:s}\'"'.format(
+ chr(i)
+ if i >= 0x20 else
+ '\\x{0:02x}'.format(i)
+ )
+ for i in sorted(pyacc.characters_used)
+ ] +
['"{0:s}"'.format(i.name) for i in pyacc.terminal_symbols] +
['"{0:s}"'.format(i.name) for i in pyacc.nonterminal_symbols] +
['YY_NULLPTR']
/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
by yylex, with out-of-bounds checking. */
-#define YYUNDEFTOK {6:d}
-#define YYMAXUTOK {7:d}
+#define YYUNDEFTOK 0
+#define YYMAXUTOK {6:d}
-#define YYTRANSLATE(YYX) \
+#define YYTRANSLATE(YYX) \\
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
as returned by yylex, without out-of-bounds checking. */
static const yytype_uint16 yytranslate[] =
-{{{8:s}
+{{{7:s}
}};
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
static const yytype_uint16 yyrline[] =
-{{{9:s}
+{{{8:s}
}};
#endif
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
-{{{10:s}
+{{{9:s}
}};
#endif
/* YYTOKNUM[NUM] -- (External) token number corresponding to the
(internal) symbol number NUM (which must be that of a token). */
static const yytype_uint16 yytoknum[] =
-{{{11:s}
+{{{10:s}
}};
# endif
-#define YYPACT_NINF {12:d}
+#define YYPACT_NINF {11:d}
-#define yypact_value_is_default(Yystate) \
- (!!((Yystate) == (-1)))
+#define yypact_value_is_default(Yystate) \\
+ (!!((Yystate) == ({12:d})))
#define YYTABLE_NINF -1
-#define yytable_value_is_error(Yytable_value) \
+#define yytable_value_is_error(Yytable_value) \\
0
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
bison_lr1dfa.rule_data.shape[0],
# YYNSTATES
bison_lr1dfa.action_pointer.shape[0],
- # YYUNDEFTOK
- bison_lr1dfa.undefined_terminal,
# YYMAXUTOK
bison_lr1dfa.translate.shape[0] - 1,
# yytranslate
),
# YYPACT_NINF
-bison_lr1dfa.entry_base,
+ # yypact_value_is_default
+ -bison_lr1dfa.entry_base,
# yypact
','.join(
[
'''/* GENERATE SECTION2 BEGIN */
{0:s}/* GENERATE SECTION2 END */
'''.format(
- ''.join(
+ '\n'.join(
[
- '''case {0:d}:
-YY_RULE_SETUP
-{1:s} YY_BREAK
+ ''' case {0:d}:
+ {1:s}
+ break;
'''.format(
i,
- element.get_text(pyacc.actions_text[i], 0)
+ ''.join(
+ [
+ element.get_text(j, 0)
+ for j in pyacc.actions_braced_code[i]
+ ]
+ )
)
- for i in range(1, len(pyacc.actions_text))
+ for i in range(1, len(pyacc.actions_braced_code))
+ if len(pyacc.actions_braced_code[i])
]
)
)
+%token TOKEN
%start start
%%
-start: ;
+start: { /* do something */ } | start TOKEN { /* do something else */ };
---- y.tab.c.orig 2018-07-02 11:50:12.830973575 +1000
-+++ y.tab.c 2018-07-02 19:21:26.303835927 +1000
+--- y.tab.c.orig 2018-07-06 07:51:34.462479398 +1000
++++ y.tab.c 2018-07-06 09:03:46.066520012 +1000
@@ -63,7 +63,7 @@
/* Copy the first part of user declarations. */
# ifndef YY_NULLPTR
# if defined __cplusplus && 201103L <= __cplusplus
-@@ -107,7 +107,7 @@
+@@ -95,11 +95,11 @@
+ # define YYTOKENTYPE
+ enum yytokentype
+ {
+- TOKEN = 258
++/* GENERATE TOKENSEQUAL */
+ };
+ #endif
+ /* Tokens. */
+-#define TOKEN 258
++/* GENERATE TOKENS */
+
+ /* Value type. */
+ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+@@ -117,7 +117,7 @@
/* Copy the second part of user declarations. */
--#line 111 "y.tab.c" /* yacc.c:358 */
+-#line 121 "y.tab.c" /* yacc.c:358 */
+/* GENERATE SECTION1SECOND */
#ifdef short
# undef short
-@@ -346,155 +346,7 @@
+@@ -356,156 +356,8 @@
# endif
#endif /* !YYCOPY_NEEDED */
-/* YYFINAL -- State number of the termination state. */
-#define YYFINAL 2
-/* YYLAST -- Last index in YYTABLE. */
--#define YYLAST 0
+-#define YYLAST 3
-
-/* YYNTOKENS -- Number of terminals. */
--#define YYNTOKENS 3
+-#define YYNTOKENS 4
-/* YYNNTS -- Number of nonterminals. */
-#define YYNNTS 2
-/* YYNRULES -- Number of rules. */
--#define YYNRULES 2
+-#define YYNRULES 3
-/* YYNSTATES -- Number of states. */
--#define YYNSTATES 3
+-#define YYNSTATES 4
-
-/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
- by yylex, with out-of-bounds checking. */
-#define YYUNDEFTOK 2
--#define YYMAXUTOK 257
+-#define YYMAXUTOK 258
-
-#define YYTRANSLATE(YYX) \
- ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-- 2, 2, 2, 2, 2, 2, 1, 2
+- 2, 2, 2, 2, 2, 2, 1, 2, 3
-};
-
-#if YYDEBUG
- /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
-static const yytype_uint8 yyrline[] =
-{
-- 0, 3, 3
+- 0, 4, 4, 4
-};
-#endif
-
- First, the terminals, then, starting at YYNTOKENS, nonterminals. */
-static const char *const yytname[] =
-{
-- "$end", "error", "$undefined", "$accept", "start", YY_NULLPTR
+- "$end", "error", "$undefined", "TOKEN", "$accept", "start", YY_NULLPTR
-};
-#endif
-
- (internal) symbol number NUM (which must be that of a token). */
-static const yytype_uint16 yytoknum[] =
-{
-- 0, 256, 257
+- 0, 256, 257, 258
-};
-# endif
-
- STATE-NUM. */
-static const yytype_int8 yypact[] =
-{
-- -1, 0, -1
+- -1, 0, -1, -1
-};
-
- /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
- means the default is an error. */
-static const yytype_uint8 yydefact[] =
-{
-- 2, 0, 1
+- 2, 0, 1, 3
-};
-
- /* YYPGOTO[NTERM-NUM]. */
- number is the opposite. If YYTABLE_NINF, syntax error. */
-static const yytype_uint8 yytable[] =
-{
-- 2
+- 2, 0, 0, 3
-};
-
--static const yytype_uint8 yycheck[] =
+-static const yytype_int8 yycheck[] =
-{
-- 0
+- 0, -1, -1, 3
-};
-
- /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
- symbol of state STATE-NUM. */
-static const yytype_uint8 yystos[] =
-{
-- 0, 4, 0
+- 0, 5, 0, 3
-};
-
- /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
-static const yytype_uint8 yyr1[] =
-{
-- 0, 3, 4
+- 0, 4, 5, 5
-};
-
- /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
-static const yytype_uint8 yyr2[] =
-{
-- 0, 2, 0
+- 0, 2, 0, 2
-};
-
+-
+/* GENERATE TABLES */
-
++
#define yyerrok (yyerrstatus = 0)
#define yyclearin (yychar = YYEMPTY)
-@@ -1169,8 +1021,7 @@
+ #define YYEMPTY (-2)
+@@ -1179,20 +1031,8 @@
YY_REDUCE_PRINT (yyn);
switch (yyn)
{
--
--#line 1174 "y.tab.c" /* yacc.c:1648 */
-+/* GENERATE SECTION2 */
+- case 2:
+-#line 4 "skel.y" /* yacc.c:1648 */
+- { /* do something */ }
+-#line 1186 "y.tab.c" /* yacc.c:1648 */
+- break;
+-
+- case 3:
+-#line 4 "skel.y" /* yacc.c:1648 */
+- { /* do something else */ }
+-#line 1192 "y.tab.c" /* yacc.c:1648 */
+- break;
+-
++/* GENERATE SECTION2 */
+
+-#line 1196 "y.tab.c" /* yacc.c:1648 */
default: break;
}
/* User semantic actions sometimes alter yychar, and that requires
-@@ -1398,3 +1249,5 @@
+@@ -1420,3 +1260,5 @@
#endif
return yyresult;
}