假设我有以下两个包含正则表达式的字符串.我如何合并它们?更具体地说,我希望将这两个表达式作为替代.
$a = '# /[a-z] #i';
$b = '/ Moo /x';
$c = preg_magic_coalesce('|', $a, $b);
// Desired result should be equivalent to:
// '/ \/[a-zA-Z] |Moo/'
Run Code Online (Sandbox Code Playgroud)
当然,这样做作为字符串操作是不实际的,因为它涉及解析表达式,构造语法树,合并树然后输出相当于树的另一个正则表达式.没有这最后一步,我真的很开心.不幸的是,PHP没有RegExp类(或者是吗?).
有没有办法实现这个目标?顺便说一句,是否有其他语言提供方式?这不是一个很正常的场景吗?可能不会.:-(
或者,是否有一种方法可以有效地检查两个表达式中的任何一个是否匹配,哪一个匹配更早(如果它们在同一位置匹配,哪个匹配更长)?这就是我现在正在做的事情.不幸的是,我经常在长字符串上执行此操作,对于两种以上的模式.结果很慢(是的,这肯定是瓶颈).
我应该更具体 - 抱歉.$a并且$b是变量,它们的内容超出了我的控制范围!否则,我会手动合并它们.因此,我不能对使用的分隔符或正则表达式修饰符做任何假设.请注意,例如,我的第一个表达式使用i修饰符(忽略大小写),而第二个表达式使用x(扩展语法).因此,我不能只将两者连接起来,因为第二表达并不能忽视壳体和第一不使用扩展语法(和任何空白在其中是显著!
我有这段代码:
import inspect
import ast
def func(foo):
return foo.bar - foo.baz
s = inspect.getsource(func)
xx = ast.parse(s)
class VisitCalls(ast.NodeVisitor):
def visit_Name(self, what):
if what.id == 'foo':
print ast.dump(what.ctx)
VisitCalls().visit(xx)
Run Code Online (Sandbox Code Playgroud)
从函数'func'我想提取:
['foo.bar', 'foo.baz']
Run Code Online (Sandbox Code Playgroud)
或类似的东西:
(('foo', 'bar'), ('foo', 'baz))
Run Code Online (Sandbox Code Playgroud)
编辑
我想将一个普通的python函数的代码转换为电子表格公式.
所以我需要转换:
foo.bar - foo.baz
Run Code Online (Sandbox Code Playgroud)
至:
=A1-B1
Run Code Online (Sandbox Code Playgroud)
示例电子表格http://img441.imageshack.us/img441/1451/84516405.png
**再次编辑*
以下程序输出:
('A1', 5)
('B1', 3)
('C1', '= A1 - B1')
Run Code Online (Sandbox Code Playgroud)
代码:
import ast, inspect
import codegen # by Armin Ronacher
from collections import OrderedDict
class SpreadSheetFormulaTransformer(ast.NodeTransformer):
def __init__(self, sym):
self.sym = …Run Code Online (Sandbox Code Playgroud) 假设我已经在解释器中导入了一个python模块.如何在解释器中获取导入模块的抽象语法树(及其中的任何函数和类)?我不想重新解析源文件.谢谢!
编译器解析源代码并构建抽象语法树.用于构造抽象语法树的函数返回构成合成属性的指针.它们是什么以及它们与继承属性有何不同.
编辑:我不知道这是否有帮助,但我最初在法国语境中听说过这些术语:Attributssynthétisés,attributshérités.
我一直在python中试验AST.我想通过在运行时转换AST来修改方法.
我可以使用预编译方法的源代码inspect.getsource(),并且可以根据需要使用AST访问者修改AST.
这可能很天真,但我希望能够编译AST并做类似的事情:
myClass.method.__func__.__code__ = compile(newAST, '<string>', 'exec')
Run Code Online (Sandbox Code Playgroud)
但是compile只接受以ast.Module为根的AST.有没有办法只编译ast.FunctionDef,或从编译(和其他空)模块代码中检索功能代码对象?
任何指向信息的指针都会受到赞赏.我见过的AST例子只处理简单的表达式.
我意识到我只需要在命名空间中执行模块,然后我就可以访问正常的结构了.所以模式是:
src = inspect.getsource(myClass.myMethod)
astFromSrc = ast.parse(unindent(src)) # need to remove extra indent from method
transform(astFromSrc.body) # transform the AST as you need
ast.fix_missing_locations(astFromSrc) # fix up line numbers etc
compiled = compile(astFromSrc, '<string>', 'exec') # compile the module AST
####### From here is the part I was missing
myScope = {} # make an empty namespace
exec compiled in myScope # now myScope contains a proper compiled …Run Code Online (Sandbox Code Playgroud) 我目前正在寻找一个Java 6/7解析器,它生成一些(可能是标准化的)表单抽象语法树.
我已经发现ANTLR有一个Java 6语法,但似乎它只生成解析树,而不是语法树.我还读过有关Java编译器API的文章 - 但是所有提到的资源都是过度设计并且记录不完整(如果它确实生成了AST,我还没发现).
你知道任何好的解析器库,可能作为标准化输出吗?
谢谢
我想获取传递给函数的参数.例如,如果我有电话
printf("%d%d",i,j);
输出应该是
%d%d
i
j
我可以使用RecursiveASTVisitor中的VisitCallExpr()进行函数调用.还能够获取参数的数量和参数类型.但我不知道如何得到论点.
bool MyRecursiveASTVisitor::VisitCallExpr (clang::CallExpr *E)
{
for(int i=0, j=E->getNumArgs(); i<j; i++)
{
llvm::errs() << "argType: " << E->getArg(i)->getType().getAsString() << "\n";
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
输出:
argType:char*
argType:int
argType:int
请帮助我得到论点.
在scala 2.10 AST中递归搜索元素的最佳方法是什么?
树可能是power.trees(code)或mirror.mkToolBox().parseExpr(code)
编辑的结果.在2.10.0-RC1 parseExpr中已重命名为parse.
我具体的用例是通过方法名称从给定的类/对象代码中提取方法的代码,但我认为如果以更通用的方式表达,问题将更加相关.
我正在为一个JavaScript AST实现一个漂亮的打印机,我想问一下是否有人知道一个"正确的"算法,根据运算符优先级和关联性自动用最小括号括起表达式.我没有在谷歌上找到任何有用的材料.
显而易见的是,父级具有更高优先级的运算符应该用括号括起来,例如:
(x + y) * z // x + y has lower precedence
Run Code Online (Sandbox Code Playgroud)
但是,也有一些运算符不是关联的,在这种情况下仍需要括号,例如:
x - (y - z) // both operators have the same precedence
Run Code Online (Sandbox Code Playgroud)
我想知道后一种情况的最佳规则是什么.对于除法和减法,是否足以说明,如果rhs子表达式的优先级小于或等于,则应将其括起来.
javascript compiler-construction pretty-print abstract-syntax-tree parentheses
我正在尝试将AST与ANTLR4一起使用,包含以下文件:
Builder.java
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.TokenStream;
public class Builder
{
public static void main(String[] args)
{
CharStream input = new ANTLRInputStream("ON M1==2 && M3 == 5 && (M2 > 1 || M5 <= 5.0) "
+ "DO P5:42 P4:10");
ExprLexer lexer = new ExprLexer(input);
TokenStream tokens = new CommonTokenStream(lexer);
ExprParser parser = new ExprParser(tokens);
parser.addParseListener(new ExprTestListener());
ExprParser.ExpressionContext uu = parser.expression();
}
}
Run Code Online (Sandbox Code Playgroud)
ExprTestListener:
import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.antlr.v4.runtime.tree.ErrorNode;
public class ExprTestListener extends ExprBaseListener …Run Code Online (Sandbox Code Playgroud) python ×3
java ×2
parsing ×2
antlr ×1
antlr4 ×1
c++ ×1
clang ×1
codegen ×1
grammar ×1
javascript ×1
llvm ×1
methods ×1
parentheses ×1
parse-tree ×1
php ×1
pretty-print ×1
regex ×1
scala ×1
scala-2.10 ×1
visitor ×1