[feature] 再见,编译原理
This commit is contained in:
parent
e92384f424
commit
8b1775974d
|
@ -14,6 +14,9 @@
|
|||
<None Update="files\if-grammar.grammar">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="files\translateFile">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text;
|
||||
|
||||
namespace CompilerDesignIFlr1
|
||||
{
|
||||
|
@ -32,32 +27,6 @@ namespace CompilerDesignIFlr1
|
|||
|
||||
internal void CalculateProspects()
|
||||
{
|
||||
//Queue<LR1Unit> queue = [];
|
||||
//var startUnit = Units.Where(x=>x.Name == LR1Creator.StartSymbol).First();
|
||||
//startUnit.Prospect.Add("End");
|
||||
|
||||
//queue.Enqueue(startUnit);
|
||||
//while (queue.Count > 0)
|
||||
//{
|
||||
// var unit = queue.Dequeue();
|
||||
// var left = unit.Name;
|
||||
// var units = UnitsHaveDotBefore(left);
|
||||
// var next = unit.Next();
|
||||
// if (next is not null && !LR1Creator.TokenUnit.ContainsKey(next))
|
||||
// foreach (var item in Units.Where(x => x.Name == next))
|
||||
// queue.Enqueue(item);
|
||||
// HashSet<string> prospect = units
|
||||
// .Select(x => GetProspectsOf(x))
|
||||
// .Aggregate(
|
||||
// new HashSet<string>(),
|
||||
// (set, x) =>
|
||||
// {
|
||||
// set.UnionWith(x);
|
||||
// return set;
|
||||
// }
|
||||
// );
|
||||
// unit.Prospect.UnionWith(prospect);
|
||||
//}
|
||||
|
||||
bool haveChange = true;
|
||||
while (haveChange)
|
||||
|
|
|
@ -1,12 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Dynamic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CompilerDesignIFlr1
|
||||
namespace CompilerDesignIFlr1
|
||||
{
|
||||
internal class LR1Creator
|
||||
{
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Text;
|
||||
|
||||
namespace CompilerDesignIFlr1
|
||||
{
|
||||
|
@ -68,9 +64,11 @@ namespace CompilerDesignIFlr1
|
|||
sb.Append("ACTION: \n");
|
||||
foreach (var (key, value) in ACTION)
|
||||
sb.Append(key).Append(": ").Append(value).Append(", ");
|
||||
sb.Append("GOTO: \n");
|
||||
if(GOTO.Count != 0)
|
||||
sb.Append("\nGOTO: \n");
|
||||
foreach (var (key, value) in GOTO)
|
||||
sb.Append(key).Append(": ").Append(value).Append(", ");
|
||||
sb.Append('\n');
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Diagnostics.SymbolStore;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CompilerDesignIFlr1
|
||||
{
|
||||
|
@ -10,6 +7,16 @@ namespace CompilerDesignIFlr1
|
|||
{
|
||||
internal LR1Unit() { }
|
||||
|
||||
internal static string LanguageMode = "English";
|
||||
internal static Dictionary<string, string> EnglishToChinese = [];
|
||||
internal static void Init(string filePath)
|
||||
{
|
||||
string fileContent = File.ReadAllText(filePath);
|
||||
EnglishToChinese = fileContent
|
||||
.Split('#')
|
||||
.Select(x => x.Split(':').Select(x => x.Trim()).ToList()).Where(x=>x.Count == 2).ToList().ToDictionary(x => x[0], x => x[1]);
|
||||
}
|
||||
|
||||
internal LR1Unit(string name, string grammar)
|
||||
{
|
||||
Type = "Token";
|
||||
|
@ -49,7 +56,16 @@ namespace CompilerDesignIFlr1
|
|||
Grammar = grammar;
|
||||
}
|
||||
|
||||
public LR1Unit(int id, string type, string name, int quadrupleIndex, string value, HashSet<string> prospect, int pointPosition, List<string> grammar)
|
||||
public LR1Unit(
|
||||
int id,
|
||||
string type,
|
||||
string name,
|
||||
int quadrupleIndex,
|
||||
string value,
|
||||
HashSet<string> prospect,
|
||||
int pointPosition,
|
||||
List<string> grammar
|
||||
)
|
||||
{
|
||||
Id = id;
|
||||
Type = type;
|
||||
|
@ -62,7 +78,17 @@ namespace CompilerDesignIFlr1
|
|||
}
|
||||
|
||||
internal LR1Unit Clone() =>
|
||||
new LR1Unit(Id, Type, Name, 0, Value,new HashSet<string>(Prospect), PointPosition, [.. Grammar]);
|
||||
new LR1Unit(
|
||||
Id,
|
||||
Type,
|
||||
Name,
|
||||
0,
|
||||
Value,
|
||||
new HashSet<string>(Prospect),
|
||||
PointPosition,
|
||||
[.. Grammar]
|
||||
);
|
||||
|
||||
internal int Id { get; set; } = -1;
|
||||
internal string Type { get; set; } = "";
|
||||
internal string Name { get; set; } = "";
|
||||
|
@ -88,22 +114,29 @@ namespace CompilerDesignIFlr1
|
|||
|
||||
public override string ToString()
|
||||
{
|
||||
string GetName(string s)
|
||||
{
|
||||
return LanguageMode switch
|
||||
{
|
||||
"Chinese" => EnglishToChinese.TryGetValue(s, out var result) ? result : s,
|
||||
"English" => s,
|
||||
_ => throw new Exception("Language mode is not supported.")
|
||||
};
|
||||
}
|
||||
StringBuilder sb = new();
|
||||
//if (Grammar.Count == 0)
|
||||
// return ".";
|
||||
sb.Append($"{Id, 2} ");
|
||||
sb.Append(Name).Append(" ::= ");
|
||||
sb.Append(GetName(Name)).Append(" ::= ");
|
||||
for (int i = 0; i < Grammar.Count; i++)
|
||||
{
|
||||
if (PointPosition == i)
|
||||
sb.Append(". ");
|
||||
sb.Append(Grammar[i] + " ");
|
||||
sb.Append(GetName(Grammar[i]) + " ");
|
||||
}
|
||||
if (PointPosition == Grammar.Count)
|
||||
sb.Append('.');
|
||||
foreach (var item in Prospect)
|
||||
{
|
||||
sb.Append(", " + item);
|
||||
sb.Append(", " + GetName(item));
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
|
|
|
@ -1,12 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using CompilerDesignIFlr1;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace CompilerDesignIflr1
|
||||
namespace CompilerDesignIFlr1
|
||||
{
|
||||
internal class LexicalAnalysis
|
||||
{
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
// See https://aka.ms/new-console-template for more information
|
||||
using CompilerDesignIflr1;
|
||||
using CompilerDesignIFlr1;
|
||||
|
||||
Console.WriteLine("Hello, World!");
|
||||
LR1Unit.Init("./files/translateFile");
|
||||
LR1Unit.LanguageMode = "Chinese";
|
||||
var grammarReader = new GrammarReader("./files/if-grammar.grammar");
|
||||
var lr1Creator = new LR1Creator(grammarReader);
|
||||
var lr1Table = new LR1Table(lr1Creator);
|
||||
|
@ -10,3 +11,4 @@ var lexicalAnalysis = new LexicalAnalysis(lr1Creator, "./files/code");
|
|||
var semanticAnalysis = new SemanticAnalysis();
|
||||
var stateMachine = new StateMachine(lr1Table, lexicalAnalysis, lr1Creator, semanticAnalysis);
|
||||
semanticAnalysis.PrintQuadruples();
|
||||
semanticAnalysis.OptimizeQuadruples();
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Runtime.InteropServices.Marshalling;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
using System.Text;
|
||||
|
||||
namespace CompilerDesignIFlr1
|
||||
{
|
||||
|
@ -733,13 +726,155 @@ namespace CompilerDesignIFlr1
|
|||
|
||||
internal void PrintQuadruples()
|
||||
{
|
||||
Console.WriteLine("四元式:");
|
||||
for (int i = 0; i < Quadruples.Count; i++)
|
||||
{
|
||||
Console.Write($"{i, 3}");
|
||||
//Console.Write($"{i, 3}");
|
||||
Console.WriteLine(Quadruples[i]);
|
||||
}
|
||||
}
|
||||
|
||||
internal void OptimizeQuadruples()
|
||||
{
|
||||
HashSet<int> basedOn = [];
|
||||
bool CanBasedOn(Quadruple quadruple)
|
||||
{
|
||||
return quadruple.Operator != "=" || !quadruple.To.Name.StartsWith("@");
|
||||
}
|
||||
Identifier GetFinal(Identifier? identifier, int from)
|
||||
{
|
||||
if (identifier == null)
|
||||
return null!;
|
||||
if (identifier.Type == IdentifierType.Literal)
|
||||
{
|
||||
if (identifier.Value.StartsWith("@"))
|
||||
{
|
||||
for (int i = from - 1; i >= 0; i--)
|
||||
{
|
||||
if (Quadruples[i].To.Name == identifier.Value)
|
||||
{
|
||||
return Identifier.Literal(Quadruples[i].To.Value);
|
||||
}
|
||||
}
|
||||
throw new Exception("Failed to track identifier");
|
||||
}
|
||||
else
|
||||
return Identifier.Literal(identifier.Value);
|
||||
}
|
||||
if (identifier.Name.StartsWith("@"))
|
||||
{
|
||||
for (int i = from - 1; i >= 0; i--)
|
||||
{
|
||||
if (Quadruples[i].To.Name == identifier.Name)
|
||||
{
|
||||
if (Quadruples[i].Operator == "=")
|
||||
return GetFinal(Quadruples[i].A, i);
|
||||
else
|
||||
return identifier;
|
||||
}
|
||||
}
|
||||
throw new Exception("Failed to track identifier");
|
||||
}
|
||||
else
|
||||
return identifier;
|
||||
}
|
||||
for (int i = 0; i < Quadruples.Count; i++)
|
||||
{
|
||||
if (CanBasedOn(Quadruples[i]))
|
||||
{
|
||||
basedOn.Add(i);
|
||||
Quadruples[i].A = GetFinal(Quadruples[i].A, i);
|
||||
Quadruples[i].B = GetFinal(Quadruples[i].B, i);
|
||||
}
|
||||
}
|
||||
List<Quadruple> afterList = basedOn.Order().Select(x => Quadruples[x].Clone()).ToList();
|
||||
HashSet<int> reAddInAfterList = [];
|
||||
for (int i = 1; i <= afterList.Count; i++)
|
||||
{
|
||||
reAddInAfterList.Add(i);
|
||||
Quadruple quadruple = afterList[^i];
|
||||
if (quadruple.Operator == "=" && quadruple.A.Name.StartsWith('@'))
|
||||
{
|
||||
reAddInAfterList.Remove(i);
|
||||
bool find = false;
|
||||
for (i++; i <= afterList.Count; i++)
|
||||
{
|
||||
reAddInAfterList.Add(i);
|
||||
if (afterList[^i].To.Name == quadruple.A.Name)
|
||||
{
|
||||
afterList[^i].To = quadruple.To;
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!find)
|
||||
throw new Exception("Failed to track identifier");
|
||||
}
|
||||
}
|
||||
afterList = reAddInAfterList.Order().Select(x => afterList[^x]).Reverse().ToList();
|
||||
Dictionary<string, string> tempValueReplace = [];
|
||||
// >x 时 回填到 y
|
||||
Stack<(int, int)> addressReset = [];
|
||||
int tempValueIndex = 0;
|
||||
string GetNewTempName()
|
||||
{
|
||||
return "@T" + tempValueIndex++;
|
||||
}
|
||||
for (int i = 0; i < afterList.Count; i++)
|
||||
{
|
||||
var quadruple = afterList[i];
|
||||
while (addressReset.Count > 0 && addressReset.Peek().Item1 < quadruple.Index)
|
||||
afterList[addressReset.Pop().Item2].To.Value = i + "";
|
||||
quadruple.Index = i;
|
||||
if (quadruple.A.Name.StartsWith("@"))
|
||||
{
|
||||
if (tempValueReplace.TryGetValue(quadruple.A.Name, out string? newName))
|
||||
quadruple.A.Name = newName;
|
||||
else
|
||||
{
|
||||
tempValueReplace.Add(quadruple.A.Name, GetNewTempName());
|
||||
quadruple.A.Name = tempValueReplace[quadruple.A.Name];
|
||||
}
|
||||
}
|
||||
if (quadruple.B is not null && quadruple.B.Name.StartsWith("@"))
|
||||
{
|
||||
if (tempValueReplace.TryGetValue(quadruple.B.Name, out string? newName))
|
||||
quadruple.B.Name = newName;
|
||||
else
|
||||
{
|
||||
tempValueReplace.Add(quadruple.B.Name, GetNewTempName());
|
||||
quadruple.B.Name = tempValueReplace[quadruple.B.Name];
|
||||
}
|
||||
}
|
||||
if (
|
||||
quadruple.To.Name.StartsWith("@")
|
||||
&& quadruple.To.Type != IdentifierType.Address
|
||||
)
|
||||
{
|
||||
if (tempValueReplace.TryGetValue(quadruple.To.Name, out string? newName))
|
||||
quadruple.To.Name = newName;
|
||||
else
|
||||
{
|
||||
tempValueReplace.Add(quadruple.To.Name, GetNewTempName());
|
||||
quadruple.To.Name = tempValueReplace[quadruple.To.Name];
|
||||
}
|
||||
}
|
||||
if (quadruple.Operator.StartsWith('j'))
|
||||
addressReset.Push((int.Parse(quadruple.To.Value), i));
|
||||
}
|
||||
while (addressReset.Count > 0)
|
||||
afterList[addressReset.Pop().Item2].To.Value = afterList.Count + "";
|
||||
Console.WriteLine("After optimize.");
|
||||
//foreach (int i in basedOn.Order().ToList())
|
||||
//{
|
||||
// Console.WriteLine(Quadruples[i]);
|
||||
//}
|
||||
foreach (var t in afterList)
|
||||
{
|
||||
Console.WriteLine(t);
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool Assert(bool val) =>
|
||||
!val ? throw new Exception("Assertion failed.") : false;
|
||||
|
||||
|
@ -892,7 +1027,7 @@ namespace CompilerDesignIFlr1
|
|||
internal Quadruple(string @operator, int index, Identifier a, Identifier? b, Identifier to)
|
||||
{
|
||||
Operator = @operator;
|
||||
this.Index = index;
|
||||
Index = index;
|
||||
A = a;
|
||||
B = b;
|
||||
To = to;
|
||||
|
@ -916,7 +1051,8 @@ namespace CompilerDesignIFlr1
|
|||
return identifier.Name;
|
||||
return identifier.Value;
|
||||
}
|
||||
sb.Append('(')
|
||||
sb.Append($"{Index, 3}")
|
||||
.Append('(')
|
||||
.Append(Operator.PadLeft(4, ' '))
|
||||
.Append(',')
|
||||
.Append(GetValue(A).PadLeft(4, ' '))
|
||||
|
|
|
@ -1,11 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using CompilerDesignIflr1;
|
||||
|
||||
namespace CompilerDesignIFlr1
|
||||
namespace CompilerDesignIFlr1
|
||||
{
|
||||
internal class StateMachine
|
||||
{
|
||||
|
@ -28,10 +21,18 @@ namespace CompilerDesignIFlr1
|
|||
|
||||
internal void Compute()
|
||||
{
|
||||
while (true)
|
||||
try
|
||||
{
|
||||
if (ComputeOnce(Tokens.Pop()))
|
||||
break;
|
||||
while (true)
|
||||
{
|
||||
if (ComputeOnce(Tokens.Pop()))
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
Environment.Exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
文法:
|
||||
key: Program
|
||||
0 程序 ::= . 语句列表
|
||||
key: StatementList
|
||||
1 语句列表 ::= . { Statement_0 }
|
||||
key: IfStatement
|
||||
2 判断语句 ::= . If 条件部分 部分判断语句 Else 语句
|
||||
3 判断语句 ::= . If 条件部分 语句
|
||||
key: PartIfStatement
|
||||
4 部分判断语句 ::= . If 条件部分 部分判断语句 Else 部分判断语句
|
||||
5 部分判断语句 ::= . 无判断语句
|
||||
key: ConditionPart
|
||||
6 条件部分 ::= . ( 条件 )
|
||||
key: Condition
|
||||
7 条件 ::= . 条件表达式 LogicalOperator_ConditionalExpression_0
|
||||
key: ConditionalExpression
|
||||
8 条件表达式 ::= . 表达式 运算符 表达式
|
||||
9 条件表达式 ::= . 表达式
|
||||
key: Expression
|
||||
10 表达式 ::= . 项 AddLike_Term_0
|
||||
key: Statement
|
||||
11 语句 ::= . 判断语句
|
||||
12 语句 ::= . 无判断语句
|
||||
key: NoIfStatement
|
||||
13 无判断语句 ::= . 赋值语句 ;
|
||||
14 无判断语句 ::= . 变量定义 ;
|
||||
15 无判断语句 ::= . { Statement_1 }
|
||||
16 无判断语句 ::= . 常量定义 ;
|
||||
17 无判断语句 ::= . ;
|
||||
key: AssignmentStatement
|
||||
18 赋值语句 ::= . 标识符 = 表达式
|
||||
key: Term
|
||||
19 项 ::= . 因子 MultiplyLike_Factor_0
|
||||
key: ConstantDefinition
|
||||
20 常量定义 ::= . Const 变量定义
|
||||
key: VariableDefinition
|
||||
21 变量定义 ::= . 类型 Identifier__AssignmentStatement_0 Comma_Identifier__Comma_AssignmentStatement_0
|
||||
key: Type
|
||||
22 类型 ::= . Int
|
||||
23 类型 ::= . Char
|
||||
key: Factor
|
||||
24 因子 ::= . 标识符
|
||||
25 因子 ::= . 数字
|
||||
26 因子 ::= . 字符
|
||||
27 因子 ::= . ( 表达式 )
|
||||
key: AddLike
|
||||
28 类加运算符 ::= . +
|
||||
29 类加运算符 ::= . -
|
||||
key: MultiplyLike
|
||||
30 类乘运算符 ::= . *
|
||||
31 类乘运算符 ::= . /
|
||||
32 类乘运算符 ::= . %
|
||||
key: Number
|
||||
33 数字 ::= . 无符号数字
|
||||
34 数字 ::= . - 无符号数字
|
||||
35 数字 ::= . + 无符号数字
|
||||
key: Operator
|
||||
36 运算符 ::= . EqualTo
|
||||
37 运算符 ::= . NotEqualTo
|
||||
38 运算符 ::= . LessThan
|
||||
39 运算符 ::= . GreaterThan
|
||||
40 运算符 ::= . LessThanOrEqual
|
||||
41 运算符 ::= . GreaterThanOrEqual
|
||||
key: LogicalOperator
|
||||
42 逻辑运算符 ::= . And
|
||||
43 逻辑运算符 ::= . Or
|
||||
key: Statement_0
|
||||
44 Statement_0 ::= .
|
||||
45 Statement_0 ::= . 语句 Statement_0
|
||||
key: LogicalOperator_ConditionalExpression_0
|
||||
46 LogicalOperator_ConditionalExpression_0 ::= .
|
||||
47 LogicalOperator_ConditionalExpression_0 ::= . 逻辑运算符 条件表达式 LogicalOperator_ConditionalExpression_0
|
||||
key: AddLike_Term_0
|
||||
48 AddLike_Term_0 ::= .
|
||||
49 AddLike_Term_0 ::= . 类加运算符 项 AddLike_Term_0
|
||||
key: Statement_1
|
||||
50 Statement_1 ::= .
|
||||
51 Statement_1 ::= . 语句 Statement_1
|
||||
key: MultiplyLike_Factor_0
|
||||
52 MultiplyLike_Factor_0 ::= .
|
||||
53 MultiplyLike_Factor_0 ::= . 类乘运算符 因子 MultiplyLike_Factor_0
|
||||
key: Identifier__AssignmentStatement_0
|
||||
54 Identifier__AssignmentStatement_0 ::= . 标识符
|
||||
55 Identifier__AssignmentStatement_0 ::= . 赋值语句
|
||||
key: Comma_Identifier__Comma_AssignmentStatement_0
|
||||
56 Comma_Identifier__Comma_AssignmentStatement_0 ::= .
|
||||
57 Comma_Identifier__Comma_AssignmentStatement_0 ::= . 逗号 标识符 Comma_Identifier__Comma_AssignmentStatement_0
|
||||
58 Comma_Identifier__Comma_AssignmentStatement_0 ::= . 逗号 赋值语句 Comma_Identifier__Comma_AssignmentStatement_0
|
|
@ -1,12 +1,4 @@
|
|||
{
|
||||
int a =1*9+2;
|
||||
if(a>9){
|
||||
a=a+1;
|
||||
if(9>1){
|
||||
a=10;
|
||||
}
|
||||
a=2+2;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
const int a = 5;
|
||||
|
||||
}
|
|
@ -93,8 +93,8 @@ LogicalOperator {
|
|||
Plus { "+" }
|
||||
Minus { "-" }
|
||||
Multiply { "*" }
|
||||
Modulo { "%" }
|
||||
Divide { "/" }
|
||||
Modulo { "%" }
|
||||
LParen { "(" }
|
||||
RParen { ")" }
|
||||
LBrace { "{" }
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
AddLike: 类加运算符 #
|
||||
AssignmentStatement: 赋值语句 #
|
||||
Char: Char #
|
||||
Character: 字符 #
|
||||
Comma: 逗号 #
|
||||
Condition: 条件 #
|
||||
ConditionalExpression: 条件表达式 #
|
||||
ConditionPart: 条件部分 #
|
||||
ConstantDefinition: 常量定义 #
|
||||
Const: Const #
|
||||
Divide: / #
|
||||
Else: Else #
|
||||
Equal: = #
|
||||
Expression: 表达式 #
|
||||
Factor: 因子 #
|
||||
Identifier: 标识符 #
|
||||
If: If #
|
||||
IfStatement: 判断语句 #
|
||||
Int: Int #
|
||||
LBrace: { #
|
||||
LParen: ( #
|
||||
Minus: - #
|
||||
Modulo: % #
|
||||
Multiply: * #
|
||||
MultiplyLike: 类乘运算符 #
|
||||
NoIfStatement: 无判断语句 #
|
||||
Number: 数字 #
|
||||
Operator: 运算符 #
|
||||
PartIfStatement: 部分判断语句 #
|
||||
Plus: + #
|
||||
Program: 程序 #
|
||||
RBrace: } #
|
||||
RParen: ) #
|
||||
Semicolon: ; #
|
||||
Statement: 语句 #
|
||||
StatementList: 语句列表 #
|
||||
String: 字符串 #
|
||||
Term: 项 #
|
||||
Type: 类型 #
|
||||
UnsignedNumber: 无符号数字 #
|
||||
VariableDefinition: 变量定义 #
|
||||
Whitespace: 空白字符 #
|
||||
LogicalOperator: 逻辑运算符 #
|
Loading…
Reference in New Issue