Skip to content

Commit

Permalink
More parsing.
Browse files Browse the repository at this point in the history
  • Loading branch information
brixen committed Nov 11, 2010
1 parent 6f3923c commit 608f508
Show file tree
Hide file tree
Showing 8 changed files with 119 additions and 85 deletions.
36 changes: 32 additions & 4 deletions lib/poison/bootstrap/parser.rb
Expand Up @@ -12,20 +12,48 @@ def parse_file(name)

# Parsing callbacks

def syntax_error
raise Syntax::SyntaxError
end

def statements(values)
Syntax::Statements.new values
end

def nil_kind
Syntax::NilKind.new
end

def true_kind
Syntax::Boolean.new true
end

def false_kind
Syntax::Boolean.new false
end

def imag(value)
value + 'i'
Syntax::Imaginary.new value.to_f
end

def real(value)
value.to_f
Syntax::Real.new value.to_f
end

def hex(value)
value.to_i 16
Syntax::Integer.new value.to_i 16
end

def int(value)
value.to_i 10
Syntax::Integer.new value.to_i 10
end

def path(name)
"/" + name
end

def message(name)
name
end

def method_missing(sym, *args)
Expand Down
28 changes: 15 additions & 13 deletions lib/poison/bootstrap/parser/ext/parser.g
Expand Up @@ -27,17 +27,17 @@
#define YY_XVAR P
#define YY_NAME(N) poison_code_##N

#define PN_VAL(n) rb_funcall(P->parser, rb_intern(n), 0)
#define PN_AST(n, v) rb_funcall(P->parser, rb_intern(n), 1, v)

%}

poison = -- s:statements end-of-file { $$ = rb_funcall(P->parser,
rb_intern("result"), 1, s); }
poison = -- s:statements end-of-file { $$ = P->ast = PN_AST("statements", s); }

statements = s1:stmt { }
(sep s2:stmt { })*
sep?
| '' { $$ = Qnil; }
| '' { $$ = PN_VAL("nil_kind"); }

