显然,C#和C++一样容易受到'>>'lexer困境的影响.
这个C#代码非常有效,它编译并运行得很好:
var List = new Dummy("List");
var Nullable = new Dummy("Nullable");
var Guid = new Dummy("Guid");
var x = List<Nullable<Guid>> 10;
var y = List<Nullable<Guid>> .Equals(10,20);
Run Code Online (Sandbox Code Playgroud)
您必须为上面的Dummy类重载'<'和'>>'运算符.
但编译器设法猜测在'x'情况下,意思是使用List,Nullable和Guid局部变量.在'y'的情况下,它突然决定将它们视为众所周知的类型的名称.
以下是另一个例子的更详细描述:http: //mihailik.blogspot.co.uk/2012/05/nested-generics-c-can-be-stinky.html
问题是:C#编译器如何将'a <b <c >>'解析为算术表达式或泛型类型/方法?
当然,它不会尝试在程序文本上多次"运行",直到它成功,或者它是否成功?这需要无限前瞻,而且非常复杂.
它是一个简单的标识符(比如cow)括在括号内的(...)东西()看起来像方法调用(...(...))或看起来像成员访问(thing.member)的东西:
def expr = identifier |
"(" ~> expr <~ ")" |
expr ~ ("(" ~> expr <~ ")") |
expr ~ "." ~ identifier
Run Code Online (Sandbox Code Playgroud)
它是用Scala Parser Combinator语法给出的,但它应该非常简单易懂.它类似于表达式最终在许多编程语言中查找(因此得名expr)然而,就目前而言,它是左递归的并且导致我的好的PEG解析器爆炸.
我还没有成功地分解左递归,同时仍然保持正确的情况,如(cow.head).moo(dog.run(fast)).我怎样才能重构这个,或者我是否需要转向一些可以容忍左递归语法的解析器生成器?
如何定义解析器和词法分析器规则来解析使用缩进来定义范围的语言.
我已经google了一下,通过在词法分析器中生成INDENT和DEDENT令牌,找到了一种解析它的聪明方法.
如果我谈到一些有趣的东西,我会更深入地研究这个问题并发表答案,但我希望看到解决问题的其他方法.
编辑:正如查理指出的,如果不是相同的话,已经有另一个非常相似的线程.我的帖子应该被删除吗?
我一直在研究简单模板语言的解析器.我正在使用Ragel.
要求是适度的.我正在尝试找到可以嵌入输入字符串中任何位置的[[tags]].
我正在尝试解析一个简单的模板语言,可以在HTML中嵌入{{foo}}等标记.我尝试了几种方法来解析这个问题,但不得不求助于使用Ragel扫描程序并使用低效的方法,只将单个字符匹配为"全部捕获".我觉得这是错误的做法.我基本上滥用扫描仪的最长匹配偏差来实现我的默认规则(它只能是1个字符长,所以它应该永远是最后的手段).
%%{
machine parser;
action start { tokstart = p; }
action on_tag { results << [:tag, data[tokstart..p]] }
action on_static { results << [:static, data[p..p]] }
tag = ('[[' lower+ ']]') >start @on_tag;
main := |*
tag;
any => on_static;
*|;
}%%
Run Code Online (Sandbox Code Playgroud)
(用红宝石写的动作,但应该很容易理解).
How would you go about writing a parser for such a simple language? Is Ragel maybe not the right tool? It seems you have to fight Ragel tooth and nails if the syntax is …
我现在正在阅读编译器和解析器架构,我想知道一件事......当你有XML,XHTML,HTML或任何基于SGML的语言时,词法分析器的作用是什么以及令牌是什么?
我读过,令牌就像为词法分析器准备的单词一样.虽然我没有找到用于语言行C,C++,Pascal等的令牌的问题,其中有关键字,名称,文字和其他由空格分隔的类似字符串的字符串,但是我有一个问题,因为它没有'任何话!它只是与标记(标签)交错的纯文本.
我心里想,可能是这些标签和纯文本片段都是令牌,类似的东西:[TXT][TAG][TAG][TXT][TAG][TXT][TAG][TAG][TXT]....这将是比较合理的,因为SGML并不关心有什么标记分隔符中<和>(当然,它识别特殊处理的说明和定义时,它创立?或!为下一个字符,评论属于该组太),和SGML标记生成器能是XML/HTML/XHTML解析器的基础.
但后来我意识到<标记内部可能会有一些字符作为其他语法的一部分:属性值: - /即使将<字符放在属性值中也不是很好(最好用<它),许多浏览器和编辑处理这些并将它们<视为属性值的一部分,而不是标记分隔符.
它使事情变得复杂,因为我没有看到通过词法分析器中的简单确定性有限自动机(DFA)识别标记的方法.看起来它需要一个单独的自动机上下文,当它在标签内时,另一个上下文遇到一个属性值时.这需要一堆状态/上下文我认为,所以DFA可能无法处理.我对吗?
你有什么看法?从标签(标记)和纯文本制作令牌是否合适?
在这里:http://www.antlr.org/wiki/display/ANTLR3/Parsing+XML
使用某种不同的技术:他们对待<和>(和</和/>)作为分隔标记,标签内,他们使用GENERIC_ID的令牌等他们通常将大部分工作转移到解析器上.但是他们还必须改变标记化器的上下文:它们在纯文本中使用不同的上下文,并且在标记中使用不同(但是他们忘记了属性值上下文我认为,因为第一次出现>将在标签中结束标记).
那么解析类似SGML的语言的最佳方法是什么?那个词法分析器真的用在那里吗?如果是,那么代币是什么字符串?
我正在将基于C#的编程语言编译器从手动词法分析器/解析器迁移到Antlr.
Antlr一直给我带来严重的头痛,因为它通常大部分都有效,但是有些小部件没有,而且难以解决.
我发现我的大部分头痛都是由Antlr的词法分析器部分引起的,而不是解析器引起的.然后我注意到parser grammar X;并意识到也许我可以手动编写lexer,然后是Antlr生成的解析器.
所以我正在寻找关于这个主题的更多文档.我想自定义ITokenStream可以工作,但似乎几乎没有关于这个主题的在线文档...
我正在为CoffeeScript编写一个Eclipse/Xtext插件,我意识到我可能需要手工编写一个lexer.CoffeeScript解析器还使用手写的词法分析器来处理语法中的缩进和其他技巧.
Xtext生成一个扩展的类,org.eclipse.xtext.parser.antlr.Lexer然后扩展org.antlr.runtime.Lexer.所以我想我会扩展它.我可以看到两种方法
mTokens().这是由生成的代码完成的,改变了内部状态.nextToken()这似乎是一种自然的方法,但随后我将不得不跟踪内部状态.我找不到任何例子如何在没有语法文件的情况下为ANTLR写一个简单的词法分析器.所以最简单的答案就是指向一个指针.
对Xtext的回答:具有重要/语义空白的语言的语法指的是通过改变底层输入流中的标记来处理缩进问题的todotext.我不想这样做,因为很难处理coffeescript语法的其他技巧.
更新:
在此期间我意识到我的问题部分是特定于Xtext的.
如何匹配ANTLRv4中的任何文本?我的意思是文字,这在语法写作时是未知的?
我的语法如下:
grammar Anytext;
line :
comment;
comment : '#' anytext;
anytext: ANY*;
WS : [ \t\r\n]+;
ANY : .;
Run Code Online (Sandbox Code Playgroud)
我的代码如下:
String line = "# This_is_a_comment";
ANTLRInputStream input = new ANTLRInputStream(line);
AnytextLexer lexer = new AnytextLexer(input);
CommonTokenStream tokens = new CommonTokenStream(lexer);
AnytextParser parser = new AnytextParser(tokens);
ParseTree tree = parser.comment();
System.out.println(tree.toStringTree(parser)); // print LISP-style tree
Run Code Online (Sandbox Code Playgroud)
输出如下:
line 1:1 extraneous input ' ' expecting {<EOF>, ANY}
(comment # (anytext T h i s _ i s _ a _ c o …Run Code Online (Sandbox Code Playgroud) 我需要从给定的C#文件中提取所有字符串文字.#if DEBUG假设所有条件编译常量(例如)都为假,并且可以假定该文件在语法上是正确的.应支持单行("a\u1000b")和逐字(@"x""\y")文字.
首先,我尝试使用正则表达式,但后来意识到我需要在#if指令中正确处理单行和多行注释和逻辑表达式.
所以,在我开始编写自己的C#lexer之前,我想问你现有的解决方案.