空規則?の扱い
#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', ) t_A = r'A' t_ignore = " \t" def t_error(t): print "Illegal character '%s'" % t.value[0] t.lexer.skip(1) lex.lex() import ply.yacc as yacc def p_input(p): '''input : | A''' if (len(p) > 1): print p[1] def p_error(p): print "Syntax error at '%s'" % p.value yacc.yacc() while 1: try: s = raw_input('input > ') except EOFError: break #if not s: continue #if not s: s = "" yacc.parse(s)
で、
input > A A input > input >
最初にエンターを入力すると以下のようにエラーになってしまうようだ(理由不明。先読みまわりで???)
input > Traceback (most recent call last): File "./20080410_ply00.py", line 39, in ? yacc.parse(s) File "/usr/lib/python2.3/site-packages/ply/yacc.py", line 237, in parse lookahead = get_token() # Get the next token File "/usr/lib/python2.3/site-packages/ply/lex.py", line 342, in token raise RuntimeError, "No input string given with input()" RuntimeError: No input string given with input()
空ルールを削除すると、
#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', ) t_A = r'A' t_ignore = " \t" def t_error(t): print "Illegal character '%s'" % t.value[0] t.lexer.skip(1) lex.lex() import ply.yacc as yacc def p_input(p): '''input : A''' print p[1] def p_error(p): print "Syntax error at '%s'" % p.value yacc.yacc() while 1: try: s = raw_input('input > ') except EOFError: break #if not s: continue yacc.parse(s)
で、
input > A A input > Traceback (most recent call last): File "./20080410_ply01.py", line 37, in ? yacc.parse(s) File "/usr/lib/python2.3/site-packages/ply/yacc.py", line 346, in parse tok = self.errorfunc(errtoken) File "./20080410_ply01.py", line 26, in p_error print "Syntax error at '%s'" % p.value AttributeError: 'NoneType' object has no attribute 'value'
empty を書いた方が読みやすいと言っているようだけど、empty というルールがあらかじめ用意されているわけでもないようだ。
#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', ) t_A = r'A' t_ignore = " \t" def t_error(t): print "Illegal character '%s'" % t.value[0] t.lexer.skip(1) lex.lex() import ply.yacc as yacc def p_input(p): '''input : empty | A''' if (len(p) > 1): print p[1] def p_error(p): print "Syntax error at '%s'" % p.value yacc.yacc() while 1: try: s = raw_input('input > ') except EOFError: break #if not s: continue #if not s: s = "" yacc.parse(s)
で、
./20080410_ply02.py:22: Symbol 'empty' used, but not defined as a token or a rule. Traceback (most recent call last): File "./20080410_ply02.py", line 29, in ? yacc.yacc() File "/usr/lib/python2.3/site-packages/ply/yacc.py", line 2156, in yacc raise YaccError,"Unable to construct parser." ply.yacc.YaccError: Unable to construct parser.
以下のように自分で empty というのを定義。
別に empty なんていらないのでは?と思わないでもない。
#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', ) t_A = r'A' t_ignore = " \t" def t_error(t): print "Illegal character '%s'" % t.value[0] t.lexer.skip(1) lex.lex() import ply.yacc as yacc def p_input(p): '''input : empty | A''' if (len(p) > 1): print p[1] def p_empty(p): 'empty :' pass def p_error(p): print "Syntax error at '%s'" % p.value yacc.yacc() while 1: try: s = raw_input('input > ') except EOFError: break #if not s: continue #if not s: s = "" yacc.parse(s)
で、
input > A A input > None input > None