feat: 按照open_set中的示例调整语法 (#71)

添加了构建LR分析表冲突的报错

Reviewed-on: PostGuard/Canon#71
This commit is contained in:
2024-05-01 21:06:27 +08:00
parent feddbff205
commit 6130adfa7c
32 changed files with 1382 additions and 985 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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);
}
}

View File

@@ -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)
]
]
},