我是 JFlex 和 CUP 的新手。我试图做一个简单的例子,但是当我运行解析器时,它总是给出同样的错误,它不会随着语句的识别而进步。我认为问题一定出在产品或规则上。我已将 Java 中始终使用的符号定义为终端,例如:
terminal LPAREN, RPAREN, RBRACE, LBRACE, LBRCKT, RBRCKT, COLON, SEMICOLON, ASSIGN, COMMA, DOT;
terminal PAGE, LABEL;
我将非终结符定义如下:
nonterminal START_PAGE;
nonterminal page_body, page_body_declarations_opt, page_body_declarations, page_body_declaration;
像这样的语法:
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 行的以下内容:
Page {
}
当我运行解析器时,我打印词法分析器的结果,然后我运行解析器得到以下结果:
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 中。
我用于测试的版本是:
<jflex.version>1.8.2</jflex.version>
<cup.version>11b-20160615</cup.version>
总体思路是:
定义页面块并在内部定义其他元素,例如标签。
如果您能帮我执行这个示例,我将不胜感激。
对于规则或产生式的定义以及应如何减少 CUP,现有的信息非常稀缺。我研究过的所有例子都是算术表达式,但我没有发现更多有助于解决问题的例子。
这是我的词法分析器文件
// 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() + " ]");
}
运行解析器时,词法分析器会检测标记。我不知道空间会发生什么。
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
文本无法修复并继续解析由解析器杯设置。
这是生成解析器时的结果
------- 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))
运行解析器的代码
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();
提前致谢