'Lex' and 'Yacc'

R implementation of the common parsing tools 'lex' and 'yacc'.


RLY is a 100% R implementation of the common parsing tools lex and yacc. This project is a R clone of Ply.

How to Use

RLY consists of two files : lex.R and yacc.R.

 library(rly)

The examples directory contains several different examples.

A simple example is found at the end of this document

Resources

The GitHub page for RLY can be found at:

 https://github.com/systemincloud/rly

Example

Here is a simple example showing a RLY implementation of a calculator with variables.

library(rly)
 
TOKENS = c('NAME', 'NUMBER')
LITERALS = c('=','+','-','*','/', '(',')')
 
Lexer <- R6Class("Lexer",
  public = list(
    tokens = TOKENS,
    literals = LITERALS,
    t_NAME = '[a-zA-Z_][a-zA-Z0-9_]*',
    t_NUMBER = function(re='\\d+', t) {
      t$value <- strtoi(t$value)
      return(t)
    },
    t_ignore = " \t",
    t_newline = function(re='\\n+', t) {
      t$lexer$lineno <- t$lexer$lineno + nchar(t$value)
      return(NULL)
    },
    t_error = function(t) {
      cat(sprintf("Illegal character '%s'", t$value[1]))
      t$lexer$skip(1)
      return(t)
    }
  )
)
 
Parser <- R6Class("Parser",
  public = list(
    tokens = TOKENS,
    literals = LITERALS,
    precedence = list(c('left','+','-'),
                      c('left','*','/'),
                      c('right','UMINUS')),
    # dictionary of names
    names = new.env(hash=TRUE),
    p_statement_assign = function(doc='statement : NAME "=" expression', p) {
      self$names[[as.character(p$get(2))]] <- p$get(4)
    },
    p_statement_expr = function(doc='statement : expression', p) {
      cat(p$get(2))
      cat('\n')
    },
    p_expression_binop = function(doc="expression : expression '+' expression
                                                  | expression '-' expression
                                                  | expression '*' expression
                                                  | expression '/' expression", p) {
           if(p$get(3) == '+') p$set(1, p$get(2) + p$get(4))
      else if(p$get(3) == '-') p$set(1, p$get(2) - p$get(4))
      else if(p$get(3) == '*') p$set(1, p$get(2) * p$get(4))
      else if(p$get(3) == '/') p$set(1, p$get(2) / p$get(4))
    },
    p_expression_uminus = function(doc="expression : '-' expression %prec UMINUS", p) {
      p$set(1, -p$get(3))
    },
    p_expression_group = function(doc="expression : '(' expression ')'", p) {
      p$set(1, p$get(3))
    },
    p_expression_number = function(doc='expression : NUMBER', p) {
      p$set(1, p$get(2))
    },
    p_expression_name = function(doc='expression : NAME', p) {
      p$set(1, self$names[[as.character(p$get(2))]])
    },
    p_error = function(p) {
      if(is.null(p)) cat("Syntax error at EOF")
      else           cat(sprintf("Syntax error at '%s'", p$value))
    }
  )
)
 
lexer  <- rly::lex(Lexer)
parser <- rly::yacc(Parser)
 
while(TRUE) {
  cat('calc > ')
  s = readLines(file("stdin"), n=1)
  if(s == 'exit') break
  parser$parse(s, lexer)
}

News

Changes in v1.4.2

BUG FIXES

  1. Fix: Error in log$info(" ! shift/reduce conflict ...

Changes in v1.4.1

BUG FIXES

  1. Fix: Error: object 'rprec_rlevel' not found.

  2. Fix: could not find function "appender.console".

Changes in v1.4.0

NEW FEATURES

  1. You can define literals as a string of characters e.g.: literals = ':;,=*{}()<>[]'.

Changes in v1.3.0

NOTES

  1. Refactor demos.

  2. Declare Depends: R (>= 3.3.0) in DESCRIPTION file.

Changes in v1.2.1

NOTES

  1. Single quote the software names 'lex' and 'yacc' both in Title and Description.

Changes in v1.2.0

NEW FEATURES

  1. LRParser : add function restart.

BUG FIXES

  1. Error when no literals defined at all.

  2. YaccProduction : Function get don't accept negative arguments.

Changes in v1.1.0

NEW FEATURES

  1. YaccProduction : add length function to the class (ex. p$length() ).

  2. Implement tracking. YaccProduction new methods: p$linespan(n) and p$lexspan(n).

  3. Implement error recovery.

BUG FIXES

  1. Lex is duplicating numeric tokens.

Changes in v1.0.3

NOTES

  1. Use CRAN template of MIT license.

  2. Add author of PLY python library as one of the authors of this extension.

  3. Add BSD license of PLY to file inst/COPYRIGHTS.

Changes in v1.0.2

BUG FIXES

  1. Fix DESCRIPTION due to 'Non-FOSS package license (file LICENSE)' message.

NOTES

  1. Replace .Internal(inspect) function with C code.

Changes in v1.0.1

BUG FIXES

  1. Library not working on 64-bit R.

Reference manual

It appears you don't have a PDF plugin for this browser. You can click here to download the reference manual.

install.packages("rly")

1.6.2 by Marek Jagielski, a year ago


https://github.com/systemincloud/rly


Report a bug at https://github.com/systemincloud/rly/issues


Browse source code at https://github.com/cran/rly


Authors: Marek Jagielski [aut, cre, cph] , David M. Beazley [aut, cph] , Yasutaka Tanaka [ctb] , Henrico Witvliet [ctb]


Documentation:   PDF Manual  


MIT + file LICENSE license


Imports R6, futile.logger

Suggests testthat


Imported by ggconf, pds3, thriftr.


See at CRAN