2014-11-29 5 views
1

Так что я пишу грамматику на Ply, которая распознает базовые операторы С, такие как объявление переменной или оператор while. В настоящее время, что я хочу сделать, это быть в состоянии объединить все маркеры, а затем распечатать его или же он распространяется на дерево, как это:ply конкатенация строк на грамматике

def p_whileStmt(p): 
    '''whileStmt : WHILE '(' condition ')' '{' stmt '}' ''' 
    p[0] += p[1] + p[2] + p[3] + p[4] + p[5] + p[6] + p[7] 

Есть ли лучший способ объединить все маркеры (Мне нужны только значения символов, мне нужно только построить строку), чем тот, который я использую?

EDIT: В некоторых случаях мне нужно сцепить все маркеры, за исключением нескольких, как, например:

def p_whileStmt(p): 
    '''whileStmt : WHILE '(' condition ')' '{' stmt '}' ''' 
    p[0] += p[1] + p[3] + p[5] 

ответ

3

Вы можете избежать += с помощью

p[0] = ''.join(p) 

И p[0] += p[1]+p[3]+p[5] вы можете сделать

p[0] += ''.join(p[1::2]) 
+0

В слое, р [0] является то, что будет передаваться "вверх" для функций родительского грамматики. Обычно вы добавляете узел AST. – jjm

+2

Upvote для показа, как использовать шаги в срезах. – jjm

2

В питона, когда у вас есть список строк, вы обычно хотите использовать str.join, который как более простой, так и более эффективный. Здесь вам нужно что-то вроде:

p[0] += ''.join(p[1:]) 

Предполагая, что p [0] уже является строкой.

Если вам нужно объединить определенные токены, ваш способ сделать это нормально. Это немного глупый дизайн со стороны ply, чтобы поместить каждый токен в p, но точка должна быть очень близка к поведению yacc.

Смежные вопросы