history

青木日記 RSS

<前の日 | この月 | 次の日>

2006-07-28

iPod

iPod を買ってしまった。nano 2GB のやつ。

これで俺も人並のデジタルライフが送れるだろうか。

(14:46)

net/http での deflate 対応

net/http の deflate 対応パッチをもらった。 おおむねそのまま使えそうなので、 近いうちに修正を加えて 1.9 に取り込む予定。

(15:45)

Racc: Dynamic Parser Generation

レポートを書いてたはずなのにいつのまにか Racc をいじっている不思議。 今日は Parsec ちっくに many とか option を使えるようにしてみた。

どことなく C 風の文法 (アクションはまだ適当)

 grammar = Racc::Grammar.define {
   g = self
 
   precedence_table {
     higher
     right '['
     right '*@', '&@', :CAST
     right '+@', '-@', '!'
     left '*', '/'
     left '+', '-'
     left ">>", "<<"
     left '&'
     left '|'
     left "==", "!=", '>', '>=', '<', '<='
     left "&&"
     left "||"
     lower
   }
 
   g.program = many(:decl)
 
   g.decl = seq(:defvar)      {|field|  declare field }\
          | seq(:defun)       {|func|   declare func }\
          | seq(:defstruct)   {|struct| define_type struct }\
          | seq(:defunion)    {|union|  define_type union }
 
   g.defvar = seq(:storage, :type, :IDENT, option(:initval), ';') {
                  |storage,  type,  name,  val,               _|
                Field.new(storage, type, name, val)
              }
 
   g.initval = seq('=', :expr) {|_, expr| expr }
 
   g.defun = seq(
     :storage, :type, :IDENT, '(', :params, ')', '{', :scope, '}') {
     |storage,  type,  name,   _,   params,  _,   _,   body,   _|
               Function.new(storage, type, name, params, body)
             }
 
   g.params = separated_by(',', :slot)
 
   g.defstruct = seq(:STRUCT, :IDENT, '{', many(:memb), '}', ';') {
                     |_,       tag,    _,  membs,        _,   _|
                   StructType.new(tag, membs)
                 }
 
   g.defunion  = seq(:UNION, :IDENT, '{', many(:memb), '}', ';') {
                     |_,      tag,    _,  membs,        _,   _|
                   UnionType.new(tag, membs)
                 }
 
   g.memb = seq(:slot, ';') {|slot, _| slot }
 
   g.struct_decl = seq(:STRUCT, :IDENT, ';') {|_, tag, _|
                     StructType.new(tag, nil)
                   }
 
   g.union_decl = seq(:UNION, :IDENT, ';') {|_, tag, _|
                    UnionType.new(tag, nil)
                  }
 
   g.scope = seq(_ { push_scope }, many(:vardecl), :stmts) {|_, decls, stmts|
               pop_scope
               ScopeNode.new(decls, stmts)
             }
 
   g.storage = null() | seq(:STATIC) | seq(:EXTERN)
 
   g.slot = seq(:type, :IDENT) {|type, name| Slot.new(type, new) }
 
   g.type = seq(:VOID) {|_| @types.void }\
          | seq(:CHAR) {|_| @types.char }\
          | seq(:SHORT) {|_| @types.short }\
          | seq(:INT) {|_| @types.int }\
          | seq(:LONG) {|_| @types.long }\
          | seq(:LONG, :LONG) {|_,_| @types.longlong }\
          | seq(:type, '[',']') {|t,_,_| @types.array_of(t) }\
          | seq(:type, '*') {|t,_,_| @types.pointer_to(t) }\
          | seq(:STRUCT, :IDENT) {|_, tag| @types.struct(tag) }\
          | seq(:UNION, :IDENT) {|_, tag| @types.union(tag) }
 
   g.stmts = many(:stmt) {|stmts| stmts.compact }
 
   g.stmt = seq(';') { nil }\
          | seq(:expr, ';') {|node, _| node }\
          | seq(:IF, '(', :expr, ')', '{', :scope, '}', option(:else)){
               |_,   _,   cond,  _,   _,   then_body, _, else_node|
              n = IfNode.new(cond, then_body, else_node)
              n.location = cond.location
              n
            }\
          | seq(:WHILE, '(', :expr, ')', '{', :scope, '}') {
               |_,      _,   cond,  _,   _,   body,     _|
              n = WhileNode.new(cond, body)
              n.location = cond.location
              n
            }\
          | seq(:BREAK, ';') {|*| BreakNode.new(nil) }\
          | seq(:CONTINUE, ';') {|*| ContinueNode.new(nil) }\
          | seq(:RETURN, ';') {|*| ReturnNode.new(nil) }\
          | seq(:RETURN, :expr, ';') {|_, expr, _| ReturnNode.new(expr) }
 
   g.else = seq(:ELSE, '{', :stmts, '}') {|_, _, body, _| body }
 
   g.expr = seq(:primary)\
          | seq(:expr, '+',  :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '-',  :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '*',  :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '/',  :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '&',  :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '|',  :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '>>', :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '<<', :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '>',  :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '>=', :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '<',  :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '<=', :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '==', :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '!=', :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '&&', :expr) {|*a| newnode(BinaryOpNode, *a) }\
          | seq(:expr, '||', :expr) {|*a| newnode(BinaryOpNode, *a) }
 
   g.primary = seq(:DIGIT) {|num| newnode(LiteralNode, @types.int, num) }\
             | seq(:CHARACTER) {|ch| newnode(LiteralNode, @types.char, ch) }\
             | seq(:STRING) {|str|
                 newnode(LiteralNode,
                         @target.types(@types.char),
                         string_constant(str))
               }\
             | seq(:IDENT) {|sym| newnode(VarrefNode, @namespace, sym) }\
             | seq('+', :primary).prec('+@') {|op, expr|
                 newnode(UnaryOpNode, op, expr)
               }\
             | seq('-', :primary).prec('-@') {|op, expr|
                 newnode(UnaryOpNode, op, expr)
               }\
             | seq('!', :primary) {|op, expr|
                 newnode(UnaryOpNode, op, expr)
               }\
             | seq('*', :primary).prec('*@') {|op, expr|
                 newnode(UnaryOpNode, op, expr)
               }\
             | seq('&', :primary).prec('&@') {|op, expr|
                 newnode(UnaryOpNode, op, expr)
               }\
             | seq(:primary, '[', :expr, ']') {|expr, _, idx, _|
                 newnode(BinaryOpNode, '[]', expr, idx)
               }\
             | seq(:IDENT, '(', separated_by(',', :expr), ')') {
                  |name,   _,   args,                       _|
                 newnode(FuncallNode, name, args)
               }\
             | seq(:cast, :primary).prec(:CAST) {|type, node|
                 CastNode.new(type, node)
               }\
             | seq('(', :expr, ')') {|_, node, _| node }
 }

