纯粹作为一种自学习练习,我正在尝试使用该Parse::RecDescent模块在Perl中编写Java解析器.我稍后可能会使用Antlr,Bison等其他工具重新实现解析器.
但是,根据Java语言规范,我如何确保我的解析器确实生成了正确的解析?意义,正确处理悬空else,操作员关联和优先等.
一种方法是通过让两个解析器为大量测试Java程序生成AST,然后比较两组AST来将我的解析器与已知的无错解析器进行比较.
如果这确实是唯一的方法,我在哪里可以找到一整套测试Java程序,完全覆盖整个Java语言规范?
我查看了JavaParser,但它似乎没有详尽的测试数据集.
当然,另一种方法是自己手工编写成千上万的测试Java程序,这对我来说是非常不切实际的,不仅在时间方面,而且在确保其详尽无遗!
我一直在研究编译器.词法分析器似乎非常直接:取一个"句子"并将其分解为单词(或标记).为了确保正确的语法,需要一个解析器.解析器通常采用令牌并构建一个树,从而产生根节点(将单词分为句子,段落,页面等等).
从这个问题来看,似乎解析器会构建一个AST.AST只包含执行代码所需的内容,所以括号之类的内容是不必要的,因为运算符优先级内置在AST中.AST可能都是编译器需要的.
但是如何将代码从一种语言转换为另一种语言?采用一种伪造的语言(语法)或现有的语法并将其转换为另一种语言,其中运算符优先级规则可能会有所不同?运营商优先还是"内置"到CST吗?
举个例子,假设我编写了一种语言,并希望将其翻译成PHP代码.大多数语言的三元运算符具有从右到左的关联性.PHP错误地使用从左到右的关联性(请在此处查看更多相关信息).我希望"我的语言"从右到左使用,但生成的PHP代码必须应用括号才能在PHP中获得正确的结果(通过指向Wikipedia的链接,结果需要是"train"而不是"horse").
因此,对于语言翻译,CST会更好吗?运营商优先级通常是否构建在CST中?介于两者之间吗?有没有例子比较两个树和一个简单的代数方程?任何说明三元运算符的例子?
("转码"是"编程语言翻译"的正确术语吗?谷歌搜索会带来转换媒体.)
我想弄清楚的是:什么时候使用一个比另一个更合适?
compiler-construction abstract-syntax-tree concrete-syntax-tree
将解析树(即具体语法树)简化为抽象语法树的一般策略是什么?
例如,我有以下语法规则:
statement_list : statement
| statement_list statement
Run Code Online (Sandbox Code Playgroud)
如果保留为解析树,它将生成看起来像扇形输出
program
statement_list
statement_list
statement
definition
p_type
assignment
statement
definition
statement
assign
assignment
Run Code Online (Sandbox Code Playgroud)
如果我连接每个节点的子节点(因为语句列表在解析后没有固有含义),我可以实现以下内容
program
definition
p_type
assignment
definition
assign
assignment
Run Code Online (Sandbox Code Playgroud)
这很好用 - 但是,我没有意识到这样做的任何"规则".是否有特定的语法规则我应该简化?这是一种感觉问题,还是一个更机械化的过程?
compiler-construction grammar parsing abstract-syntax-tree concrete-syntax-tree
我正在尝试编写一种解释性编程语言,它将读入文件并输出类似字节码的格式,然后由虚拟机执行.
我最初的计划是:
IF myvalue = 5 THEN将成为IF myvalue 5,IF即将成为0x09),IF或0x09后跟两个字节).我被告知正则表达式是一种可怕的方式,但我不确定这是否是实现解释语言的好或坏方法.
这主要是为了体验,所以我不介意它是否不完全是性能友好的,但这将是一个好处.
实现我的解释器的最佳方法是什么,是否有任何例子(用简单的旧C编写)?
因此,由于我的任务,我最终想知道下一步可能是什么.
为了澄清事情,我应该使用Java实现DSL语言.该语言应该使"用户"能够指定并根据输入创建问卷表格.
以下输入应提供以下给定的输出:
form taxOfficeExample {
"Did you sell a house in 2010?"
hasSoldHouse: boolean
"Did you buy a house in 2010?"
hasBoughtHouse: boolean
"Did you enter a loan?"
hasMaintLoan: boolean
if (hasSoldHouse) {
"What was the selling price?"
sellingPrice: money
"Private debts for the sold house:"
privateDebt: money
"Value residue:"
valueResidue: money = (sellingPrice - privateDebt)
}
}
Run Code Online (Sandbox Code Playgroud)

我选择的解析器技术是ANTLRv4,它是这个平台的最佳选择.无论如何,我熟悉所有模型,术语等 - 例如解析,词汇,语法等 - 但还有一件事仍然缺乏 - Java和ANTLRv4之间的桥梁.
所以基本上我想根据你的经验知道,ANTLRv4和Java之间的桥梁是什么?例如,一旦我为DSL定义语法,该语法(语言)如何应用?这两个实体之间的桥梁是什么?
我问这个问题只是因为我在这方面很新,因此,任何提示,研究论文指针等都将受到赞赏!
谢谢
我正在阅读Rebol Wikipedia页面。
“解析表达式是用解析方言编写的,与do方言一样,它是数据交换方言的面向表达式的子语言。与do方言不同,解析方言使用表示运算符和最重要的非终结符的关键字”
你能解释一下什么是terminals和nonterminals?我已经阅读了很多有关语法的内容,但不了解它们的含义。这是另一个经常使用此词的链接。
parsing ×4
grammar ×3
java ×3
testing ×2
antlr ×1
bnf ×1
c ×1
dsl ×1
interpreter ×1
javaparser ×1
rebol ×1
red ×1
regex ×1
validation ×1
verification ×1