『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 too large", t.value
        t.value = 0
    return t

def t_STRING(t):
    r'"(?:[^"\\]+|\\.)*"'
    t.value = eval(t.value)
    return t

def t_EOL(t):
    r'\n'
    return t

t_IDENT = r'[a-zA-Z_]\w*'

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_program_stmt(p):
    """program :
               | program stmt EOL"""

def p_program(p):
    "program : program EOL"

def p_stmt(p):
    """stmt : funcall
            | assign"""

def p_stmt_IDENT(p):
    "stmt : IDENT args"
    p[0] = do_funcall(p[1], p[2])

def p_funcall_args(p):
    "funcall : IDENT '(' args ')'"
    p[0] = do_funcall(p[1], p[3])

def p_funcall_no_args(p):
    "funcall : IDENT '(' ')'"
    p[0] = do_funcall(p[1], [])

def p_args1(p):
    "args : primary"
    p[0] = [p[1]]

def p_args2(p):
    "args : args ',' primary"
    p[1].append(p[3])
    p[0] = p[1]

def p_assign(p):
    "assign : IDENT '=' primary"
    p[0] = do_assign(p[1], p[3])

def p_primary_ident(p):
    "primary : IDENT"
    p[0] = do_varref(p[1])

def p_primary_others(p):
    """primary : NUMBER
               | STRING
               | funcall"""
    p[0] = p[1]

def p_error(p):
    global lineno
    try:
        print "%s:%d Syntax error at '%s'" % (fileinput.filename(), fileinput.lineno(), p.value)
    except AttributeError:
        print "%s:%d Syntax error" % (fileinput.filename(), fileinput.lineno())

yacc.yacc()

vtable = {}
lineno = 1

def do_funcall(func, args):
    import string
    cmd_args     = string.join([repr(x) for x in args], ",")
    cmd          = func + "(" + cmd_args + ")"
    cmd_no_paren = func + " " + cmd_args
    
    try:
        return eval(cmd)
    except SyntaxError:
        exec(cmd_no_paren)

def do_assign(vname, val):
    global vtable
    vtable[vname] = val

def do_varref(vname):
    global vtable
    if vtable.has_key(vname):
        return vtable[vname]
    else:
        return eval(vname)

for line in fileinput.input():
    yacc.parse(line)

で、

print((

を入力すると、

foo:1 Syntax error at '('

Commons Lang、Validate.isTrue()

import org.apache.commons.lang.Validate;

public class C2009051000 {
    public static void main(String[] args) {
        Validate.isTrue(true,  "foo", 100);

        Validate.isTrue(false, "foo", 100);
    }
}

で、

Exception in thread "main" java.lang.IllegalArgumentException: foo100
	at org.apache.commons.lang.Validate.isTrue(Validate.java:101)
	at C2009051000.main(C2009051000.java:8)