生成される文法

rule 1 program:
rule 2 program: program decl
rule 3 decl: defvar
rule 4 decl: defun
rule 5 decl: defstruct
rule 6 decl: defunion
rule 7 decl: struct_decl
rule 8 decl: union_decl
rule 9 defvar: storage type IDENT option@initval ";"
rule 10 option@initval:
rule 11 option@initval: initval
rule 12 initval: "=" expr
rule 13 defun: storage type IDENT "(" params ")" "{" scope "}"
rule 14 separated_by1@slot: slot
rule 15 separated_by1@slot: separated_by1@slot "," slot
rule 16 params:
rule 17 params: separated_by1@slot
rule 18 defstruct: STRUCT IDENT "{" many@memb "}" ";"
rule 19 many@memb:
rule 20 many@memb: many@memb memb
rule 21 defunion: UNION IDENT "{" many@memb "}" ";"
rule 22 memb: slot ";"
rule 23 struct_decl: STRUCT IDENT ";"
rule 24 union_decl: UNION IDENT ";"
rule 25 scope: @1 many@vardecl stmts
rule 26 @1:
rule 27 many@vardecl:
rule 28 many@vardecl: many@vardecl vardecl
rule 29 storage:
rule 30 storage: STATIC
rule 31 storage: EXTERN
rule 32 slot: type IDENT
rule 33 type: VOID
rule 34 type: CHAR
rule 35 type: SHORT
rule 36 type: INT
rule 37 type: LONG
rule 38 type: LONG LONG
rule 39 type: type "[" "]"
rule 40 type: type "*"
rule 41 type: STRUCT IDENT
rule 42 type: UNION IDENT
rule 43 stmts: many@stmt-1-base
rule 44 many@stmt-1-base:
rule 45 many@stmt-1-base: many@stmt-1-base stmt
rule 46 stmt: ";"
rule 47 stmt: expr ";"
rule 48 stmt: IF "(" expr ")" "{" scope "}" option@else
rule 49 stmt: WHILE "(" expr ")" "{" scope "}"
rule 50 stmt: BREAK ";"
rule 51 stmt: CONTINUE ";"
rule 52 stmt: RETURN ";"
rule 53 stmt: RETURN expr ";"
rule 54 option@else:
rule 55 option@else: else
rule 56 else: ELSE "{" stmts "}"
rule 57 expr: primary
rule 58 expr: expr "+" expr
rule 59 expr: expr "-" expr
rule 60 expr: expr "*" expr
rule 61 expr: expr "/" expr
rule 62 expr: expr "&" expr
rule 63 expr: expr "|" expr
rule 64 expr: expr ">>" expr
rule 65 expr: expr "<<" expr
rule 66 expr: expr ">" expr
rule 67 expr: expr ">=" expr
rule 68 expr: expr "<" expr
rule 69 expr: expr "<=" expr
rule 70 expr: expr "==" expr
rule 71 expr: expr "!=" expr
rule 72 expr: expr "&&" expr
rule 73 expr: expr "||" expr
rule 74 primary: DIGIT
rule 75 primary: CHARACTER
rule 76 primary: STRING
rule 77 primary: IDENT
rule 78 primary: "+" primary
rule 79 primary: "-" primary
rule 80 primary: "!" primary
rule 81 primary: "*" primary
rule 82 primary: "&" primary
rule 83 primary: primary "[" expr "]"
rule 84 primary: IDENT "(" option@separated_by1@expr ")"
rule 85 primary: cast primary
rule 86 primary: "(" expr ")"
rule 87 separated_by1@expr: expr
rule 88 separated_by1@expr: separated_by1@expr "," expr
rule 89 option@separated_by1@expr:
rule 90 option@separated_by1@expr: separated_by1@expr

(03:10)

名前
メールアドレス

<前の日 | この月 | 次の日>
2002|04|05|06|07|08|09|10|11|12|
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|04|05|06|09|10|
2009|07|
2010|09|

Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved. LIRS