实现一个简单语言(一)
没有赋值的变量可以直接使用,缺点:变量名错误不易发现
前面实现了简单的计算器,在动作中直接计算
下面一步一步实现一个语言
1.变量 (只能由英文构成)
2.数字 (int)
2.赋值表达式
3.加法表达式
4.语句
语法定义
S' -> S
S -> L//语句集合
L -> L T// 语句集合 语句
L -> T// 语句
T -> E ;// 表达式 冒号
E -> identifier = A// 赋值表达式
A -> A + U// 加法表达式
A -> A - U// 减法表达式
A -> U// 一元表达式
U -> P //基本表达式
P -> identifier// 变量
P -> digit/ 数字
语句:
a = 3;
b = 4;
a = a + b;
b = a - 1;
结果
a = 7
b = 6;
前面没有实现词法分析器,简单用空格分隔,现在实现一个简单的词法分析器
需要能够接受下面的语句
a = 5 ; b = a + 3;b = b + a;
解析为词法符号串
public class Lexical { // 输入 private String input; private Set<String> terminals;// 保留字,终结符号 // 计算用 private char[] arr; private int idx; private List<Character> tmp; // 结果 private List<Symbol> result; public Lexical(Collection<String> terminals, String input) { this.terminals = terminals.stream().collect(Collectors.toSet()); this.input = input; this.result = new ArrayList<>(); } public List<Symbol> parse() { arr = input.toCharArray(); char c; while (idx < arr.length) { c = currCh(); if (Character.isDigit(c)) { parseDigit(); } else if (Character.isLetter(c)) { parseIdentifier(); } else if (Character.isSpaceChar(c)) { nextCh(); } else { StringBuilder sb = new StringBuilder(); sb.append(c); String str = sb.toString(); if (terminals.contains(str)) { result.add(Terminal.of(str)); nextCh(); } else { throw new RuntimeException("非法字符串"); } } } return this.result; } private void nextCh() { idx++; } private char currCh() { return arr[idx]; } public void parseIdentifier() { tmp = new ArrayList<>(); char c; while (idx < arr.length) { c = currCh(); if (Character.isLetter(c)) { tmp.add(c); nextCh(); } else { break; } } String str = tmp.stream().map(String::valueOf).collect(Collectors.joining("")); result.add(Terminal.of("identifier", str)); } public void parseDigit() { tmp = new ArrayList<>(); char c; while (idx < arr.length) { c = currCh(); if (Character.isDigit(c)) { tmp.add(c); nextCh(); } else { break; } } String str = tmp.stream().map(String::valueOf).collect(Collectors.joining("")); result.add(Terminal.of("digit", IntExpression.of(Integer.parseInt(str)))); } }
浙公网安备 33010602011771号