Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/347.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用EBNF表达式解析代码块_Java_Compiler Construction_Grammar_Ebnf_Cocor - Fatal编程技术网

Java 使用EBNF表达式解析代码块

Java 使用EBNF表达式解析代码块,java,compiler-construction,grammar,ebnf,cocor,Java,Compiler Construction,Grammar,Ebnf,Cocor,我正在使用CocoR生成一个类似java的扫描程序/解析器: 我在创建EBNF表达式以匹配代码块时遇到一些问题: 我假设一个代码块由两个众所周知的标记包围: 例如: public method(int a, int b) <& various code &> public方法(inta,intb) 如果我定义一个非终结符号 codeblock = "<&" {ANY} "&>" codeblock=“” 如果两个符号

我正在使用CocoR生成一个类似java的扫描程序/解析器:
我在创建EBNF表达式以匹配代码块时遇到一些问题:

我假设一个代码块由两个众所周知的标记包围: 例如:

public method(int a, int b) <&  
various code  
&>  
public方法(inta,intb)
如果我定义一个非终结符号

codeblock = "<&" {ANY} "&>"  
codeblock=“”
如果两个符号中的代码包含一个“”或“&”。

您可以扩展ANY术语以包括
,以及另一个非终结符(称之为\u块中的ANY_)

那你就用

ANY = "<&" | {ANY_WITHIN_BLOCK} | "&>"
codeblock = "<&" {ANY_WITHIN_BLOCK} "&>"
ANY=“”
codeblock=“”
如果你以后真的需要,{ANY}的意思是不变的

好吧,我对CocoR一无所知,给了你一个没用的答案,让我们再试一次

正如我在后面的评论中开始说的那样,我觉得真正的问题是你的语法可能太过松散,没有得到充分的说明

当我为我试图创建的一种语言编写CFG时,我最终使用了一种“中间相遇”的方法:我首先编写了顶级结构和直接的低级别标记组合,然后努力使它们在中间相遇(我猜大约在条件和控制流的级别)

你说过这种语言有点像Java,所以让我给你看一下我作为第一稿写的第一行,来描述它的语法(对不起,用伪代码,实际上它就像yacc/bison。在这里,我用括号代替Java):

/*高级资料*/
课程:班级
类:主类内部类
内部类:内部类内部类
|/*空*/
主类:类修饰符“类”标识符类块
内部类:“类”标识符类块
类块:“
类别decls:字段decls
|方法
方法:方法签名方法块
方法块:“
声明:声明声明
|/*空*/
类修饰语:“公共”
|“私人”
标识符:/*嗯,你知道*/
在你做这些的同时,找出你的即时标记组合,比如把“number”定义为float或int,然后创建加/减等规则


我不知道到目前为止您的方法是什么,但您肯定希望确保仔细指定所有内容,并在需要特定结构时使用新规则。创建一对一的规则不要显得可笑,但如果新规则能帮助你更好地组织你的思想,就不要害怕创建新规则。

尼克,来晚了

有多种方法可以做到这一点:

定义标记,以便lexer了解它们

您可以使用COMMENTS指令

来自
-引用CoCo期望的评论

或者在scanner.frame文件中创建hack NextToken()。执行以下操作(伪代码):

或者可以重写缓冲区中的Read()方法,并在最低级别执行eat


HTH

您如何定义_块中的任何_?ANY是CocoR中的“jolly”标记:它匹配每个标记。抱歉,我承认我不熟悉CocoR。我只是在写一个伪代码CFG语言。我假设您已经定义了{ANY},但如果这只是一个包罗万象的标记,那么这显然会使事情复杂化。:-)(编辑:Dang it.lol)我给你提供了更多细节:我可以用这种方式定义字符集:letter=“a..Z”+“%>”因此字母可以是任何大写字母或“”中的符号。然后我可以定义一个令牌,它必须根据字符集来定义。所以一个标记,比方说,单词应该被定义为:单词=字母{letter}啊,{WHATEVER}意味着零个或多个WHATEVER?
ANY = "<&" | {ANY_WITHIN_BLOCK} | "&>"
codeblock = "<&" {ANY_WITHIN_BLOCK} "&>"
/* High-level stuff */

program: classes

classes: main-class inner-classes

inner-classes: inner-classes inner-class
             | /* empty */

main-class: class-modifier "class" identifier class-block

inner-class: "class" identifier class-block

class-block: "<&" class-decls "&>"

class-decls: field-decl
           | method

method: method-signature method-block

method-block: "<&" statements "&>"

statements: statements statement
          | /* empty */

class-modifier: "public"
              | "private"

identifier: /* well, you know */
if (Peek() == CODE_START)
{
     while (NextToken() != CODE_END)
     {
        // eat tokens
     }
}