- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我必须编写要在java应用程序中使用的解析器,它将接受:
每个标记由以下任一分隔:
<WHITE : ([" ", "\t"])+ >
<COMMA : (",") >
<SEMICOLON : (";") >
<EOL : ("\r" | "\n" | "\r\n") >
如果范围没有可选空格,一切都会很容易,例如:
1- 2
2 -3
3 - 4
4-5
测试字符串是这样的:"1 2 3 4 5,6,7;8;9,, 10;11;;, ;,;,,;\n\n ;,,; 12,13-13, 14 - 14 15- 15 16 -16\n17-17\n 18 - 18\n 19 - 19\n GROUP_1_A;GROUP_1_A GROUP_1_A;GROUP_1_A,GROUP_1_A ,;;\n\n\"GROUP_1_A\";; 20"
我尝试了几种定义“-”周围空格的方法,但总而言之,要么以无限嵌套循环结束,该循环处理给定的简单字符串直到结束,然后从头开始,要么无法进入下一次迭代。如果有一种方法可以检查访问下一个 token 而不消耗它,那就很容易了。
SKIP: {
< QUOTATION : ( ["\""] ) > |
< APOSTROPHE : ( ["'"] ) >
}
TOKEN: {
< NAME : ( ["a"-"z", "A"-"Z"])+ (["a"-"z", "A"-"Z", "_", "0"-"9"] )* > |
< NUM : ( ["0"-"9"] ){1,5} > |
< WHITE : ( [" ", "\t"] ) > |
< EOL : ( "\n" | "\r" | "\r\n" ) > |
< COMMA : ( [","] ) > |
< SEMICOLON : ( [";"] ) >
}
Map<String, List<String>> parse() : {
Map<String, List<String>> result = new HashMap<String, List<String>>();
List<String> single = new ArrayList<String>();
List<String> range = new ArrayList<String>();
List<String> named = new ArrayList<String>();
result.put(SINGLE, single);
result.put(RANGE, range);
result.put(NAMED, named);
Token name = null;
Token first = null;
Token last = null;
}
{
(<WHITE>)*
(
(name = <NAME> |
first = <NUM>
(LOOKAHEAD(2) (<WHITE>)* "-" (<WHITE>)* last = <NUM>)?
)
((LOOKAHEAD(2) <EOL> | <COMMA> | <SEMICOLON> | <WHITE>)+ | <EOF>)
{
if (name != null) {
named.add(name.image);
} else if (first != null && last == null) {
single.add(first.image);
} else if (first != null && last != null) {
String s = first.image + " - " + last.image;
range.add(s);
} else {
System.err.println("Parser error found");
}
name = null;
first = null;
last = null;
}
)+
{
return result;
}
}
这是解析的输出:
Call: parse
Consumed token: <<WHITE>: " " at line 1 column 1>
Consumed token: <<WHITE>: " " at line 1 column 2>
Consumed token: <<NUM>: "1" at line 1 column 3>
Visited token: <<WHITE>: " " at line 1 column 4>; Expected token: <<WHITE>>
Visited token: <<NUM>: "2" at line 1 column 5>; Expected token: <<WHITE>>
Visited token: <<NUM>: "2" at line 1 column 5>; Expected token: <"-">
Visited token: <<WHITE>: " " at line 1 column 4>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 1 column 4>
Consumed token: <<NUM>: "2" at line 1 column 5>
Visited token: <<WHITE>: " " at line 1 column 6>; Expected token: <<WHITE>>
Visited token: <<NUM>: "3" at line 1 column 7>; Expected token: <<WHITE>>
Visited token: <<NUM>: "3" at line 1 column 7>; Expected token: <"-">
Visited token: <<WHITE>: " " at line 1 column 6>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 1 column 6>
Consumed token: <<NUM>: "3" at line 1 column 7>
Visited token: <<WHITE>: " " at line 1 column 8>; Expected token: <<WHITE>>
Visited token: <<NUM>: "4" at line 1 column 9>; Expected token: <<WHITE>>
Visited token: <<NUM>: "4" at line 1 column 9>; Expected token: <"-">
Visited token: <<WHITE>: " " at line 1 column 8>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 1 column 8>
Consumed token: <<NUM>: "4" at line 1 column 9>
Visited token: <<WHITE>: " " at line 1 column 10>; Expected token: <<WHITE>>
Visited token: <<NUM>: "5" at line 1 column 11>; Expected token: <<WHITE>>
Visited token: <<NUM>: "5" at line 1 column 11>; Expected token: <"-">
Visited token: <<WHITE>: " " at line 1 column 10>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 1 column 10>
Consumed token: <<NUM>: "5" at line 1 column 11>
Visited token: <<COMMA>: "," at line 1 column 12>; Expected token: <<WHITE>>
Visited token: <<COMMA>: "," at line 1 column 12>; Expected token: <"-">
Visited token: <<COMMA>: "," at line 1 column 12>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 1 column 12>
Consumed token: <<NUM>: "6" at line 1 column 13>
Visited token: <<COMMA>: "," at line 1 column 14>; Expected token: <<WHITE>>
Visited token: <<COMMA>: "," at line 1 column 14>; Expected token: <"-">
Visited token: <<COMMA>: "," at line 1 column 14>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 1 column 14>
Consumed token: <<NUM>: "7" at line 1 column 15>
Visited token: <<SEMICOLON>: ";" at line 1 column 16>; Expected token: <<WHITE>>
Visited token: <<SEMICOLON>: ";" at line 1 column 16>; Expected token: <"-">
Visited token: <<SEMICOLON>: ";" at line 1 column 16>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 1 column 16>
Consumed token: <<NUM>: "8" at line 1 column 17>
Visited token: <<SEMICOLON>: ";" at line 1 column 18>; Expected token: <<WHITE>>
Visited token: <<SEMICOLON>: ";" at line 1 column 18>; Expected token: <"-">
Visited token: <<SEMICOLON>: ";" at line 1 column 18>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 1 column 18>
Consumed token: <<NUM>: "9" at line 1 column 19>
Visited token: <<COMMA>: "," at line 1 column 20>; Expected token: <<WHITE>>
Visited token: <<COMMA>: "," at line 1 column 20>; Expected token: <"-">
Visited token: <<COMMA>: "," at line 1 column 20>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 1 column 20>
Visited token: <<COMMA>: "," at line 1 column 21>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 1 column 21>
Visited token: <<WHITE>: " " at line 1 column 22>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 1 column 22>
Visited token: <<WHITE>: " " at line 1 column 23>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 1 column 23>
Consumed token: <<NUM>: "10" at line 1 column 24>
Visited token: <<SEMICOLON>: ";" at line 1 column 26>; Expected token: <<WHITE>>
Visited token: <<SEMICOLON>: ";" at line 1 column 26>; Expected token: <"-">
Visited token: <<SEMICOLON>: ";" at line 1 column 26>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 1 column 26>
Consumed token: <<NUM>: "11" at line 1 column 27>
Visited token: <<SEMICOLON>: ";" at line 1 column 29>; Expected token: <<WHITE>>
Visited token: <<SEMICOLON>: ";" at line 1 column 29>; Expected token: <"-">
Visited token: <<SEMICOLON>: ";" at line 1 column 29>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 1 column 29>
Visited token: <<SEMICOLON>: ";" at line 1 column 30>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 1 column 30>
Visited token: <<COMMA>: "," at line 1 column 31>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 1 column 31>
Visited token: <<WHITE>: " " at line 1 column 32>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 1 column 32>
Visited token: <<WHITE>: " " at line 1 column 33>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 1 column 33>
Visited token: <<SEMICOLON>: ";" at line 1 column 34>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 1 column 34>
Visited token: <<COMMA>: "," at line 1 column 35>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 1 column 35>
Visited token: <<SEMICOLON>: ";" at line 1 column 36>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 1 column 36>
Visited token: <<COMMA>: "," at line 1 column 37>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 1 column 37>
Visited token: <<COMMA>: "," at line 1 column 38>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 1 column 38>
Visited token: <<SEMICOLON>: ";" at line 1 column 39>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 1 column 39>
Visited token: <<EOL>: "\n" at line 1 column 40>; Expected token: <<EOL>>
Consumed token: <<EOL>: "\n" at line 1 column 40>
Visited token: <<EOL>: "\n" at line 2 column 1>; Expected token: <<EOL>>
Consumed token: <<EOL>: "\n" at line 2 column 1>
Visited token: <<WHITE>: " " at line 3 column 1>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 1>
Visited token: <<WHITE>: " " at line 3 column 2>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 2>
Visited token: <<WHITE>: " " at line 3 column 3>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 3>
Visited token: <<SEMICOLON>: ";" at line 3 column 4>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 3 column 4>
Visited token: <<COMMA>: "," at line 3 column 5>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 3 column 5>
Visited token: <<COMMA>: "," at line 3 column 6>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 3 column 6>
Visited token: <<SEMICOLON>: ";" at line 3 column 7>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 3 column 7>
Visited token: <<WHITE>: " " at line 3 column 8>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 8>
Visited token: <<WHITE>: " " at line 3 column 9>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 9>
Consumed token: <<NUM>: "12" at line 3 column 10>
Visited token: <<COMMA>: "," at line 3 column 12>; Expected token: <<WHITE>>
Visited token: <<COMMA>: "," at line 3 column 12>; Expected token: <"-">
Visited token: <<COMMA>: "," at line 3 column 12>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 3 column 12>
Consumed token: <<NUM>: "13" at line 3 column 13>
Visited token: <"-" at line 3 column 15>; Expected token: <<WHITE>>
Visited token: <"-" at line 3 column 15>; Expected token: <"-">
Visited token: <<NUM>: "13" at line 3 column 16>; Expected token: <<WHITE>>
Visited token: <<NUM>: "13" at line 3 column 16>; Expected token: <<NUM>>
Consumed token: <"-" at line 3 column 15>
Consumed token: <<NUM>: "13" at line 3 column 16>
Visited token: <<COMMA>: "," at line 3 column 18>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 3 column 18>
Visited token: <<WHITE>: " " at line 3 column 19>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 19>
Visited token: <<WHITE>: " " at line 3 column 20>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 20>
Consumed token: <<NUM>: "14" at line 3 column 21>
Visited token: <<WHITE>: " " at line 3 column 23>; Expected token: <<WHITE>>
Visited token: <<WHITE>: " " at line 3 column 24>; Expected token: <<WHITE>>
Consumed token: <<WHITE>: " " at line 3 column 23>
Consumed token: <<WHITE>: " " at line 3 column 24>
Consumed token: <"-" at line 3 column 25>
Consumed token: <<WHITE>: " " at line 3 column 26>
Consumed token: <<WHITE>: " " at line 3 column 27>
Consumed token: <<WHITE>: " " at line 3 column 28>
Consumed token: <<WHITE>: " " at line 3 column 29>
Consumed token: <<NUM>: "14" at line 3 column 30>
Visited token: <<WHITE>: " " at line 3 column 32>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 32>
Consumed token: <<NUM>: "15" at line 3 column 33>
Visited token: <"-" at line 3 column 35>; Expected token: <<WHITE>>
Visited token: <"-" at line 3 column 35>; Expected token: <"-">
Visited token: <<WHITE>: " " at line 3 column 36>; Expected token: <<WHITE>>
Consumed token: <"-" at line 3 column 35>
Consumed token: <<WHITE>: " " at line 3 column 36>
Consumed token: <<NUM>: "15" at line 3 column 37>
Visited token: <<WHITE>: " " at line 3 column 39>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 39>
Consumed token: <<NUM>: "16" at line 3 column 40>
Visited token: <<WHITE>: " " at line 3 column 42>; Expected token: <<WHITE>>
Visited token: <"-" at line 3 column 43>; Expected token: <<WHITE>>
Visited token: <"-" at line 3 column 43>; Expected token: <"-">
Consumed token: <<WHITE>: " " at line 3 column 42>
Consumed token: <"-" at line 3 column 43>
Consumed token: <<NUM>: "16" at line 3 column 44>
Visited token: <<WHITE>: " " at line 3 column 46>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 3 column 46>
Visited token: <<EOL>: "\n" at line 3 column 47>; Expected token: <<EOL>>
Consumed token: <<EOL>: "\n" at line 3 column 47>
Consumed token: <<NUM>: "17" at line 4 column 1>
Visited token: <"-" at line 4 column 3>; Expected token: <<WHITE>>
Visited token: <"-" at line 4 column 3>; Expected token: <"-">
Visited token: <<NUM>: "17" at line 4 column 4>; Expected token: <<WHITE>>
Visited token: <<NUM>: "17" at line 4 column 4>; Expected token: <<NUM>>
Consumed token: <"-" at line 4 column 3>
Consumed token: <<NUM>: "17" at line 4 column 4>
Visited token: <<EOL>: "\n" at line 4 column 6>; Expected token: <<EOL>>
Consumed token: <<EOL>: "\n" at line 4 column 6>
Visited token: <<WHITE>: " " at line 5 column 1>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 5 column 1>
Consumed token: <<NUM>: "18" at line 5 column 2>
Visited token: <<WHITE>: " " at line 5 column 4>; Expected token: <<WHITE>>
Visited token: <"-" at line 5 column 5>; Expected token: <<WHITE>>
Visited token: <"-" at line 5 column 5>; Expected token: <"-">
Consumed token: <<WHITE>: " " at line 5 column 4>
Consumed token: <"-" at line 5 column 5>
Consumed token: <<WHITE>: " " at line 5 column 6>
Consumed token: <<NUM>: "18" at line 5 column 7>
Visited token: <<EOL>: "\n" at line 5 column 9>; Expected token: <<EOL>>
Consumed token: <<EOL>: "\n" at line 5 column 9>
Visited token: <<WHITE>: " " at line 6 column 1>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 6 column 1>
Consumed token: <<NUM>: "19" at line 6 column 2>
Visited token: <<WHITE>: " " at line 6 column 4>; Expected token: <<WHITE>>
Visited token: <"-" at line 6 column 5>; Expected token: <<WHITE>>
Visited token: <"-" at line 6 column 5>; Expected token: <"-">
Consumed token: <<WHITE>: " " at line 6 column 4>
Consumed token: <"-" at line 6 column 5>
Consumed token: <<WHITE>: " " at line 6 column 6>
Consumed token: <<NUM>: "19" at line 6 column 7>
Visited token: <<WHITE>: " " at line 6 column 9>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 6 column 9>
Visited token: <<EOL>: "\n" at line 6 column 10>; Expected token: <<EOL>>
Consumed token: <<EOL>: "\n" at line 6 column 10>
Visited token: <<WHITE>: " " at line 7 column 1>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 7 column 1>
Consumed token: <<NAME>: "GROUP_1_A" at line 7 column 2>
Visited token: <<SEMICOLON>: ";" at line 7 column 20>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 7 column 20>
Consumed token: <<NAME>: "GROUP_1_A" at line 7 column 21>
Visited token: <<WHITE>: " " at line 7 column 39>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 7 column 39>
Consumed token: <<NAME>: "GROUP_1_A" at line 7 column 40>
Visited token: <<SEMICOLON>: ";" at line 7 column 58>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 7 column 58>
Consumed token: <<NAME>: "GROUP_1_A" at line 7 column 59>
Visited token: <<COMMA>: "," at line 7 column 77>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 7 column 77>
Consumed token: <<NAME>: "GROUP_1_A" at line 7 column 78>
Visited token: <<WHITE>: " " at line 7 column 96>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 7 column 96>
Visited token: <<WHITE>: " " at line 7 column 97>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 7 column 97>
Visited token: <<COMMA>: "," at line 7 column 98>; Expected token: <<EOL>>
Consumed token: <<COMMA>: "," at line 7 column 98>
Visited token: <<SEMICOLON>: ";" at line 7 column 99>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 7 column 99>
Visited token: <<SEMICOLON>: ";" at line 7 column 100>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 7 column 100>
Visited token: <<EOL>: "\n" at line 7 column 101>; Expected token: <<EOL>>
Consumed token: <<EOL>: "\n" at line 7 column 101>
Visited token: <<EOL>: "\n" at line 8 column 1>; Expected token: <<EOL>>
Consumed token: <<EOL>: "\n" at line 8 column 1>
Visited token: <<WHITE>: " " at line 9 column 1>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 9 column 1>
Visited token: <<WHITE>: " " at line 9 column 2>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 9 column 2>
Visited token: <<WHITE>: " " at line 9 column 3>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 9 column 3>
Consumed token: <<NAME>: "GROUP_1_A" at line 9 column 5>
Visited token: <<WHITE>: " " at line 9 column 24>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 9 column 24>
Visited token: <<WHITE>: " " at line 9 column 25>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 9 column 25>
Visited token: <<SEMICOLON>: ";" at line 9 column 26>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 9 column 26>
Visited token: <<SEMICOLON>: ";" at line 9 column 27>; Expected token: <<EOL>>
Consumed token: <<SEMICOLON>: ";" at line 9 column 27>
Visited token: <<WHITE>: " " at line 9 column 28>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 9 column 28>
Visited token: <<WHITE>: " " at line 9 column 29>; Expected token: <<EOL>>
Consumed token: <<WHITE>: " " at line 9 column 29>
Consumed token: <<NUM>: "20" at line 9 column 30>
Visited token: <<WHITE>: " " at line 9 column 32>; Expected token: <<WHITE>>
Visited token: <<WHITE>: " " at line 9 column 33>; Expected token: <<WHITE>>
Consumed token: <<WHITE>: " " at line 9 column 32>
Consumed token: <<WHITE>: " " at line 9 column 33>
Return: parse
parsers.excel.ParseException: Encountered " <NUM> "1 "" at line 9, column 34.
Was expecting one of:
<WHITE> ...
"-" ...
解析器应该产生类似的输出:
single = [1,2,3,4,5,6,7,8,9,10,11,12,20]
range = [13 - 13,14 - 14,15 - 15,16 - 16,17 - 17,18 - 18,19 - 19]
named = [GROUP_1_A,GROUP_1_A,GROUP_1_A,GROUP_1_A,GROUP_1_A,GROUP_1_A]
当解析器不知道空格是来自破折号之前的空格还是来自整个数字的分隔符的空格时,就会出现问题。
如果您知道修改 JavaCC 以正确完成解析提供的字符串的任何方法,我们将不胜感激。
最佳答案
让我们从 JavaCC 退一步,看看您的语法实际上是什么。
parse --> ows ( body )+
body --> part sep
part --> <NAME>
part --> <NUM>
part --> <NUM> ows "-" ows <NUM>
sep --> (<EOL> | <COMMA> | <SEMICOLON> | <WHITE>)+
sep --> EOF
ows --> (<WHITE>)*
您应该检查一遍,以确保 (a) 我没有犯任何错误,并且 (b) 这确实是您想要的语言。
我不喜欢您处理EOF
的方式。它并不是真正的分隔符。我建议使用以下几乎相同的语法
parse --> ows body
body --> part ( sep body | <EOF> )
part --> <NAME>
part --> <NUM>
part --> <NUM> ows "-" ows <NUM>
sep --> (<EOL> | <COMMA> | <SEMICOLON> | <WHITE>)+
ows --> (<WHITE>)*
<小时/>
第一个解决方案:语法前瞻
OP 说如果有一种方法可以检查下一个 token 而不消耗它,那就很容易了。 有。这称为语法前瞻。
我们唯一需要前瞻的地方是区分部分
的第二个和第三个产生式。让我们将它们结合起来。
part --> <NAME>
part --> <NUM> ( ows "-" ows <NUM> )?
没有固定长度的前瞻决定是否在第二次产生式中采用可选路径。所以我们使用这样的语法前瞻:
part --> <NAME>
part --> <NUM> ( LOOKAHEAD( ows "-" ) ows "-" ows <NUM> )?
现在,我们完成了。让我们将生成式放回到 JavaCC 中
void parse() : { }
{
ows() body }
}
void body() : { }
{
part() ( sep() body() | <EOF> )
}
void part() : { }
{
<NAME>
|
<NUM>
( LOOKAHEAD( ows() "-")
ows() "-" ows() <NUM>
)?
}
void sep() : {}
{
(<EOL> | <COMMA> | <SEMICOLON> | <WHITE>)+
}
void ows() : {}
{
(<WHITE>)*
}
<小时/>
第二个解决方案:LL(1)
我们可以用 LL(1) 语法来解决这个问题吗?是的。让我们回到最初的语法,或者更确切地说,回到将 EOF
移出循环的语法。
parse --> ows body
body --> part (sep body | <EOF>)
part --> <NAME>
part --> <NUM> ( ows "-" ows <NUM> )?
sep --> (<EOL> | <COMMA> | <SEMICOLON> | <WHITE>)+
ows --> (<WHITE>)*
内联part
并引入非终结符afternum
parse --> ows body
body --> <NAME> (sep body | <EOF>)
body --> <NUM> afternum
afternum --> ( ows "-" ows <NUM> )? (sep body | <EOF>)
sep --> (<EOL> | <COMMA> | <SEMICOLON> | <WHITE>)+
ows --> (<WHITE>)*
现在问题出在afternum
中。
当我们开始解析 afternum
时,有 5 种可能性需要考虑。 (i) 下一个标记是"-"
。 (ii) 下一个标记是 EOL
、COMMA
或 SEMICOLON
。 (iii) 下一个标记是空格。 (iv) 下一个标记是EOF
。 (v) 在任何其他情况下,我们都会出错。
对于情况 (ii),这不能是最后一部分。在情况 (iii) 中,我们刚刚看到的 WHITE 可能是 sep
的第一个字符,也可能会导致连字符。我们创建一个新的非终结符来处理这两种可能性。
afternum --> "-" ows <NUM> (sep body | <EOF>)
afternum --> nonwssep (sep)? body
afternum --> <WHITE> moreafternum
afternum --> EOF
moreafternum --> ows "-" ows <NUM> (sep body | EOF)
| sep? body
nonwssep --> <EOL> | <COMMA> | <SEMICOLON>
现在问题出在 moreafternum
中,因为如果下一个标记是 WHITE
,则任一选择都是可行的。
让我们稍微操作一下moreafternum
。目标是公开该 WHITE
token ,以便我们可以将其分解出来。
moreafternum
= By definition
ows "-" ows <NUM> (sep body | EOF) | sep? body
= Expand the ?
ows "-" ows <NUM> (sep body | EOF)
| body
| sep body
= Expand first `ows` and split white from other cases
"-" ows <NUM> (sep body | EOF)
| WHITE ows "-" ows <NUM> (sep body | EOF)
| body
| sep body
= Expand the `sep` in the fourth case
"-" ows <NUM> (sep body | EOF)
| WHITE ows "-" ows <NUM> (sep body | EOF)
| body
| (WHITE | nonwesep) sep? body
= Split the fourth case
"-" ows <NUM> (sep body | EOF)
| WHITE ows "-" ows <NUM> (sep body | EOF)
| body
| WHITE sep? body
| nonwssep sep? body
= Duplicate the fourth choice
"-" ows <NUM> (sep body | EOF)
| WHITE ows "-" ows <NUM> (sep body | EOF)
| WHITE sep? body
| body
| WHITE sep? body
| nonwssep sep?
= Combine the second and third choices.
"-" ows <NUM> (sep body | EOF)
| WHITE ( ows "-" ows <NUM> (sep body | EOF) | sep? body )
| body
| WHITE sep? body
| nonwssep sep? body
= combine the third, fourth, and fifth choices
"-" ows <NUM> (sep body | EOF)
| WHITE ( ows "-" ows <NUM> (sep body | EOF) | sep? body)
| sep? body
= Definition of moreafternum
"-" ows <NUM> (sep body | EOF)
| WHITE moreafternum
| sep? body
现在我们可以用这个递归版本重新定义moreafternum
moreafternum --> "-" ows <NUM> (sep body | EOF)
| <WHITE> moreafternum
| sep? body
如果我们用 JavaCC 编写这个产生式,当下一个标记是 WHITE 时,第二个和第三个选择之间仍然会存在选择冲突。 JavaCC 会优先选择第二个而不是第三个,这正是我们想要的。如果您不喜欢该警告,可以使用 LOOKAHEAD 来抑制它。请注意,此 LOOKAHEAD 不会更改生成的 Java 代码,它只是抑制警告。
void moreafternum() : {} {
"-" ows() <NUM> (sep() body() | <EOF>)
|
// LOOKAHEAD( <WHITE> ) // Optional lookahead to suppresss the warning
<WHITE> moreafternum()
|
( sep() )? body() }
通过再次查看 moreafternum
,我们可以一直到 LL(1)。
moreafternum
= From above
"-" ows <NUM> (sep body | EOF)
| WHITE ( ows "-" ows <NUM> (sep body | EOF) | sep? body)
| body
| WHITE sep? body
| nonwssep sep? body
= Fourth choice is subsumed by the second.
"-" ows <NUM> (sep body | EOF)
| WHITE ( ows "-" ows <NUM> (sep body | EOF) | sep? body)
| body
| nonwssep sep? body
= Combine last two choices
"-" ows <NUM> (sep body | EOF)
| WHITE ( ows "-" ows <NUM> (sep body | EOF) | sep? body)
| (nonwssep sep?)? body
= Original definition of moreaftersep
"-" ows <NUM> (sep body | EOF)
| WHITE moreaftersep
| (nonwssep sep?)? body
总而言之,我们得到
parse --> ows body
body --> <NAME> (sep body | <EOF>)
body --> <NUM> afternum
afternum --> "-" ows <NUM> (sep body | <EOF>)
afternum --> <WHITE> moreafternum
afternum --> nonwssep (sep)? body
afternum --> EOF
moreafternum --> "-" ows <NUM> (sep body | EOF)
moreafternum --> <WHITE> moreafternum
moreafternum --> ( nonwssep (sep)? )? body
nonwssep --> <EOL> | <COMMA> | <SEMICOLON>
sep --> (nonwssep | <WHITE>)+
ows --> (<WHITE>)*
这是 LL(1),因此您可以将其转换为 JavaCC,无需先行。
关于java - 使用可为空/可选标记时进入下一个循环迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53966401/
如果我 mov, eax 12345 和之后的 mov var, eax (假设 var 是一个 32 位的 int 等..等等)并输出 var 稍后它会正确输出。 与 ax 相同。 mov ax,
我有这个代码: for($nrt=0; $nrt"; if($sidesIndexes[$nrt]==$nrt) { echo "am I in??? ".$sidesInde
我正在阅读The Go Programming Language的8.5章,并陷入一些代码。下面的代码列表。 func main() { naturals := make(chan int)
我写了一个 MySQL 查询用于将数据导出到文本文件。 查询运行成功,但结果与我的预期不符。 我想在列之间没有间距的结果。 select sample_export_record1_2013.
在普通的 Excel 窗口中,我可以打开 VBE 并通过触摸键序列插入一个新模块:ALT+F11、ALTim 全部不使用鼠标。有没有办法打开 VBE 并导航到 本工作手册 不使用鼠标的代码区域? 最佳
我正在使用 axios 发出 http 请求。在 .then() 内部,我正在使用另一个 axios 调用。最后,我有第三个 then(),它应该在第二个 then 之后运行,但实际上并没有这样做。
我需要在 cocos2d 项目中播放视频..我的问题是:如何将 MPMoviePlayerController 放入我的 View 中,如下所示:? UIView *theView = [[CCDir
我正在学习 Angular。以下代码有效: .controller('abc', function ($scope, $http) { $http.get("/Handlers/Authenticat
目前我正在使用 WPF 学习 C#。我的主要方法是尽我所能使用 MVVM 模式,但现在我有点困惑。 在我所有 View 的应用程序中,我有一个 View 模型: private DruckviewVi
关于将 G 邮件提取到 Google 电子表格,我该如何添加 IF 以按主题驳回特定电子邮件?例如:电子邮件回复(主题中带有“RE:”)。我不希望这些电子邮件出现在我的电子表格中。 我尝试过使用 LO
我正在尝试使用 Spotify API 并进入数组。 const App = () => { const [isLoading, setIsLoading] = useState(true);
我有一个 html 模板,并且有一个条件为 --> 的代码 --> window.jQuery || document.write(""+"");
我正在开发一个 Android 应用程序,该应用程序会暴力破解从 int 创建的 MD5 和。 暴力破解部分工作正常。 (我可以sysout最终值并且它是正确的。) 我在将输出值发送到警报对话框时遇到
我正在创建一个界面,用户可以通过该界面生成多系列折线图,并控制绘制哪些数据集。 要绘制哪些数据集由复选框控制。页面加载时,默认数据集以图表形式呈现,并且 $('input:checkbox.data-
我尝试将有向无环图绘制为力布局。 但是我注意到,尽管为每个组元素灌输了进入/退出条件,弹出的节点/链接并没有从 DOM 中删除它们自己。 相反,弹出的节点/链接在力布局中卡住;这意味着没有调用进入/退
这里是新手。我不知道它是怎么发生的,但我正在处理一个程序,当我去调试并进入时,黄色箭头走到了我代码的最后并跳过了整个 block 。有快速解决方法吗? 最佳答案 按 F11,或单击工具栏上的“Step
我的 Action 栏 sherlock 中有一个列表。我想在用户点击该列表时得到。我不想知道用户何时点击某个项目,我已经知道 (onNavigationItemSelected)。 在我的 onCr
** 你好 **我如何从 ci 中的 mysql 日期获取 eurodate 来工作......无法弄清楚 - 请帮忙 想要获取日期 YY-mm- dd -> dd-mm-yy提前致谢 最佳答案 $t
我有以下脚本: #!/bin/bash ls -1 | while read d do [[ -f "$d" ]] && continue echo $d cd $d done
TL;DR - 跳转到最后一段 背景 我正在执行一些数据驱动测试,并将日志文件用作测试输出之一。它的工作原理是这样的- 读取文件夹中的第一个文件 处理第一行并转换为测试 运行测试 执行验证 1 ...
我是一名优秀的程序员,十分优秀!