忽略 PLY/Yacc Productions 中的换行符
Ignoring new line characters in PLY/Yacc Productions
我正在尝试在我的语法中(在 PLY 中)实现一个结构。如果我将我的结构写在一行上,解析器不会产生语法错误,但如果我将它写在多行上,它会在包含大括号的行上产生语法错误。我的代码如下(没有 ast.py 因为我认为它没有帮助):
main.py
from parser import *
import ply.yacc as yacc
yacc.yacc()
def main():
with open('main.smp') as fp:
for line in fp:
try:
yacc.parse(line)
except EOFError:
break
main()
parser.py(也包含词法分析代码)
import sys
sys.path.insert(0,"../..")
from ast import *
tokens = (
'NAME', 'NUMBER', 'STRUCT', 'LBRACE', 'RBRACE'
)
literals = ['=','+','-','*','/', '(',')', '{', '}']
# Tokens
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
t_LBRACE = r'\{'
t_RBRACE = r'\}'
def t_NUMBER(t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print "Integer value too large", t.value
t.value = 0
return t
def t_STRUCT(t):
r'struct '
return t
t_ignore = " \t"
def t_newline(t):
r'\n+'
t.lexer.lineno += len(t.value)
print "new line"
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.lexer.skip(1)
# Build the lexer
import ply.lex as lex
lexer = lex.lex()
lexer.brace_count = 0
# Parsing rules
precedence = (
('left','+','-'),
('left','*','/'),
('right','UMINUS'),
)
start='statement'
def p_statement_assign(p):
'statement : NAME "=" expression'
names[p[1]] = p[3]
def p_statement_struct(p):
"statement : STRUCT NAME LBRACE statement RBRACE"
print "parsed struct"
def p_statement_expr(p):
'statement : expression'
try:
print p[1].codegen()
except AttributeError:
print p[1], "no attribute"
def p_expression_binop(p):
'''expression : expression '+' expression
| expression '-' expression
| expression '*' expression
| expression '/' expression'''
p[0] = BinOpNode(p[1], p[3], p[2])
def p_expression_uminus(p):
"expression : '-' expression %prec UMINUS"
p[0] = NumNode(-p[2])
def p_expression_group(p):
"expression : '(' expression ')'"
p[0] = NumNode(p[2])
def p_expression_number(p):
"expression : NUMBER"
p[0] = NumNode(p[1])
def p_expression_name(p):
"expression : NAME"
try:
p[0] = names[p[1]]
except LookupError:
print "Undefined name '%s'" % p[1]
p[0] = 0
def p_error(p):
try:
print "{1}: Syntax error on '{0}'".format(p.value, lexer.lineno)
except AttributeError:
print "{0}: Syntax error on line".format(lexer.lineno)
main.smp
struct test
{
9+9
}
输出
new line
2: Syntax error on line
2: Syntax error on '{'
new line
new line
18
4: Syntax error on '}'
你的主循环:
def main():
with open('main.smp') as fp:
for line in fp:
try:
yacc.parse(line)
except EOFError:
break
故意分别解析每一行输入。因此,每一行都需要是完整的 statement
才能使解析成功(对于该行)。
我正在尝试在我的语法中(在 PLY 中)实现一个结构。如果我将我的结构写在一行上,解析器不会产生语法错误,但如果我将它写在多行上,它会在包含大括号的行上产生语法错误。我的代码如下(没有 ast.py 因为我认为它没有帮助):
main.py
from parser import *
import ply.yacc as yacc
yacc.yacc()
def main():
with open('main.smp') as fp:
for line in fp:
try:
yacc.parse(line)
except EOFError:
break
main()
parser.py(也包含词法分析代码)
import sys
sys.path.insert(0,"../..")
from ast import *
tokens = (
'NAME', 'NUMBER', 'STRUCT', 'LBRACE', 'RBRACE'
)
literals = ['=','+','-','*','/', '(',')', '{', '}']
# Tokens
t_NAME = r'[a-zA-Z_][a-zA-Z0-9_]*'
t_LBRACE = r'\{'
t_RBRACE = r'\}'
def t_NUMBER(t):
r'\d+'
try:
t.value = int(t.value)
except ValueError:
print "Integer value too large", t.value
t.value = 0
return t
def t_STRUCT(t):
r'struct '
return t
t_ignore = " \t"
def t_newline(t):
r'\n+'
t.lexer.lineno += len(t.value)
print "new line"
def t_error(t):
print "Illegal character '%s'" % t.value[0]
t.lexer.skip(1)
# Build the lexer
import ply.lex as lex
lexer = lex.lex()
lexer.brace_count = 0
# Parsing rules
precedence = (
('left','+','-'),
('left','*','/'),
('right','UMINUS'),
)
start='statement'
def p_statement_assign(p):
'statement : NAME "=" expression'
names[p[1]] = p[3]
def p_statement_struct(p):
"statement : STRUCT NAME LBRACE statement RBRACE"
print "parsed struct"
def p_statement_expr(p):
'statement : expression'
try:
print p[1].codegen()
except AttributeError:
print p[1], "no attribute"
def p_expression_binop(p):
'''expression : expression '+' expression
| expression '-' expression
| expression '*' expression
| expression '/' expression'''
p[0] = BinOpNode(p[1], p[3], p[2])
def p_expression_uminus(p):
"expression : '-' expression %prec UMINUS"
p[0] = NumNode(-p[2])
def p_expression_group(p):
"expression : '(' expression ')'"
p[0] = NumNode(p[2])
def p_expression_number(p):
"expression : NUMBER"
p[0] = NumNode(p[1])
def p_expression_name(p):
"expression : NAME"
try:
p[0] = names[p[1]]
except LookupError:
print "Undefined name '%s'" % p[1]
p[0] = 0
def p_error(p):
try:
print "{1}: Syntax error on '{0}'".format(p.value, lexer.lineno)
except AttributeError:
print "{0}: Syntax error on line".format(lexer.lineno)
main.smp
struct test
{
9+9
}
输出
new line
2: Syntax error on line
2: Syntax error on '{'
new line
new line
18
4: Syntax error on '}'
你的主循环:
def main():
with open('main.smp') as fp:
for line in fp:
try:
yacc.parse(line)
except EOFError:
break
故意分别解析每一行输入。因此,每一行都需要是完整的 statement
才能使解析成功(对于该行)。