From 9ccaba0b1684a99fbe7d8f74d2333c13649ff5ed Mon Sep 17 00:00:00 2001
From: Roguelearg <lebasketteurdu76@hotmail.fr>
Date: Thu, 7 Sep 2017 17:05:06 +0200
Subject: [PATCH] Add grammar to depend

---
 Gemfile          |  2 ++
 Gemfile.lock     |  9 +++++
 data/test.txt    |  2 +-
 exe/mm2ep-depend | 14 ++++----
 lib/lexer.rb     | 33 ++++++++++---------
 lib/parser.rb    | 85 ++++++++++++++++++++++++++++++------------------
 6 files changed, 89 insertions(+), 56 deletions(-)

diff --git a/Gemfile b/Gemfile
index a52dc6d..1080d03 100644
--- a/Gemfile
+++ b/Gemfile
@@ -33,6 +33,8 @@ gem 'turbolinks', '~> 5'
 gem 'jbuilder', '~> 2.5'
 
 gem 'thor'
+gem 'rly'
+gem 'pry'
 
 group :development, :test do
   # Call 'byebug' anywhere in the code to stop execution and get a debugger console
diff --git a/Gemfile.lock b/Gemfile.lock
index 9cf7bbe..baaa294 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -61,6 +61,7 @@ GEM
       xpath (~> 2.0)
     childprocess (0.7.1)
       ffi (~> 1.0, >= 1.0.11)
+    coderay (1.1.1)
     coffee-rails (4.2.2)
       coffee-script (>= 2.2.0)
       railties (>= 4.0.0)
@@ -97,6 +98,10 @@ GEM
     nio4r (2.1.0)
     nokogiri (1.8.0)
       mini_portile2 (~> 2.2.0)
+    pry (0.10.4)
+      coderay (~> 1.1.0)
+      method_source (~> 0.8.1)
+      slop (~> 3.4)
     public_suffix (3.0.0)
     puma (3.10.0)
     rack (2.0.3)
@@ -129,6 +134,7 @@ GEM
     rb-fsevent (0.10.2)
     rb-inotify (0.9.10)
       ffi (>= 0.5.0, < 2)
+    rly (0.2.3)
     ruby_dep (1.5.0)
     rubyzip (1.2.1)
     sass (3.5.1)
@@ -145,6 +151,7 @@ GEM
     selenium-webdriver (3.5.1)
       childprocess (~> 0.5)
       rubyzip (~> 1.0)
+    slop (3.6.0)
     spring (2.0.2)
       activesupport (>= 4.2)
     spring-watcher-listen (2.0.1)
@@ -190,8 +197,10 @@ DEPENDENCIES
   jbuilder (~> 2.5)
   listen (>= 3.0.5, < 3.2)
   mm2ep_core!
+  pry
   puma (~> 3.7)
   rails (~> 5.1.2)
+  rly
   sass-rails (~> 5.0)
   selenium-webdriver
   spring
diff --git a/data/test.txt b/data/test.txt
index 30dade7..fe31b32 100644
--- a/data/test.txt
+++ b/data/test.txt
@@ -1 +1 @@
-(truc_bidule = false)
+( truc_bidule = true )
diff --git a/exe/mm2ep-depend b/exe/mm2ep-depend
index fc790f4..d59d18e 100755
--- a/exe/mm2ep-depend
+++ b/exe/mm2ep-depend
@@ -3,6 +3,8 @@
 $:.insert(0, 'lib')
 
 require 'thor'
+require 'rly'
+require 'pry'
 require 'parser.rb'
 require 'lexer.rb'
 
@@ -12,17 +14,13 @@ module Mm2ep
     class ParseCli < Thor
       desc 'parse INFILE', 'Parse INFILE into tokens'
       def parse(infile)
-        parser = Parser.new
+
         File.open(infile).each_line do |line|
-          parser.parse(line)
+          parser = Parser.new(Lexer.new)
+          token = parser.parse(line.chomp)
+          puts token
         end
       end
-        desc 'lexer ', 'Lexe into tokens'
-        def lexer()
-          truc = Lexer.new
-          truc.validate ['VAR', 'SPACE']
-        end
-
     end
   end
 end
diff --git a/lib/lexer.rb b/lib/lexer.rb
index 602d8d1..f63b260 100755
--- a/lib/lexer.rb
+++ b/lib/lexer.rb
@@ -1,23 +1,24 @@
 module Mm2ep
   module Depend
-    class Lexer
-      attr_reader :expr
+    class Lexer < Rly::Lex
 
