tag_names
):
return last_action
+ def add_to_groups(
+ self,
+ _ast,
+ production,
+ first_action,
+ add_space,
+ groups,
+ pos
+ ):
+ return first_action, add_space, pos
class Action(Item):
# GENERATE ELEMENT() BEGIN
# lookaheads (list of initial_set, can_be_empty)
[([], True)],
# ref_data
- last_action
+ ([], None, last_action)
)
)
assert isinstance(self[0], AST.Text) # temporary
i.tag_name = tag_names[i.index - 1]
i.offset = -len(symbols)
return self[0]
+ def add_to_groups(
+ self,
+ _ast,
+ production,
+ first_action,
+ add_space,
+ groups,
+ pos
+ ):
+ if first_action: # had first action, treat this as symbol
+ return True, False, pos - 2
+ return True, add_space, pos
class DPrec(Item):
# GENERATE ELEMENT(int value) BEGIN
):
# just skip %empty for now (fix this later)
return last_action
+ def add_to_groups(
+ self,
+ _ast,
+ production,
+ first_action,
+ add_space,
+ groups,
+ pos
+ ):
+ # just skip %empty for now (fix this later)
+ return first_action, add_space, pos
class Merge(Item):
# GENERATE ELEMENT() BEGIN
# lookaheads (list of initial_set, can_be_empty)
[([], True)],
# ref_data
- last_action
+ ([], None, last_action)
)
)
symbols.append(
_ast.tags[_ast.symbols[self.symbol]._tag].name
)
return None
+ def add_to_groups(
+ self,
+ _ast,
+ production,
+ first_action,
+ add_space,
+ groups,
+ pos
+ ):
+ return True, False, pos - 2
class GroupElement(Item):
# GENERATE ELEMENT() BEGIN
tag_names
)
return last_action
+ def add_to_groups(
+ self,
+ _ast,
+ production,
+ first_action,
+ add_space,
+ groups,
+ pos
+ ):
+ pos0 = pos
+ for i in self[:0:-1]:
+ first_action, add_space, pos0 = i.add_to_groups(
+ _ast,
+ production,
+ add_space,
+ first_action,
+ groups,
+ pos0
+ )
+ groups.append((pos0, pos, self[0]))
+ return first_action, True, pos - 1
# GENERATE ELEMENT(int lhs_nonterminal, int n_symbols, int last_terminal, int precedence_terminal) BEGIN
def __init__(
_ast.tags[_ast.symbols[self.lhs_nonterminal]._tag].name
)
+ # go backwards collecting negative indices of element group start/end
+ # here we ignore the first action, rather than holding the most recent
+ first_action = False # have not had first action yet
+ add_space = False # didn't absorb inter-token space
+ groups = []
+ pos = 0
+ for i in self[::-1]:
+ first_action, add_space, pos = i.add_to_groups(
+ _ast,
+ self,
+ first_action,
+ add_space,
+ groups,
+ pos
+ )
+
_lr1.productions.append(
(
# symbols (list of terminal_set, nonterminal_set)
# lookaheads (list of initial_set, can_be_empty)
[([], False) for i in range(len(symbols))] + [([], True)],
# ref_data
- last_action
+ (groups, pos if add_space else None, last_action)
)
)
# lookaheads (list of initial_set, can_be_empty)
[([], False), ([], True)],
# ref_data
- None # temporary
+ ([], None, None) # temporary
)
],
# precedences
_lr1dfa = _ast.to_lr1().to_lalr1()
assert _lr1dfa.eof_terminal == 0
actions = [i for _, i in _lr1dfa.productions]
+ #print('actions', actions)
_lr1dfa.productions = [
(_lr1dfa.productions[i][0], 'yy_action{0:d}'.format(i))
for i in range(len(_lr1dfa.productions))
[
'''def yy_action{0:d}():
global yyval, yyloc
-{1:s}'''.format(
+{1:s}{2:s}{3:s}'''.format(
i,
+ ''.join(
+ [
+ ''' yy_element_stack[{0:s}:{1:s}] = [
+ element.Element(
+ 'root',
+ children = [
+ element.concatenate(
+ yy_element_stack[{2:s}:{3:s}],
+{4:s} )
+ ]
+ )
+ ]
+'''.format(
+ str(pos0) if pos0 else 'len(yy_element_stack)',
+ str(pos1) if pos1 else '',
+ str(pos0) if pos0 else 'len(yy_element_stack)',
+ str(pos1) if pos1 else '',
+ ast_text_to_python(factory_text, ' ')
+ )
+ for pos0, pos1, factory_text in actions[i][0]
+ ]
+ ),
+ (
+ ''
+ if actions[i][1] is None else
+ ''' yy_element_stack[{0:s}:{1:s}] = [
+ element.Element('root')
+ ]
+'''.format(
+ (
+ str(actions[i][1])
+ if actions[i][1] else
+ 'len(yy_element_stack)'
+ ),
+ (
+ str(actions[i][1])
+ if actions[i][1] else
+ ''
+ )
+ )
+ ),
(
' pass\n'
- if actions[i] is None else
- ast_text_to_python(actions[i], ' ')
+ if actions[i][2] is None else
+ ast_text_to_python(actions[i][2], ' ')
)
)
for i in range(len(actions))
}
;
E : (?E{ast.AST.Add}E '+' E) {
- yy_element_stack[-5:] = [
- element.Element(
- 'root',
- children = [
- element.concatenate(yy_element_stack[-5:], ast.AST.Add)
- ]
- )
- ]
$$ = $1 + $3
}
- | E '-' E {
- yy_element_stack[-5:] = [
- element.Element(
- 'root',
- children = [
- element.concatenate(yy_element_stack[-5:], ast.AST.Sub)
- ]
- )
- ]
+ | (?E{ast.AST.Sub}E '-' E) {
$$ = $1 - $3
}
- | E '*' E {
- yy_element_stack[-5:] = [
- element.Element(
- 'root',
- children = [
- element.concatenate(yy_element_stack[-5:], ast.AST.Mul)
- ]
- )
- ]
+ | (?E{ast.AST.Mul}E '*' E) {
$$ = $1 * $3
}
- | E '/' E {
- yy_element_stack[-5:] = [
- element.Element(
- 'root',
- children = [
- element.concatenate(yy_element_stack[-5:], ast.AST.Div)
- ]
- )
- ]
+ | (?E{ast.AST.Div}E '/' E) {
$$ = $1 / $3
}
| '(' E ')' {
$$ = $2
}
- | '-' E %prec UMINUS {
+ | (?E{ast.AST.Neg}'-' E) %prec UMINUS {
$$ = -$2
- yy_element_stack[-3:] = [
- element.Element(
- 'root',
- children = [
- element.concatenate(yy_element_stack[-3:], ast.AST.Neg)
- ]
- )
- ]
}
| NUM
;