単純なものを試す。ルールの書きかた、まとめ方
#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', ) t_A = r'A' t_B = r'B' t_C = r'C' t_D = r'D' t_E = r'E' t_F = r'F' t_a = r'a' t_b = r'b' t_c = r'c' 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 : lower | upper''' def p_lower(p): '''lower : a b c''' print "*abc*" def p_upper(p): '''upper : A B C | D E F''' if p[1] == 'A': print "*ABC*" else: print "*DEF*" 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 b c *abc* input > A B C *ABC* input > D E F *DEF*
複数のルールをまとめて書くこともできる。
#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', ) t_A = r'A' t_B = r'B' t_C = r'C' t_D = r'D' t_E = r'E' t_F = r'F' t_a = r'a' t_b = r'b' t_c = r'c' 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 : lower | upper lower : a b c upper : A B C | D E F''' if p[1] == 'A': print "*ABC*" elif p[1] == 'D': print "*DEF*" elif p[1] == 'a': print "*abc*" 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 b c *abc* input > A B C *ABC* input > D E F *DEF*
「elif p[1] == 'a':」を「else:」にしたら「*abc*」が2つ目の出力として常に出るようになった。変だなと思ったが、input の規則のところでマッチしているのかな???