-      BOOL_EXPR = ['T_BOOL', 'F_BOOL']
-      START_EXPR = ['VAR', 'BOOL_EXPR','NOT_OP', 'EXPR', 'L_PAR']
+      token :L_PAR, /\(/
+      token :NUMBER, /[0-9]+(\.[0-9]+)?/
+      token :STRING, /"[^"]*"/
+      token :EQ_OP, /\=/
+      token :T_BOOL, /[tT]rue/
+      token :F_BOOL, /[fF]alse/
+      token :VAR, /[a-z][a-zA-Z0-9_]+/
+      token :AND_OP, /AND/
+      token :OR_OP, /OR/
+      token :NOT_OP, /NOT/
+      token :SPACE, /\s+/
+      token :R_PAR, /\)/
 
-      def initialize
-        @expr = []
-      end
-
-      def validate_space
-      end
-
-      def validate tokens
-        if START_EXPR.include? tokens[0]
-          @expr << tokens[0]
-          tokens = tokens.drop(1)
-        end
+      on_error do |t|
+        puts "Illegal character #{t.value}"
+        t.lexer.pos += 1
+        nil
       end
 
     end # class
diff --git a/lib/parser.rb b/lib/parser.rb
index b9ee272..7b763ee 100755
--- a/lib/parser.rb
+++ b/lib/parser.rb
@@ -1,39 +1,62 @@
 module Mm2ep
   module Depend
-    class Parser
-      attr_reader :tokens
+    class Parser < Rly::Yacc
 
-      TOKEN = {
-        'L_PAR' => "(",
-        'NUMBER' => /[0-9]+(\.[0-9]+)?/,
-        'STRING' => /"[^"]*"/,
-        'EQ_OP' => "=",
-        'T_BOOL' => /[tT]rue/,
-        'F_BOOL' => /[fF]alse/,
-        'VAR' => /[a-z][a-zA-Z0-9_]+/,
-        'AND_OP' => "AND",
-        'OR_OP' => "OR",
-        'NOT_OP' => "NOT",
-        'SPACE' => /\s+/,
-        'R_PAR' => ")"
-      }.freeze
-
-      def initialize
-        @tokens = []
+      rule 'statement : expr' do |st, e|
+        st.value = e.value
       end
 
-      def parse s
-        s = s.split(' ')
-        s.each_with_index do |element, idx|
-          TOKEN.each do |token, regex|
-            next if element.sub!(regex, '').nil?
-            @tokens << token
-            break if element.nil?
-          end
-          @tokens <<'SPACE' unless idx == s.length-1
-        end
-        puts @tokens
-      end # def
+      rule 'expr : NOT_OP SPACE expr' do |ex, l, s, e|
+        ex.value = "#{l.value} #{s.value} #{e.value}"
+      end
+
+      rule 'expr : expr SPACE AND_OP SPACE expr' do |ex, l, s, e, sp, r|
+        ex.value = "#{l.value} #{s.value} #{e.value} #{sp.value} #{r.value}"
+      end
+
+      rule 'expr : expr SPACE OR_OP SPACE expr' do |ex, l, s, e, sp, r|
+        ex.value = "#{l.value} #{s.value} #{e.value} #{sp.value} #{r.value}"
+      end
+      rule 'expr : L_PAR SPACE expr SPACE R_PAR' do |ex, l, s, e, sp, r|
+        ex.value = "#{l.value} #{s.value} #{e.value} #{sp.value} #{r.value}"
+      end
+
+      rule 'expr : VAR SPACE EQ_OP SPACE F_BOOL' do |ex, v, s, eq, _, n|
+        ex.value = "#{v.value} #{s.value} #{eq.value} #{s.value} #{n.value}"
+      end
+
+      rule 'expr : VAR SPACE EQ_OP SPACE T_BOOL' do |ex, v, s, eq, _, n|
+        ex.value = "#{v.value} #{s.value} #{eq.value} #{s.value} #{n.value}"
+      end
+
+      rule 'expr : VAR SPACE EQ_OP SPACE STRING' do |ex, v, s, eq, _, n|
+        ex.value = "#{v.value} #{s.value} #{eq.value} #{s.value} #{n.value}"
+      end
+
+      rule 'expr : VAR SPACE EQ_OP SPACE NUMBER' do |ex, v, s, eq, _, n|
+        ex.value = "#{v.value} #{s.value} #{eq.value} #{s.value} #{n.value}"
+      end
+
+      # lexer do
+      #
+      # end
+      #
+      # def initialize
+      #   @tokens = []
+      # end
+      #
+      # def parse s
+      #   s = s.split(' ')
+      #   s.each_with_index do |element, idx|
+      #     TOKEN.each do |token, regex|
+      #       next if element.sub!(regex, '').nil?
+      #       @tokens << token
+      #       break if element.nil?
+      #     end
+      #     @tokens <<'SPACE' unless idx == s.length-1
+      #   end
+      #   puts @tokens
+      # end # def
 
     end # class
   end # module