2011-07-02 64 views
4

做這樣的分析工具存在的R?它不一定是我的情況下的lex/yacc兼容工具。用於R的Lex-和YACC-like工具?

(我的R新手)

編輯:我感興趣的實施使用R.

+0

http://stackoverflow.com/questions/5705564/is-there-an-existing-antlr-or-irony:下面使用的

install.packages("rly") 

例-grammar-for-r – NickD

+1

這是關於定義R語法的語法。我認爲海報想要在R中編寫一些其他語言的解析器。 – Spacedman

+0

準確!如果我要使用R來實現另一個解釋器,解析工具是否存在? – adamo

回答

2

AFAIK另一種語言,存在一種用於R.

沒有解析器生成

然而,用戶創建packages in R(又名 「擴展名」),可以用Java,C或Fortran的(和R,當然)。所以,你可以使用Lex/YaccBison(在C的情況下)或者JavaCCANTLR(用於Java)來創建用於您的語言的詞法分析器和解析器和使用那些在你的R代碼裏面。

-1

AFAIK,有作爲R源代碼YACC語法文件。 查看這些文件,

R-2.15.2\src\main\gram.y R-2.15.2\src\main\gramLatex.y R-2.15.2\src\main\gramRd.y

但我不知道,如果這些文件是建立在官方版本......

4

我開發RLY名爲蟒蛇簾布層的克隆。您可以在CRAN找到它:

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, 
    # 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)) 
    } 
) 
) 

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) 
}