R存在这样的解析工具吗?它不一定是我的案例的lex / yacc兼容工具。
(我是R新手)
编辑:我对使用R。
实现另一种语言感兴趣答案 0 :(得分:7)
我开发了一个名为rly的python PLY的克隆。你可以在CRAN中找到它:
install.packages("rly")
以下用法示例:
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)
}
答案 1 :(得分:2)
AFAIK,R没有解析器生成器。
但是,用户创建的packages in R(a.k.a。“extensions”)可以用Java,C或Fortran(当然还有R)编写。因此,您可以使用Lex/Yacc和Bison(在C的情况下)或JavaCC或ANTLR(对于Java)来为您的语言创建词法分析器和解析器并使用它们在你的R代码中。
答案 2 :(得分:2)
请参阅CRAN上的qmrparser包。
答案 3 :(得分:-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
但我不确定这些文件是否构建在官方版本中......