Ply: проблема при определении правил для языка "c" - PullRequest
2 голосов
/ 18 февраля 2011

Я пытаюсь написать синтаксический анализатор для языка c, который сможет заботиться о выражениях, присваиваниях, циклах if-else и while.

вот мои правила:

выражение -> выражение выражение выражение
выражение -> ID
выражение -> NUMBER
выражение -> выражение ID ASSIGN
выражение -> выражение IF THEN выражение
выражение -> WHILE выражение THEN выражение

Все, что в заглавных буквах, является токеном (символ терминала)

При синтаксическом анализе строки «тогда, когда h <= 0, тогда t = 1», кажется, что «h» рассматривается как выражениевыражение правила-> ID).Таким образом, выражение в выражении «WHILE выражение THEN Statement» становится «h».Очевидно, я бы хотел, чтобы оно рассматривало выражение как «h <= 0» (используя выражение «Правила -> выражение»).Как мне убедиться, что это произойдет?

1 Ответ

1 голос
/ 19 февраля 2011

Основываясь на предыдущем посте , где вы спрашивали о модуле ply.lex, приведенный ниже фрагмент выглядит как частичная реализация c-подобной грамматики.Я не очень много использовал ply, но одна из хитростей заключается в том, что вам нужно определить правила грамматики в правильном порядке.

tokens   = [ 'ID', 'NUMBER', 'LESSEQUAL', 'ASSIGN' ]
reserved = {
    'while' : 'WHILE',
    'then'  : 'THEN',
    'if'    : 'IF'
}
tokens += reserved.values()

t_ignore    = ' \t'
t_NUMBER    = r'\d+'
t_LESSEQUAL = r'<='
t_ASSIGN    = r'\='

def t_ID(t):
    r'[a-zA-Z_][a-zA-Z0-9_]*'
    if t.value in reserved:
        t.type = reserved[ t.value ]
    return t

def t_error(t):
    print 'Illegal character'
    t.lexer.skip(1)

def p_statement_assign(p):
    'statement : ID ASSIGN expression'
    p[0] = ('assign', p[1], p[3] )

def p_statement_if(p):
    'statement : IF expression THEN statement'
    p[0] = ('if', p[2], p[4] )

def p_statement_while(p):
    'statement : WHILE expression THEN statement'
    p[0] = ('while', p[2], p[4] )

def p_expression_simple(p):
    '''expression : ID
                  | NUMBER'''
    p[0] = p[1]

def p_expression_cmp(p):
    'expression : expression LESSEQUAL expression'
    p[0] = ( '<=', p[1], p[3] )

import ply.lex as lex
import ply.yacc as yacc
lexer = lex.lex()
parser = yacc.yacc()
inp = 'while h<=0 then t=1'
res = parser.parse(inp)
print res

Вывод из фрагмента:

('while', ('<=', 'h', '0'), ('assign', 't', '1'))
...