我正在将基于C#的编程语言编译器从手动词法分析器/解析器迁移到Antlr.
Antlr一直给我带来严重的头痛,因为它通常大部分都有效,但是有些小部件没有,而且难以解决.
我发现我的大部分头痛都是由Antlr的词法分析器部分引起的,而不是解析器引起的.然后我注意到parser grammar X;并意识到也许我可以手动编写lexer,然后是Antlr生成的解析器.
所以我正在寻找关于这个主题的更多文档.我想自定义ITokenStream可以工作,但似乎几乎没有关于这个主题的在线文档...
我在expr.ml文件中有一个类型expr.在parser.mly(OCamlyacc文件)中,我定义了expr规则并给出了类型:
%start expr
%type <expr> expr
Run Code Online (Sandbox Code Playgroud)
但是,我得到:
File "parser.mli", line 34, characters 48-52:
Error: Unbound type constructor expr
Run Code Online (Sandbox Code Playgroud)
我尝试添加
%{
open Expr
%}
Run Code Online (Sandbox Code Playgroud)
在.mly文件的开头,但它仍然无法正常工作.如何在外部文件中定义此expr类型并将其用作规则的返回值?谢谢.
我正在使用ParseKit作为Objective-C,它采用类似BNF的语法来指定语法:
@start = command+;
command = new;
new = 'new' object ';';
object = 'house' | other;
Run Code Online (Sandbox Code Playgroud)
包含最后一行会导致错误.基本上我想说一个物体可以是房子或其他东西.非终端元素"其他"应该捕获那些不是房子的字.
我是否以错误的方式讨论"任何地方"的想法?
谢谢!
我有一些使用ANTLR编写解析器的经验,我正在尝试(自我教育:))将其中一个移植到PEG(Parsing Expression Grammar).
当我想要了解这个想法时,有一件事让我觉得麻烦,我觉得我已经错过了一些:如何处理空白.
在ANTLR中,处理空格和注释的常规方法是将标记放在隐藏的通道中,但是使用PEG语法时,没有标记化步骤.考虑到诸如C或Java之类的语言,几乎在任何地方都允许使用注释,人们希望立即"隐藏"注释,但由于注释可能具有语义含义(例如,在生成代码文档,类图等时),不会只是想丢弃它们.
那么,有没有办法解决这个问题?
我正在清理我的一个旧项目,它计算了一些关于大型软件项目的简单指标.其中一个指标是文件/类/方法的长度.目前我的代码"猜测"类/方法边界基于一个非常粗略的算法(遍历文件,保持"当前深度"并在遇到不带引号的括号时调整它;当你返回到关卡时,类或方法开始于,考虑退出).但是,这个过程存在许多问题,并且检测深度变化的"简单"方法并不总是有效.
为了使这个结果准确,我需要使用检测函数定义,类定义和深度变化的规范方法(在每种语言中).这相当于编写一个简单的解析器来生成解析树,该解析树至少包含我希望项目适用的每种语言的这些元素.
显然之前已经为所有这些语言编写了解析器,所以看起来我不应该重复这种努力(即使编写解析器很有趣). 是否有一些开源项目为一堆源语言收集即用型解析器库?或者我应该只是使用ANTLR从头开始创建自己的? (注意:我很高兴将项目移植到另一种语言来使用一个很好的现有资源,所以如果你知道一个,那么写入它的语言并不重要.)
我正在寻找一个用PHP编写的语言解析器.
目标是阅读自定义语言,而不是阅读PHP代码.
基本上,我想指定语言语法,给出代码片段并返回表示它的结构.然后我可以遍历该结构来执行代码片段.我相信结构将是一个AST,但我不知道这是否是唯一的选择(我与解析器及其词汇不相关).
我看了一下Doctrine DQL解析器,但它看起来不像通用语言解析器.
在使用Alex lexer生成器或Happy解析器生成器创建一个Lexer.x或一个Parser.y解析器时,将它们编译成Haskell文件,并将它们编译成目标文件,默认情况下会产生以下"警告":
$ ghc Lexer
line-map.c: file "<command-line>" left but not entered
line-map.c: file "<command-line>" left but not entered
[1 of 1] Compiling Lexer ( Lexer.hs, Lexer.o )
$ happy Parser.y
$ ghc Parser
line-map.c: file "<command-line>" left but not entered
line-map.c: file "<command-line>" left but not entered
[2 of 2] Compiling Parser ( Parser.hs, Parser.o )
Run Code Online (Sandbox Code Playgroud)
这些行是由于生成的.hs文件中嵌入了以下行而产生的:
{-# LINE 1 "<command-line>" #-}
Run Code Online (Sandbox Code Playgroud)
为什么包含这些行,并且有一种方法可以抑制这些消息,以防命令行显然没有用于生成的词法分析器和解析器中的任何内容?
我需要编写一个编译器.这是大学的家庭作业.老师告诉我们,我们可以使用任何我们想要解析代码的API,只要它是一个好的.这样我们就可以更专注于我们将生成的JVM.
所以,是的,我将用Java编写一个编译器来生成Java.
你知道这个有什么好的API吗?我应该使用正则表达式吗?我通常手工编写自己的解析器,但在这种情况下不可取.
任何帮助,将不胜感激.
当使用带有空右侧的规则编写("理论")语法时,总是使用诸如ε(或1)之类的符号来使这个空白显式:
A ? ? | a A
Run Code Online (Sandbox Code Playgroud)
Yacc和其他人的这种语法看起来就像
a: | 'a' a
Run Code Online (Sandbox Code Playgroud)
或"更糟"
a: { $$ = new_list(); }
| a 'a' { $$ = $1; $$->append($1); }
;
Run Code Online (Sandbox Code Playgroud)
事实上,在"真实世界语法"(Yacc,Bison等)规则的这个空的右侧部分没有明确标记为空的麻烦我:很容易错过rhs空的事实,或者更糟糕的是:忘记插入|并实际使用中规则操作:
a: { $$ = new_list(); }
a 'a' { $$ = $1; $$->append($1); }
;
Run Code Online (Sandbox Code Playgroud)
1)我不知道有任何工具可以提供显式空rhs的方法.有吗?
Bison的未来版本可能支持专用符号,在非空rhs中使用时会出现错误,而在留下隐式空rhs时会出现警告.
2)人们认为这有用吗?
3)你建议的符号是什么?
目前,候选人是$empty:
a: $empty { $$ = new_list(); }
| a 'a' { $$ = $1; $$->append($1); }
;
Run Code Online (Sandbox Code Playgroud)
选择的语法是%empty:
a: %empty { $$ = …Run Code Online (Sandbox Code Playgroud) 在词法分析器中,可以跳过令牌,使它们脱离解析器,如下所示:
Whitespace : [ \t\r\n]+ -> skip ;
Run Code Online (Sandbox Code Playgroud)
-> skip解析器是否有相同的功能?也就是说,一旦匹配解析器规则,是否有办法将其保留在解析树之外?假设,它可能看起来像这样:
document : prolog? -> skip
misc* element misc*
;
Run Code Online (Sandbox Code Playgroud)
(例子取自最终的ANTLR书,第225页.)