Permalink
Browse files

+ A really rudimentary postscript parser

  • Loading branch information...
1 parent 1e95a97 commit b00b329caf1b36feb2ded855160a3b9113a83f41 @kschiess committed Jan 2, 2011
Showing with 55 additions and 9 deletions.
  1. +5 −2 lib/wt.rb
  2. +10 −0 lib/wt/ast.rb
  3. +15 −0 lib/wt/compiler.rb
  4. +10 −5 lib/wt/parser.rb
  5. BIN samples/arith.ps
  6. BIN samples/test.ps
  7. +13 −0 spec/wt/compiler_spec.rb
  8. +2 −2 spec/wt/parser_spec.rb
View
@@ -4,6 +4,9 @@
module Wt
end
-require 'wt/ast'
require 'wt/parser'
-require 'wt/transform'
+
+require 'wt/ast'
+require 'wt/transform'
+
+require 'wt/compiler'
View
@@ -2,9 +2,19 @@
# AST nodes
module Wt::AST
class IntLit < Struct.new(:int)
+ def compile
+ int
+ end
end
class Expression < Struct.new(:left, :op, :right)
+ OP_TABLE = {
+ '+' => 'add'
+ }
+
+ def compile
+ "#{left.compile} #{right.compile} #{OP_TABLE[op]}"
+ end
end
class Assign < Struct.new(:ident, :exp)
View
@@ -0,0 +1,15 @@
+
+# The entry point and main controller.
+#
+class Wt::Compiler
+
+ def parser; Wt::Parser.new; end
+ def transformer; Wt::Transform.new; end
+
+ # Compiles source and returns compilation result.
+ #
+ def compile(source)
+ ast = transformer.apply(parser.parse(source))
+ ast.compile
+ end
+end
View
@@ -2,25 +2,26 @@
require 'parslet'
class Wt::Parser < Parslet::Parser
+ root(:expression)
rule(:expression) {
assignment |
aexpression }
rule(:assignment) { identifier >> s('=') >> expression.as(:exp) }
rule(:aexpression) {
- mexpression.as(:left) >> c('+-').as(:op) >> expression.as(:right) |
+ mexpression.as(:left) >> c('+-', :op) >> expression.as(:right) |
mexpression
}
rule(:mexpression) {
- atom.as(:left) >> c('*/').as(:op) >> mexpression.as(:right) |
+ atom.as(:left) >> c('*/', :op) >> mexpression.as(:right) |
atom }
rule(:atom) { integer | s('(') >> expression >> s(')') }
rule(:identifier) {
(match['a-z'] >> match['\w\d'].repeat).as(:ident) >> space?
}
- rule(:integer) { c('0-9').as(:int) }
+ rule(:integer) { c('0-9', :int) }
rule(:space?) { space.maybe }
rule(:space) { match['\\s'].repeat }
@@ -33,7 +34,11 @@ def s(str)
# Defines a set of characters followed by any number of spaces.
#
- def c(chars)
- match[chars] >> space?
+ def c(chars, name=nil)
+ if name
+ match[chars].as(name) >> space?
+ else
+ match[chars] >> space?
+ end
end
end
View
Binary file not shown.
View
Binary file not shown.
View
@@ -0,0 +1,13 @@
+require 'spec_helper'
+
+describe Wt::Compiler do
+ let(:compiler) { described_class.new() }
+ let(:output) { compiler.compile(source) }
+ subject { output }
+
+ context "a simple addition" do
+ let(:source) { '1 + 2'}
+
+ it { should == '1 2 add'}
+ end
+end
View
@@ -11,9 +11,9 @@
as(left: {int: '1'}, right: {int: '2'}, op: '+') }
it { should parse("1-2").
as(left: {int: '1'}, right: {int: '2'}, op: '-') }
- it { should parse("1*2").
+ it { should parse("1 * 2").
as(left: {int: '1'}, right: {int: '2'}, op: '*') }
- it { should parse("1/2").
+ it { should parse("1 / 2").
as(left: {int: '1'}, right: {int: '2'}, op: '/') }
it { should parse('1*2 + 3') }
it { should parse('1 * (1 + 3)') }

0 comments on commit b00b329

Please sign in to comment.