首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用cup和jflex运行解析时出错

使用cup和jflex运行解析时出错
EN

Stack Overflow用户
提问于 2022-01-07 21:00:45
回答 1查看 1K关注 0票数 0

我是JFlex和CUP的新手。我试着做一个简单的例子,但是当我运行解析器时,它总是给出相同的错误,在语句的识别方面没有进展。我认为问题一定出在产品或规则上。我将Java中经常使用的符号定义为终端,例如:

代码语言:javascript
运行
复制
terminal LPAREN, RPAREN, RBRACE, LBRACE, LBRCKT, RBRCKT, COLON, SEMICOLON, ASSIGN, COMMA, DOT;
terminal PAGE, LABEL;

非终端机的定义如下:

代码语言:javascript
运行
复制
nonterminal START_PAGE;
nonterminal page_body, page_body_declarations_opt, page_body_declarations, page_body_declaration;

这样的语法:

代码语言:javascript
运行
复制
start with START_PAGE;
START_PAGE ::= PAGE page_body ;

page_body ::= LBRACE page_body_declarations_opt RBRACE ;
page_body_declarations_opt ::= | page_body_declarations ;
page_body_declaration ;
page_body_declarations ::= page_body_declarations page_body_declaration ;
page_body_declaration ::= label_declaration ;
label_declaration ::= LABEL LPAREN RPAREN SEMICOLON ;

输入数据或文件包含第2行中的下列内容:

代码语言:javascript
运行
复制
Page {
}

当我运行解析器时,我会打印lexer的结果,然后运行解析器,得到以下结果:

代码语言:javascript
运行
复制
Token: # 2 Page
Token: # 51 {
Token: # 52}
Token: # 0
Compiler has detected a syntax error at line 2 column 8
Error in line 2, column 8: Couldn't repair and continue parse

该误差出现在LBRACE中。

我用于测试的版本是:

代码语言:javascript
运行
复制
<jflex.version>1.8.2</jflex.version>
<cup.version>11b-20160615</cup.version>

总的想法是:

定义页面块,并在内部定义其他元素,如标签。

如果你能帮我做这个例子,我将不胜感激。

对于规则或产品的定义以及如何减少杯的数量,现有的信息是非常缺乏的。我所研究的所有例子都是算术表达式,但我没有发现更多有助于解决这个问题的例子。

这是我的雷克萨斯文件

代码语言:javascript
运行
复制
// USER CODE

package core;

import java.io.Reader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java_cup.runtime.Symbol;
import java_cup.runtime.Scanner;
import java.nio.charset.StandardCharsets;
import java_cup.runtime.ComplexSymbolFactory;
import java_cup.runtime.ComplexSymbolFactory.Location;
import java_cup.runtime.ComplexSymbolFactory.ComplexSymbol;


/**
 * Lexer class.
 */

%% /*----------------------------------------------------------*/

%public
// Lexer class to generate
%class Lexer
%cupsym MSymbol
%function next_token
%implements MSymbol, Scanner
%type java_cup.runtime.Symbol

%unicode

%cupdebug

%char
%full

%line
%column

%eofval{
    
    return mSymbol(MSymbol.EOF);

%eofval}


/*--------------------------------------------------------------
    CODE COPIED INTO LEXER
  --------------------------------------------------------------*/
%{ 

    ComplexSymbolFactory symbolFactory;
    
    StringBuffer string = new StringBuffer();

    public Lexer(Reader in, ComplexSymbolFactory sf){
        this(in);
        symbolFactory = sf;
    }
    
    private Symbol mSymbol(int type) {
        return new Symbol(type, yyline, yycolumn);
    }
    
    private Symbol mSymbol(int type, Object value) {
        return new Symbol(type, yyline, yycolumn, value);
    }
    private void error(String message) {
        System.out.println("Error at line "+(yyline+1)+", column "+(yycolumn+1)+" : " + message);
    }

%}

/*--------------------------------------------------------------
    MACRO DECLARATIONS
  --------------------------------------------------------------*/
LineTerminator = \r|\n|\r\n
InputCharacter = [^\r\n]
//WhiteSpace     = {LineTerminator} | [\ ,\t,\f]
WhiteSpace     = [\ ,\t,\f,\t] | {LineTerminator}