stmt = s:sets
( or x:sets { }
Expand Down Expand Up @@ -144,15 +144,15 @@ table = table-start s:statements table-end { }
block = block-start s:statements block-end { }
lick = lick-start i:lick-items lick-end { }

path = '/' message { }
message = < utfw+ > - { }
path = '/' m:message { $$ = PN_AST("path", m); }
message = < utfw+ > - { $$ = PN_AST("message", rb_str_new(yytext, yyleng)); }

value = i:immed - { }
| lick

immed = nil { $$ = Qnil; }
| true { $$ = Qtrue; }
| false { $$ = Qfalse; }
immed = nil { $$ = PN_VAL("nil_kind"); }
| true { $$ = PN_VAL("true_kind"); }
| false { $$ = PN_VAL("false_kind"); }
| imag { $$ = PN_AST("imag", rb_str_new(yytext, yyleng)); }
| real { $$ = PN_AST("real", rb_str_new(yytext, yyleng)); }
| hex { $$ = PN_AST("hex", rb_str_new(yytext, yyleng)); }
Expand Down Expand Up @@ -211,8 +211,8 @@ hexl = [0-9A-Fa-f]
hex = '0x' < hexl+ >
digits = '0' | [1-9] [0-9]*
int = < digits >
real = < digits '.' digits ('e' [-+] [0-9]+)? >
imag = real 'i'
real = < digits '.' digits ('e' [-+]? [0-9]+)? >
imag = (real | int) 'i'

q1 = [']
c1 = < (!q1 utf8)+ > { }
Expand Down Expand Up @@ -276,14 +276,16 @@ VALUE poison_parse(VALUE self, VALUE string) {
P.size = RSTRING_LEN(string);
P.bytes = RSTRING_PTR(string);

VALUE result = Qtrue;
GREG *G = poison_code_parse_new(&P);
G->pos = G->limit = 0;

if (!poison_code_parse(G)) result = Qfalse;
if (!poison_code_parse(G)) {
rb_funcall(P.parser, rb_intern("syntax_error"), 0);
return Qnil;
}
poison_code_parse_free(G);

return result;
return P.ast;
}

void Init_parser(void) {
Expand Down
1 change: 1 addition & 0 deletions lib/poison/bootstrap/parser/ext/parser.h
Expand Up @@ -14,6 +14,7 @@ typedef struct PoisonParserState {
unsigned int size;
char* bytes;
VALUE parser;
VALUE ast;
} Poison;

VALUE poison_parse(VALUE self, VALUE string);
Expand Down
74 changes: 7 additions & 67 deletions lib/poison/bootstrap/syntax.rb
@@ -1,7 +1,11 @@
require 'poison/bootstrap/syntax/node'
require 'poison/bootstrap/syntax/value'
require 'poison/bootstrap/syntax/expression'

module Poison
class SyntaxError < Exception; end
module Syntax
class SyntaxError < Exception; end

class Syntax
def initialize(parse_tree)
@syntax = parse_tree.node
end
Expand All @@ -14,15 +18,6 @@ def graph
@syntax.graph
end

class Node
def to_sexp
end

def graph
Rubinius::AST::AsciiGrapher.new(self, Node).print
end
end

class Script < Node
attr_accessor :statements

Expand All @@ -37,7 +32,7 @@ def to_sexp

class Statements < Node
def initialize(statements)
@statements = statements
@statements = Array(statements)
end

def to_sexp
Expand Down Expand Up @@ -149,18 +144,6 @@ def sexp_name
end
end

class Expression < Node
attr_accessor :expression

def initialize(expression)
@expression = expression
end

def to_sexp
[:expr].concat @expression.map { |e| e.to_sexp }
end
end

class Message < Node
attr_accessor :name

Expand All @@ -173,49 +156,6 @@ def to_sexp
end
end

class Value < Node
attr_accessor :value

def initialize(value)
@value = value
end

def to_sexp
[:value, @value.to_sexp]
end
end

class Literal < Node
attr_accessor :value

def initialize(value)
@value = value
end

def to_sexp
[@value, nil, nil]
end
end

class NilKind < Literal
def initialize
@value = nil
end
end

class Boolean < Literal
end

class Integer < Literal
end

class Real < Literal
end

class Imaginary < Literal
end

class String < Literal
end
end
end
15 changes: 15 additions & 0 deletions lib/poison/bootstrap/syntax/expression.rb
@@ -0,0 +1,15 @@
module Poison
module Syntax
class Expression < Node
attr_accessor :expression

def initialize(expression)
@expression = expression
end

def to_sexp
[:expr].concat @expression.map { |e| e.to_sexp }
end
end
end
end
12 changes: 12 additions & 0 deletions lib/poison/bootstrap/syntax/node.rb
@@ -0,0 +1,12 @@
module Poison
module Syntax
class Node
def to_sexp
end

def graph
Rubinius::AST::AsciiGrapher.new(self, Node).print
end
end
end
end
36 changes: 36 additions & 0 deletions lib/poison/bootstrap/syntax/value.rb
@@ -0,0 +1,36 @@
module Poison
module Syntax
class Value < Node
attr_accessor :value

def initialize(value)
@value = value
end

def to_sexp
[:value, @value.to_sexp]
end
end

class Boolean < Value
end

class Integer < Value
end

class Real < Value
end

class Imaginary < Value
end

class String < Value
end

class NilKind < Value
def initialize
@value = nil
end
end
end
end
2 changes: 1 addition & 1 deletion spec/custom/matchers/parse_as.rb
Expand Up @@ -4,7 +4,7 @@ def initialize(expected)
end

def matches?(actual)
@actual = Poison::Parser.new.parse_string(actual).to_sexp.last
@actual = Poison::Parser.new.parse(actual).to_sexp.last
@actual == @expected
end

Expand Down

0 comments on commit 608f508

Please sign in to comment.