feat: 按照open_set中的示例调整语法 (#71)
添加了构建LR分析表冲突的报错 Reviewed-on: PostGuard/Canon#71
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,6 @@
|
||||
using Canon.Core.Abstractions;
|
||||
using Canon.Core.Enums;
|
||||
using Canon.Core.Exceptions;
|
||||
|
||||
namespace Canon.Core.GrammarParser;
|
||||
|
||||
@@ -45,13 +47,23 @@ public class Grammar
|
||||
{
|
||||
if (expression.Pos == expression.Right.Count)
|
||||
{
|
||||
transformer.ReduceTable.TryAdd(expression.LookAhead, new ReduceInformation(
|
||||
expression.Right.Count, expression.Left));
|
||||
if (transformer.ShiftTable.ContainsKey(expression.LookAhead))
|
||||
{
|
||||
throw new ReduceAndShiftConflictException();
|
||||
}
|
||||
|
||||
if (!transformer.ReduceTable.TryAdd(expression.LookAhead,
|
||||
new ReduceInformation(expression.Right.Count, expression.Left)))
|
||||
{
|
||||
// 发生归约-归约冲突
|
||||
throw new ReduceConflictException(state, expression.LookAhead, expression.Left,
|
||||
transformer.ReduceTable[expression.LookAhead].Left);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 生成移进的迁移表
|
||||
foreach (KeyValuePair<TerminatorBase,LrState> pair in state.Transformer)
|
||||
foreach (KeyValuePair<TerminatorBase, LrState> pair in state.Transformer)
|
||||
{
|
||||
ITransformer targetTransformer;
|
||||
if (transformers.TryGetValue(pair.Value, out Transformer? oldTransformer2))
|
||||
@@ -64,7 +76,19 @@ public class Grammar
|
||||
transformers.Add(pair.Value, newTransformer);
|
||||
targetTransformer = newTransformer;
|
||||
}
|
||||
transformer.ShiftTable.TryAdd(pair.Key, targetTransformer);
|
||||
|
||||
// 检测移进-归约冲突
|
||||
if (pair.Key.IsTerminated)
|
||||
{
|
||||
Terminator terminator = (Terminator)pair.Key;
|
||||
// hack 对于ElsePart的移进-归约冲突
|
||||
if (terminator != new Terminator(KeywordType.Else) && transformer.ReduceTable.ContainsKey(terminator))
|
||||
{
|
||||
throw new ReduceAndShiftConflictException();
|
||||
}
|
||||
}
|
||||
|
||||
transformer.ShiftTable.Add(pair.Key, targetTransformer);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -101,7 +101,7 @@ public static class PascalGrammar
|
||||
]
|
||||
},
|
||||
{
|
||||
// ConstValue -> +num | -num | num | 'letter'
|
||||
// ConstValue -> +num | -num | num | 'letter' | true | false
|
||||
new NonTerminator(NonTerminatorType.ConstValue), [
|
||||
[
|
||||
new Terminator(OperatorType.Plus), Terminator.NumberTerminator
|
||||
@@ -114,6 +114,12 @@ public static class PascalGrammar
|
||||
],
|
||||
[
|
||||
Terminator.CharacterTerminator,
|
||||
],
|
||||
[
|
||||
new Terminator(KeywordType.True)
|
||||
],
|
||||
[
|
||||
new Terminator(KeywordType.False)
|
||||
]
|
||||
]
|
||||
},
|
||||
@@ -245,6 +251,10 @@ public static class PascalGrammar
|
||||
[
|
||||
Terminator.EmptyTerminator,
|
||||
],
|
||||
[
|
||||
new Terminator(DelimiterType.LeftParenthesis),
|
||||
new Terminator(DelimiterType.RightParenthesis)
|
||||
],
|
||||
[
|
||||
new Terminator(DelimiterType.LeftParenthesis),
|
||||
new NonTerminator(NonTerminatorType.ParameterList),
|
||||
@@ -334,13 +344,10 @@ public static class PascalGrammar
|
||||
{
|
||||
// Statement -> ε
|
||||
// | Variable AssignOp Expression
|
||||
// | FuncId AssignOp Expression
|
||||
// | ProcedureCall
|
||||
// | CompoundStatement
|
||||
// | if Expression then Statement ElsePart
|
||||
// | for id AssignOp Expression to Expression do Statement
|
||||
// | read ( VariableList )
|
||||
// | write( ExpressionList )
|
||||
// 注意这里 read 和 write 作为普通的函数调用处理了
|
||||
// 因此下面并没有单独声明
|
||||
new NonTerminator(NonTerminatorType.Statement), [
|
||||
@@ -354,12 +361,6 @@ public static class PascalGrammar
|
||||
new Terminator(OperatorType.Assign),
|
||||
new NonTerminator(NonTerminatorType.Expression)
|
||||
],
|
||||
[
|
||||
// FuncId AssignOp Expression
|
||||
Terminator.IdentifierTerminator,
|
||||
new Terminator(OperatorType.Assign),
|
||||
new NonTerminator(NonTerminatorType.Expression)
|
||||
],
|
||||
[
|
||||
// ProcedureCall
|
||||
new NonTerminator(NonTerminatorType.ProcedureCall)
|
||||
@@ -426,11 +427,16 @@ public static class PascalGrammar
|
||||
]
|
||||
},
|
||||
{
|
||||
// ProcedureCall -> id | id ( ExpressionList )
|
||||
// ProcedureCall -> id | id() | id ( ExpressionList )
|
||||
new NonTerminator(NonTerminatorType.ProcedureCall), [
|
||||
[
|
||||
Terminator.IdentifierTerminator,
|
||||
],
|
||||
[
|
||||
Terminator.IdentifierTerminator,
|
||||
new Terminator(DelimiterType.LeftParenthesis),
|
||||
new Terminator(DelimiterType.RightParenthesis)
|
||||
],
|
||||
[
|
||||
Terminator.IdentifierTerminator,
|
||||
new Terminator(DelimiterType.LeftParenthesis),
|
||||
@@ -506,9 +512,13 @@ public static class PascalGrammar
|
||||
{
|
||||
// Factor -> num | Variable
|
||||
// | ( Expression )
|
||||
// | id ( ExpressionList )
|
||||
// | id ()
|
||||
// | id (ExpressionList)
|
||||
// | not Factor
|
||||
// | minus Factor
|
||||
// | - Factor
|
||||
// | + Factor
|
||||
// | true
|
||||
// | false
|
||||
new NonTerminator(NonTerminatorType.Factor), [
|
||||
[
|
||||
Terminator.NumberTerminator,
|
||||
@@ -521,6 +531,11 @@ public static class PascalGrammar
|
||||
new NonTerminator(NonTerminatorType.Expression),
|
||||
new Terminator(DelimiterType.RightParenthesis)
|
||||
],
|
||||
[
|
||||
Terminator.IdentifierTerminator,
|
||||
new Terminator(DelimiterType.LeftParenthesis),
|
||||
new Terminator(DelimiterType.RightParenthesis)
|
||||
],
|
||||
[
|
||||
Terminator.IdentifierTerminator,
|
||||
new Terminator(DelimiterType.LeftParenthesis),
|
||||
@@ -534,6 +549,16 @@ public static class PascalGrammar
|
||||
[
|
||||
new Terminator(OperatorType.Minus),
|
||||
new NonTerminator(NonTerminatorType.Factor)
|
||||
],
|
||||
[
|
||||
new Terminator(OperatorType.Plus),
|
||||
new NonTerminator(NonTerminatorType.Factor)
|
||||
],
|
||||
[
|
||||
new Terminator(KeywordType.True)
|
||||
],
|
||||
[
|
||||
new Terminator(KeywordType.False)
|
||||
]
|
||||
]
|
||||
},
|
||||
|
Reference in New Issue
Block a user