yacc: Build a parser

View source: R/yacc.R

yaccR Documentation

Build a parser

Description

This function is entry point to the library

Usage

yacc(module = NA, args = list(), method = "LALR", debug = FALSE,
  start = NA, check_recursion = TRUE, debugfile = "parser.out",
  outputdir = NA, debuglog = NA, errorlog = NA)

Arguments

module

R6 class containing rules

args

list of arguments that should be passed to constructor

method

type of algorithm

debug

on and off debug mode

start

provide custom start method

check_recursion

should yacc look for recursions in rules

debugfile

the name of the custom debug output logs

outputdir

the dierectory of custom debug logs

debuglog

custom logger for debug messages

errorlog

custom logger for error messages

Value

Parser ready to use

Examples

TOKENS = c('NAME', 'NUMBER')
LITERALS = c('=','+','-','*','/', '(',')')

Parser <- R6::R6Class("Parser",
  public = list(
    tokens = TOKENS,
    literals = LITERALS,
    # Parsing rules
    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))
    }
  )
)

parser <- rly::yacc(Parser)

rly documentation built on May 8, 2022, 5:05 p.m.