PLY

『Rubyを256倍使うための本 無道編』の 13.defun/intp.y を移植

関数定義可能。変数スコープあり。コードを理解できていないので、意味(動作)から推測(IntpFrame クラスはなし) class Node: def exec_list(self, nodes): for x in nodes: x.evaluate() class RootNode(Node): def __init__(self, tree): self.tree = tree …

『Rubyを256倍使うための本 無道編』の 13.defun/intp.y を移植

関数定義可能に。ただし、変数スコープなし、グローバル class Node: def exec_list(self, nodes): for x in nodes: x.evaluate() class RootNode(Node): def __init__(self, tree): self.tree = tree def evaluate(self): self.exec_list(self.tree) class …

『Rubyを256倍使うための本 無道編』の 12.if_while/intp.y を移植

class Node: def exec_list(self, nodes): for x in nodes: x.evaluate() class RootNode(Node): def __init__(self, tree): self.tree = tree def evaluate(self): self.exec_list(self.tree) class FuncallNode(Node): def __init__(self, func, args): se…

『Rubyを256倍使うための本 無道編』の 11.op_ok/intp.y を移植

四則演算ができるように #!/usr/bin/env python from math import * import fileinput import ply.lex as lex tokens = ( 'NUMBER', 'STRING', 'IDENT', 'EOL', ) literals = "(),=+-*/" def t_NUMBER(t): r'\d+' try: t.value = int(t.value) except ValueE…

『Rubyを256倍使うための本 無道編』の 09.errmsg/intp.y を移植

#!/usr/bin/env python from math import * import fileinput import ply.lex as lex tokens = ( 'NUMBER', 'STRING', 'IDENT', 'EOL', ) literals = "(),=" def t_NUMBER(t): r'\d+' try: t.value = int(t.value) except ValueError: print "Integer value …

『Rubyを256倍使うための本 無道編』の 08.noarg/intp.y を移植

未知変数は引数のない関数呼び出しと解釈 #!/usr/bin/env python from math import * def foo(): print "foo" import string import ply.lex as lex tokens = ( 'NUMBER', 'STRING', 'IDENT', # 'EOL', ) literals = "(),=" def t_NUMBER(t): r'\d+' try: t.…

『Rubyを256倍使うための本 無道編』の 07.parenomit/intp.y を移植

#!/usr/bin/env python from math import * import string import ply.lex as lex tokens = ( 'NUMBER', 'STRING', 'IDENT', # 'EOL', ) literals = "(),=" def t_NUMBER(t): r'\d+' try: t.value = int(t.value) except ValueError: print "Integer value t…

『Rubyを256倍使うための本 無道編』の 03.func/intp.y を移植

#!/usr/bin/env python from math import * import string import ply.lex as lex tokens = ( 'NUMBER', 'STRING', 'IDENT', # 'EOL', ) literals = "(),=" def t_NUMBER(t): r'\d+' try: t.value = int(t.value) except ValueError: print "Integer value t…

『Rubyを256倍使うための本 無道編』の 01.first/intp.y を移植

#!/usr/bin/env python import string import ply.lex as lex tokens = ( 'NUMBER', 'STRING', 'IDENT', # 'EOL', ) literals = "(),=" def t_NUMBER(t): r'\d+' try: t.value = int(t.value) except ValueError: print "Integer value too large", t.value …

bison マニュアルの多機能電卓 練習問題2

定数 PI, E を追加 #!/usr/bin/env python import ply.lex as lex tokens = ( 'NUM', 'VAR', 'FNCT', ) literals = ['+', '-', '*', '/', '^', '(', ')', '='] def t_NUM(t): r'\d+(\.\d+)*' try: t.value = float(t.value) except ValueError: print "Integ…

bison マニュアルの多機能電卓

#!/usr/bin/env python import ply.lex as lex tokens = ( 'NUM', 'VAR', 'FNCT', ) literals = ['+', '-', '*', '/', '^', '(', ')', '='] def t_NUM(t): r'\d+(\.\d+)*' try: t.value = float(t.value) except ValueError: print "Integer value too large…

bison マニュアルの中間記法電卓

#!/usr/bin/env python import ply.lex as lex tokens = ( 'NUM', ) literals = ['+', '-', '*', '/', '^', '(', ')'] def t_NUM(t): r'\d+(\.\d+)*' try: t.value = float(t.value) except ValueError: print "Integer value too large", t.value t.value =…

bison マニュアルの逆ポーランド記法電卓

#!/usr/bin/env python import ply.lex as lex tokens = ( 'NUM', ) literals = ['+', '-', '*', '/', '^', 'n'] def t_NUM(t): r'\d+(\.\d+)*' try: t.value = float(t.value) except ValueError: print "Integer value too large", t.value t.value = 0 re…

最適化モード

「lex.lex(optimize=1)」「yacc.yacc(optimize=1)」 #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) 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.…

parser, lexer の参照

#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) def t_A(t): r'A' print t.lexer return t 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() im…

yacc.yacc は parser object を返す

#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) 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_i…

debug ファイルの指定

「yacc.yacc(debug=1, debugfile="debugging.out")」 #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) 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…

parsing 中に debugging 情報をたくさん出力

「yacc.parse(debug=1)」 #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) 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 …

parsing table ファイルの出力を止める

「yacc.yacc(write_tables=0)」 #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) 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() i…

parsing table ファイルの出力ディレクトリを変更

「yacc.yacc(tabmodule="foo", outputdir="/tmp")」 #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) 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.…

parsing table ファイル名を変更

「yacc.yacc(tabmodule="foo")」 デフォルトは parsetab.py に出力される #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) t_A = r'A' t_B = r'B' t_C = r'C' t_ignore = " \t" def t_error(t): print "Illegal character '%s'" %…

debugging mode をオフ

「yacc.yacc(debug=0)」 parser.out が出力されなくなる #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) 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.le…

自前 Lexer の指定

「yacc.parse(s, lexer = Lexer())」 #!/usr/bin/env python tokens = ( 'A', 'B', 'C', ) class LexToken: def __init__(self, t, value, lineno, lexpos): self.type = t self.value = value self.lineno = lineno self.lexpos = lexpos class Lexer: def …

LALR でなく SLR を使う

「yacc.yacc(method="SLR")」 #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) 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() imp…

規則の途中のアクションで shift/reduce conflicts が発生してしまう

まんま #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', 'D', 'X', ) t_A = r'A' t_B = r'B' t_C = r'C' t_D = r'D' t_X = r'X' t_ignore = " \t" def t_error(t): print "Illegal character '%s'" % t.value[0] t.lexer.skip(1) le…

規則の途中のアクション

自分で書き下す必要があるようだほぼ、まんま #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', 'D', ) t_A = r'A' t_B = r'B' t_C = r'C' t_D = r'D' t_ignore = " \t" def t_error(t): print "Illegal character '%s'" % t.value[0…

p.lineno(num), p.lexpos(num), p.linespan(num), p.lexspan(num)

#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', 'C', ) 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_i…

エラーまわり

良く分かっていない #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', ) t_A = r'A' t_B = r'B' 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 …

nonassoc

試したが、失敗…(原因不明) #!/usr/bin/env python import ply.lex as lex tokens = ( 'A', ) t_A = r'A' t_ignore = " \t" literals = ['+', '<'] def t_error(t): print "Illegal character '%s'" % t.value[0] t.lexer.skip(1) lex.lex() import ply.yacc…

エラーまわり

#!/usr/bin/env python import ply.lex as lex tokens = ( 'A', 'B', ) t_A = r'A' t_B = r'B' 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 …