使用F#解析AST来构建解释器的最佳方法是什么?有很多F#例子用于简单的语法(基本的算术运算),但我似乎找不到任何具有更大范围功能的语言.
受歧视的工会看起来非常有用,但您如何构建具有大量选项的工会呢?是否更好地在其他地方定义类型(例如加法,减法,条件,控制流)并将它们作为联合中的预定义类型组合在一起?
或者我错过了一些更有效的口译员写作方式?对每种类型的eval函数更有效,或者使用monad?
提前致谢
以下是使用ast和symtable 包的Python代码段.我试图解析代码并检查类型.但我不明白如何遍历对象以获取被引用的实际变量.
下面的代码实现了一个NodeVisitor,并且一个函数被呈现给编译器并由编译器和ast走了.正在分析的函数(eval_types)传递了几个对象.
下面是构成示例的代码块.我为每个块添加了一些注释.要运行代码,需要重新组装"块".
导入和用于解压缩代码块的函数.
import inspect
import ast
import symtable
from tokenize import generate_tokens, untokenize, INDENT
from cStringIO import StringIO
# _dedent borrowed from the myhdl package (www.myhdl.org)
def _dedent(s):
"""Dedent python code string."""
result = [t[:2] for t in generate_tokens(StringIO(s).readline)]
# set initial indent to 0 if any
if result[0][0] == INDENT:
result[0] = (INDENT, '')
return untokenize(result)
Run Code Online (Sandbox Code Playgroud)
以下是节点访问者,它具有通用的未处理和名称访问者重载.
class NodeVisitor(ast.NodeVisitor):
def __init__(self, SymbolTable):
self.symtable = SymbolTable
for child in SymbolTable.get_children():
self.symtable = …Run Code Online (Sandbox Code Playgroud) 我正在使用scala编写玩具编译器.目标语言本身看起来像scala,但它是一个开放的实验领域.
在几次大型重构之后,我找不到一种模拟抽象语法树的好方法.我想使用scala模式匹配的设施,问题是树在编译过程中携带移动信息(如类型,符号).
我可以看到几个解决方案,我都不喜欢它们:
具有可变字段的case类(我相信scala编译器会这样做):问题是这些字段不存在于编译的每个阶段,因此必须被置为空(或者选项)并且调试/它变得非常繁重写代码.此外,如果例如,我在键入阶段后找到一个空类型的节点我很难找到错误的原因.
巨大的特质/案例类层次结构:像Node,NodeWithSymbol,NodeWithType,......似乎很难写和使用
完全用提取器手工制作的东西
我也不确定使用完全不可变的AST是否是一个好习惯,特别是在scala中没有隐式共享(因为编译器不知道不变性)并且它可能会损害性能以便始终复制树.
你能想到使用scala强大的类型系统来模拟我的树的优雅模式吗?
摘要问题描述:
我看到它的方式,unparsing意味着从AST创建一个令牌流,当再次解析时产生一个相等的AST.
所以 parse(unparse(AST)) = AST持有.
这等于找到一个有效的解析树,它将生成相同的AST.
因此,解析者必须通过所有语法约束所包含的遍历节点找到有效的"路径".这基本上意味着找到AST节点到语法生成规则的有效分配.这通常是一个约束满足问题(CSP),可以通过回溯 O(exp(n))来解决,如解析.
幸运的是,对于解析,这可以使用GLR(或更好地限制语法)在O(n³)中完成.因为AST结构非常接近语法生成规则结构,所以我真的很惊讶看到运行时比解析更糟糕的实现:XText使用ANTLR进行解析和回溯以进行解析.
问题
例1:
Area returns AnyObject -> Pedestrian | Highway
Highway returns AnyObject -> "Foo" Car
Pedestrian returns AnyObject -> "Bar" Bike
Car returns Vehicle -> anyObjectInstance.name="Car"
Bike returns Vehicle -> anyObjectInstance.name="Bike"
Run Code Online (Sandbox Code Playgroud)
所以,如果我有一个AST包含
AnyObject -> AnyObject -> Vehicle [name="Car"] 我知道root可以是Area,我可以解决它
Area -> Highway -> Car
Run Code Online (Sandbox Code Playgroud)
因此(公路|行人)决定取决于子树决策.当一片叶子乍一看是几种类型中的一种时,问题会变得更糟,但必须是特定的一种,以便稍后形成有效路径. …
parsing antlr abstract-syntax-tree xtext constraint-satisfaction
具体来说,我们有一个像这样的C++源文件:
template <int n>
struct N {};
struct B {
template <typename M>
using A = typename std::conditional<std::is_same<M, N<4>>::value,
int*, void*>::type;
};
template <typename T, T value>
struct F : B {};
template <>
struct F<decltype(&fopen), &fopen> : B {
template <typename M>
using A = double*;
};
template <>
struct F<decltype(&fclose), &fclose> : B {
template <typename M>
using A = typename std::conditional<std::is_same<M, N<16>>::value,
void*, char**>::type;
};
// More specialization of 'F' follows.
Run Code Online (Sandbox Code Playgroud)
这是很容易找到ClassTemplateDecl第N和F …
我正在用clang进行程序间数据流分析.目前我正在使用libtooling来解析源文件并调用AST访问者.问题是如何为几个.c文件创建单个AST?
我曾尝试使用ASTImport类,但它不支持导入某些AST节点.而且,当我创建和操作CompilerIstance并且它在析构函数中崩溃时,我做错了什么.
一个非常相似的选项是ASTImportAction,但在这种情况下我不太清楚哪些命令行参数应传递给ClangTool.
第三种选择是为每个.c文件创建ASTUnits并在每个文件中查找定义,不清楚如何找到用户定义类型之间的对应关系,例如记录.在ASTImport中,它们使用IsStructurallyEquivalent()函数,但它在匿名命名空间中声明,因此我只能将所有这些代码复制到我的程序中.并且它再次支持不是所有AST节点.
从互联网上链接http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-August/023865.html似乎是最合适的,但对我来说,解决方案的技术细节并不清楚.
欢迎任何建议.非常感谢.
我试图根据我在网上阅读的一些有用的文献,使用Free monad构建AST.
我有一些关于在实践中使用这些AST的问题,我已经归结为以下示例.
假设我的语言允许以下命令:
{-# LANGUAGE DeriveFunctor #-}
data Command next
= DisplayChar Char next
| DisplayString String next
| Repeat Int (Free Command ()) next
| Done
deriving (Eq, Show, Functor)
Run Code Online (Sandbox Code Playgroud)
我手动定义了Free monad样板:
displayChar :: Char -> Free Command ()
displayChar ch = liftF (DisplayChar ch ())
displayString :: String -> Free Command ()
displayString str = liftF (DisplayString str ())
repeat :: Int -> Free Command () -> Free Command ()
repeat times block = liftF (Repeat times …Run Code Online (Sandbox Code Playgroud) 如何使用PEG.js为左关联运算符构建AST(抽象语法树)?
我试图根据我在互联网上找到的信息编写一些代码,但我似乎犯了一个错误.
我编写的代码为大多数表达式生成了不正确的AST.
12-6-4-2*1-1
Run Code Online (Sandbox Code Playgroud)
{
"left": {
"left": {
"left": {
"left": 12,
"operator": "-",
"right": 6
},
"operator": "-",
"right": 4
},
"operator": "-",
"right": {
"left": 2,
"operator": "*",
"right": 1
}
},
"operator": "-",
"right": 1
}
Run Code Online (Sandbox Code Playgroud)
{
"left": {
"left": {
"left": 12,
"operator": "-",
"right": 6
},
"operator": "-",
"right": 4
},
"operator": "-",
"right": {
"left": 2,
"operator": "*",
"right": {
"left": 1,
"operator": "-", …Run Code Online (Sandbox Code Playgroud) 我正在使用Parsec编写Delphi代码解析器,我目前的AST数据结构如下所示:
module Text.DelphiParser.Ast where
data TypeName = TypeName String [String] deriving (Show)
type UnitName = String
data ArgumentKind = Const | Var | Out | Normal deriving (Show)
data Argument = Argument ArgumentKind String TypeName deriving (Show)
data MethodFlag = Overload | Override | Reintroduce | Static | StdCall deriving (Show)
data ClassMember =
ConstField String TypeName
| VarField String TypeName
| Property String TypeName String (Maybe String)
| ConstructorMethod String [Argument] [MethodFlag]
| DestructorMethod String [Argument] [MethodFlag]
| ProcMethod …Run Code Online (Sandbox Code Playgroud) 使用clang-check转储源代码的AST,可以用下面的命令来完成:
$ clang-check -ast-dump file.c --
Run Code Online (Sandbox Code Playgroud)
但是,此命令的输出将在终端内显示为彩色.
当我将输出定向到文件时,我会遇到所有颜色转义码:
$ clang-check -ast-dump file.c -- > out.txt
Run Code Online (Sandbox Code Playgroud)
例:
[0;1;32mTranslationUnitDecl[0m[0;33m 0x227c5c0[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x227cac0[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __int128_t[0m [0;32m'__int128'[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x227cb20[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __uint128_t[0m [0;32m'unsigned __int128'[0m
[0;34m|-[0m[0;1;32mTypedefDecl[0m[0;33m 0x227ce70[0m <[0;33m<invalid sloc>[0m> [0;33m<invalid sloc>[0m implicit[0;1;36m __builtin_va_list[0m [0;32m'__va_list_tag [1]'[0m
...
Run Code Online (Sandbox Code Playgroud)
在clang-check中是否有禁用颜色的标志?
我尝试添加以下标志,但它不起作用:
--extra-arg="--no-color-diagnostics"
Run Code Online (Sandbox Code Playgroud)