/* comments */
Comment = {TraditionalComment} | {EndOfLineComment} | {DocumentationComment}

TraditionalComment   = "/*" [^*] ~"*/" | "/*" "*"+ "/"
// Comment can be the last line of the file, without line terminator.
EndOfLineComment     = "//" {InputCharacter}* {LineTerminator}?
DocumentationComment = "/**" {CommentContent} "*"+ "/"
CommentContent       = ( [^*] | \*+ [^/*] )*


%state STRING

%% /*----------------------------------------------------------*/

/* Keywords */

<YYINITIAL> {

/*-------------------------------------------------------------
    KEYWORDS
  -------------------------------------------------------------*/
    "Page"      { 
                    return mSymbol(MSymbol.PAGE, yytext()); 
                }
    
}   //------> End of Keywords


<YYINITIAL> {
    /* separators */
    "("             { return mSymbol(MSymbol.LPAREN, yytext()); }
    ")"             { return mSymbol(MSymbol.RPAREN, yytext()); }
    "{"             { return mSymbol(MSymbol.RBRACE, yytext()); }
    "}"             { return mSymbol(MSymbol.LBRACE, yytext()); }
    "["             { return mSymbol(MSymbol.LBRCKT, yytext()); }
    "]"             { return mSymbol(MSymbol.RBRCKT, yytext()); }
    ";"             { return mSymbol(MSymbol.SEMICOLON, yytext()); }
    ","             { return mSymbol(MSymbol.COMMA, yytext()); }
    "."             { return mSymbol(MSymbol.DOT, yytext()); }
    "="             { return mSymbol(MSymbol.ASSIGN, yytext()); }
    ":"             { return mSymbol(MSymbol.COLON, yytext()); }

    \"              { yybegin(STRING); string.setLength(0); }
    

    /* WHITESPACE */
    {WhiteSpace}    { /* ignore */ }

    /* comments */
    {Comment}       { /* ignore */ }
}

<STRING> {
    \"              {   
                        yybegin(YYINITIAL);
                        return mSymbol(MSymbol.STRING_LITERAL, string.toString()); 
                    }
    
}

/* error fallback */
[^]                 { 
                        this.error("Illegal character [ " + yytext() + " ]");
                    }

当运行解析器时,lexer将检测令牌。我不知道太空会发生什么。

代码语言:javascript
运行
复制
Token: #2 Page
Token: #51 {
Token: #52 }
Token: #0 
Compiler has detected a syntax error at line 2 column 8
Error in line 2, column 8 : Couldn't repair and continue parse

文本无法修复,继续解析是由解析器杯设置的。

这是生成解析器时的结果。

代码语言:javascript
运行
复制
------- CUP v0.11b 20160615 (GIT 4ac7450) Parser Generation Summary -------
  0 errors and 54 warnings
  62 terminals, 7 non-terminals, and 8 productions declared, 
  producing 15 unique parse states.
  54 terminals declared but not used.
  0 non-terminals declared but not used.
  0 productions never reduced.
  0 conflicts detected (0 expected).
  Code written to "Parser.java", and "MSymbol.java".
---------------------------------------------------- (CUP v0.11b 20160615 (GIT 4ac7450))

运行解析器的代码

代码语言:javascript
运行
复制
    ComplexSymbolFactory csf = new ComplexSymbolFactory();
    Lexer lexer = new Lexer(new BufferedReader(new FileReader(args[0], StandardCharsets.UTF_8)), csf);
    ScannerBuffer lxrBuff = new ScannerBuffer(lexer);
    Parser mParser = new Parser(lxrBuff, csf);
    mParser.parse();

提前感谢

EN

回答 1

Stack Overflow用户

发布于 2022-01-10 16:17:32

在纠正了LBRACE和RBRACE令牌之后,我已经找到了问题的解决方案。在使用集成CUP的最新版本的JFlex时,它在CUP实现上使用了一个新的ComplexSymbolFactory,并且不得不使用这个方法来存储令牌。

代码语言:javascript
运行
复制
private Symbol mSymbol (String tokenName, int type, Object val) {
    Location left = new Location (yyline + 1, yycolumn + 1);
    Location right = new Location (yyline + 1, yycolumn + yylength ());

    return symbolFactory.newSymbol (tokenName, type, left, right, val);
}

谢谢

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70627129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档