add receive function

This commit is contained in:
Masato Imai
2022-07-19 10:38:15 +09:00
parent 0d51fa958d
commit 30d9d53973
40 changed files with 20 additions and 13668 deletions

View File

@ -1,16 +0,0 @@
{
// IntelliSense を使用して利用可能な属性を学べます。
// 既存の属性の説明をホバーして表示します。
// 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "lldb",
"request": "launch",
"name": "Debug",
"program": "${workspaceFolder}/<your program>",
"args": [],
"cwd": "${workspaceFolder}"
}
]
}

View File

@ -1,10 +0,0 @@
[package]
name = "gpsl"
version = "0.1.0"
authors = ["mii"]
edition = "2018"
[dependencies]
uuid = { version = "0.8.1", features = ["serde", "v4"] }
log = "0.4.0"
env_logger = "0.8.4"

View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2021 mii8080
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1 +0,0 @@
# General Purpose Simple Language

Binary file not shown.

View File

@ -1,29 +0,0 @@
use gpsl::{
vm::gpsl::GPSL,
source::Source,
external_function::*,
tokenizer::Tokenizer,
parser::Parser
};
use std::{fs, env, collections::HashMap};
fn main() {
env::set_var("RUST_LOG", "info");
env_logger::init();
let args: Vec<String> = env::args().collect();
let mut source = Source::new(fs::read_to_string(&(args.last().unwrap())).expect("Cannot read file."));
let mut tokenizer = Tokenizer::new();
tokenizer.tokenize(&mut source).unwrap();
let mut parser = Parser {
tokenizer,
local_vars: HashMap::new()
};
let mut gpsl = GPSL::new(source, Some(parser.functions().unwrap()), vec![STD_FUNC]);
let res = gpsl.run("main".to_string(), vec![]);
if let Err(err) = res {
println!("Error: {:?}", err);
}
}

View File

@ -1,19 +0,0 @@
use std::collections::VecDeque;
fn main() {
println!("testing binary");
let mut queue: VecDeque<i64> = VecDeque::new();
queue.push_back(1i64);
queue.push_back(2i64);
queue.push_back(3i64);
for x in 0..queue.len() {
println!("{}", queue[x]);
}
println!("{:?}", queue);
println!("{:?}", queue.len());
}

View File

@ -1,63 +0,0 @@
use crate::{variable::Variable, permission::Permission};
#[derive(PartialEq)]
pub enum ExternalFuncStatus {
SUCCESS,
NOTFOUND,
ERROR,
REJECTED,
}
pub struct ExternalFuncReturn {
pub status: ExternalFuncStatus,
pub value: Option<Variable>
}
#[allow(dead_code)]
pub const STD_FUNC: fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn = |name, args, accept, reject| {
let name = name.as_str();
match name {
"println" => {
if accept.contains(&Permission::StdIo) && !reject.contains(&Permission::StdIo) {
match &args[0] {
Variable::Text { value } => println!("{}", value),
Variable::Number { value } => println!("{}", value),
_ => {}
}
ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: None
}
} else {
ExternalFuncReturn {
status: ExternalFuncStatus::REJECTED,
value: None
}
}
}
"print" => {
if accept.contains(&Permission::StdIo) && !reject.contains(&Permission::StdIo) {
match &args[0] {
Variable::Text { value } => print!("{}", value),
Variable::Number { value } => print!("{}", value),
_ => {}
}
ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: None
}
} else {
ExternalFuncReturn {
status: ExternalFuncStatus::REJECTED,
value: None
}
}
}
_ => {
ExternalFuncReturn {
status: ExternalFuncStatus::NOTFOUND,
value: None
}
}
}
};

File diff suppressed because one or more lines are too long

View File

@ -1,186 +0,0 @@
// Generated from h:\Git\gpsl\src\grammar\GpslLexer.g4 by ANTLR 4.8
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class GpslLexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.8", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
WS=1, ADD=2, SUB=3, MUL=4, DIV=5, CONJ=6, AND=7, EQ=8, EQEQ=9, NE=10,
BE=11, LE=12, BT=13, LT=14, SEMICOLON=15, COLON=16, COMMA=17, DOT=18,
QUOTE=19, ADD_ASSIGNMENT=20, SUB_ASSIGNMENT=21, MUL_ASSIGNMENT=22, DIV_ASSIGNMENT=23,
LPAREN=24, RPAREN=25, LCURL=26, RCURL=27, ARROW=28, FN=29, FOR=30, WHILE=31,
IF=32, ELSE=33, LET=34, RETURN=35, NUM=36, TEXT=37, IDENT=38;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
public static String[] modeNames = {
"DEFAULT_MODE"
};
private static String[] makeRuleNames() {
return new String[] {
"WS", "ADD", "SUB", "MUL", "DIV", "CONJ", "AND", "EQ", "EQEQ", "NE",
"BE", "LE", "BT", "LT", "SEMICOLON", "COLON", "COMMA", "DOT", "QUOTE",
"ADD_ASSIGNMENT", "SUB_ASSIGNMENT", "MUL_ASSIGNMENT", "DIV_ASSIGNMENT",
"LPAREN", "RPAREN", "LCURL", "RCURL", "ARROW", "FN", "FOR", "WHILE",
"IF", "ELSE", "LET", "RETURN", "NUM", "TEXT", "IDENT"
};
}
public static final String[] ruleNames = makeRuleNames();
private static String[] makeLiteralNames() {
return new String[] {
null, null, "'+'", "'-'", "'*'", "'/'", "'&&'", "'&'", "'='", "'=='",
"'!='", "'>='", "'<='", "'>'", "'<'", "';'", "':'", "','", "'.'", "'\"'",
"'+='", "'-='", "'*='", "'/='", "'('", "')'", "'{'", "'}'", "'->'", "'fn'",
"'for'", "'while'", "'if'", "'else'", "'let'", "'return'"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null, "WS", "ADD", "SUB", "MUL", "DIV", "CONJ", "AND", "EQ", "EQEQ",
"NE", "BE", "LE", "BT", "LT", "SEMICOLON", "COLON", "COMMA", "DOT", "QUOTE",
"ADD_ASSIGNMENT", "SUB_ASSIGNMENT", "MUL_ASSIGNMENT", "DIV_ASSIGNMENT",
"LPAREN", "RPAREN", "LCURL", "RCURL", "ARROW", "FN", "FOR", "WHILE",
"IF", "ELSE", "LET", "RETURN", "NUM", "TEXT", "IDENT"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
public GpslLexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "GpslLexer.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getChannelNames() { return channelNames; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2(\u00c8\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\3\2\3\2\3\2\3\2\3\3\3\3\3"+
"\4\3\4\3\5\3\5\3\6\3\6\3\7\3\7\3\7\3\b\3\b\3\t\3\t\3\n\3\n\3\n\3\13\3"+
"\13\3\13\3\f\3\f\3\f\3\r\3\r\3\r\3\16\3\16\3\17\3\17\3\20\3\20\3\21\3"+
"\21\3\22\3\22\3\23\3\23\3\24\3\24\3\25\3\25\3\25\3\26\3\26\3\26\3\27\3"+
"\27\3\27\3\30\3\30\3\30\3\31\3\31\3\32\3\32\3\33\3\33\3\34\3\34\3\35\3"+
"\35\3\35\3\36\3\36\3\36\3\37\3\37\3\37\3\37\3 \3 \3 \3 \3 \3 \3!\3!\3"+
"!\3\"\3\"\3\"\3\"\3\"\3#\3#\3#\3#\3$\3$\3$\3$\3$\3$\3$\3%\3%\7%\u00b6"+
"\n%\f%\16%\u00b9\13%\3&\3&\7&\u00bd\n&\f&\16&\u00c0\13&\3&\3&\3\'\6\'"+
"\u00c5\n\'\r\'\16\'\u00c6\2\2(\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13"+
"\25\f\27\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61"+
"\32\63\33\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(\3\2\7\5\2\13\f\17\17"+
"\"\"\3\2\63;\3\2\62;\7\2//\62;C\\aac|\5\2C\\aac|\2\u00ca\2\3\3\2\2\2\2"+
"\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2"+
"\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2"+
"\33\3\2\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2"+
"\2\'\3\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2"+
"\2\63\3\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2"+
"\2\2?\3\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2"+
"K\3\2\2\2\2M\3\2\2\2\3O\3\2\2\2\5S\3\2\2\2\7U\3\2\2\2\tW\3\2\2\2\13Y\3"+
"\2\2\2\r[\3\2\2\2\17^\3\2\2\2\21`\3\2\2\2\23b\3\2\2\2\25e\3\2\2\2\27h"+
"\3\2\2\2\31k\3\2\2\2\33n\3\2\2\2\35p\3\2\2\2\37r\3\2\2\2!t\3\2\2\2#v\3"+
"\2\2\2%x\3\2\2\2\'z\3\2\2\2)|\3\2\2\2+\177\3\2\2\2-\u0082\3\2\2\2/\u0085"+
"\3\2\2\2\61\u0088\3\2\2\2\63\u008a\3\2\2\2\65\u008c\3\2\2\2\67\u008e\3"+
"\2\2\29\u0090\3\2\2\2;\u0093\3\2\2\2=\u0096\3\2\2\2?\u009a\3\2\2\2A\u00a0"+
"\3\2\2\2C\u00a3\3\2\2\2E\u00a8\3\2\2\2G\u00ac\3\2\2\2I\u00b3\3\2\2\2K"+
"\u00ba\3\2\2\2M\u00c4\3\2\2\2OP\t\2\2\2PQ\3\2\2\2QR\b\2\2\2R\4\3\2\2\2"+
"ST\7-\2\2T\6\3\2\2\2UV\7/\2\2V\b\3\2\2\2WX\7,\2\2X\n\3\2\2\2YZ\7\61\2"+
"\2Z\f\3\2\2\2[\\\7(\2\2\\]\7(\2\2]\16\3\2\2\2^_\7(\2\2_\20\3\2\2\2`a\7"+
"?\2\2a\22\3\2\2\2bc\7?\2\2cd\7?\2\2d\24\3\2\2\2ef\7#\2\2fg\7?\2\2g\26"+
"\3\2\2\2hi\7@\2\2ij\7?\2\2j\30\3\2\2\2kl\7>\2\2lm\7?\2\2m\32\3\2\2\2n"+
"o\7@\2\2o\34\3\2\2\2pq\7>\2\2q\36\3\2\2\2rs\7=\2\2s \3\2\2\2tu\7<\2\2"+
"u\"\3\2\2\2vw\7.\2\2w$\3\2\2\2xy\7\60\2\2y&\3\2\2\2z{\7$\2\2{(\3\2\2\2"+
"|}\7-\2\2}~\7?\2\2~*\3\2\2\2\177\u0080\7/\2\2\u0080\u0081\7?\2\2\u0081"+
",\3\2\2\2\u0082\u0083\7,\2\2\u0083\u0084\7?\2\2\u0084.\3\2\2\2\u0085\u0086"+
"\7\61\2\2\u0086\u0087\7?\2\2\u0087\60\3\2\2\2\u0088\u0089\7*\2\2\u0089"+
"\62\3\2\2\2\u008a\u008b\7+\2\2\u008b\64\3\2\2\2\u008c\u008d\7}\2\2\u008d"+
"\66\3\2\2\2\u008e\u008f\7\177\2\2\u008f8\3\2\2\2\u0090\u0091\7/\2\2\u0091"+
"\u0092\7@\2\2\u0092:\3\2\2\2\u0093\u0094\7h\2\2\u0094\u0095\7p\2\2\u0095"+
"<\3\2\2\2\u0096\u0097\7h\2\2\u0097\u0098\7q\2\2\u0098\u0099\7t\2\2\u0099"+
">\3\2\2\2\u009a\u009b\7y\2\2\u009b\u009c\7j\2\2\u009c\u009d\7k\2\2\u009d"+
"\u009e\7n\2\2\u009e\u009f\7g\2\2\u009f@\3\2\2\2\u00a0\u00a1\7k\2\2\u00a1"+
"\u00a2\7h\2\2\u00a2B\3\2\2\2\u00a3\u00a4\7g\2\2\u00a4\u00a5\7n\2\2\u00a5"+
"\u00a6\7u\2\2\u00a6\u00a7\7g\2\2\u00a7D\3\2\2\2\u00a8\u00a9\7n\2\2\u00a9"+
"\u00aa\7g\2\2\u00aa\u00ab\7v\2\2\u00abF\3\2\2\2\u00ac\u00ad\7t\2\2\u00ad"+
"\u00ae\7g\2\2\u00ae\u00af\7v\2\2\u00af\u00b0\7w\2\2\u00b0\u00b1\7t\2\2"+
"\u00b1\u00b2\7p\2\2\u00b2H\3\2\2\2\u00b3\u00b7\t\3\2\2\u00b4\u00b6\t\4"+
"\2\2\u00b5\u00b4\3\2\2\2\u00b6\u00b9\3\2\2\2\u00b7\u00b5\3\2\2\2\u00b7"+
"\u00b8\3\2\2\2\u00b8J\3\2\2\2\u00b9\u00b7\3\2\2\2\u00ba\u00be\5\'\24\2"+
"\u00bb\u00bd\t\5\2\2\u00bc\u00bb\3\2\2\2\u00bd\u00c0\3\2\2\2\u00be\u00bc"+
"\3\2\2\2\u00be\u00bf\3\2\2\2\u00bf\u00c1\3\2\2\2\u00c0\u00be\3\2\2\2\u00c1"+
"\u00c2\5\'\24\2\u00c2L\3\2\2\2\u00c3\u00c5\t\6\2\2\u00c4\u00c3\3\2\2\2"+
"\u00c5\u00c6\3\2\2\2\u00c6\u00c4\3\2\2\2\u00c6\u00c7\3\2\2\2\u00c7N\3"+
"\2\2\2\6\2\u00b7\u00be\u00c6\3\b\2\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}

View File

@ -1,72 +0,0 @@
WS=1
ADD=2
SUB=3
MUL=4
DIV=5
CONJ=6
AND=7
EQ=8
EQEQ=9
NE=10
BE=11
LE=12
BT=13
LT=14
SEMICOLON=15
COLON=16
COMMA=17
DOT=18
QUOTE=19
ADD_ASSIGNMENT=20
SUB_ASSIGNMENT=21
MUL_ASSIGNMENT=22
DIV_ASSIGNMENT=23
LPAREN=24
RPAREN=25
LCURL=26
RCURL=27
ARROW=28
FN=29
FOR=30
WHILE=31
IF=32
ELSE=33
LET=34
RETURN=35
NUM=36
TEXT=37
IDENT=38
'+'=2
'-'=3
'*'=4
'/'=5
'&&'=6
'&'=7
'='=8
'=='=9
'!='=10
'>='=11
'<='=12
'>'=13
'<'=14
';'=15
':'=16
','=17
'.'=18
'"'=19
'+='=20
'-='=21
'*='=22
'/='=23
'('=24
')'=25
'{'=26
'}'=27
'->'=28
'fn'=29
'for'=30
'while'=31
'if'=32
'else'=33
'let'=34
'return'=35

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +0,0 @@
WS=1
ADD=2
SUB=3
MUL=4
DIV=5
CONJ=6
AND=7
EQ=8
EQEQ=9
NE=10
BE=11
LE=12
BT=13
LT=14
SEMICOLON=15
COLON=16
COMMA=17
DOT=18
QUOTE=19
ADD_ASSIGNMENT=20
SUB_ASSIGNMENT=21
MUL_ASSIGNMENT=22
DIV_ASSIGNMENT=23
LPAREN=24
RPAREN=25
LCURL=26
RCURL=27
ARROW=28
FN=29
FOR=30
WHILE=31
IF=32
ELSE=33
LET=34
RETURN=35
NUM=36
TEXT=37
IDENT=38
'+'=2
'-'=3
'*'=4
'/'=5
'&&'=6
'&'=7
'='=8
'=='=9
'!='=10
'>='=11
'<='=12
'>'=13
'<'=14
';'=15
':'=16
','=17
'.'=18
'"'=19
'+='=20
'-='=21
'*='=22
'/='=23
'('=24
')'=25
'{'=26
'}'=27
'->'=28
'fn'=29
'for'=30
'while'=31
'if'=32
'else'=33
'let'=34
'return'=35

File diff suppressed because one or more lines are too long

View File

@ -1,181 +0,0 @@
STRING=1
NUMBER=2
INTEGER=3
DEF=4
RETURN=5
RAISE=6
FROM=7
IMPORT=8
AS=9
GLOBAL=10
NONLOCAL=11
ASSERT=12
IF=13
ELIF=14
ELSE=15
WHILE=16
FOR=17
IN=18
TRY=19
FINALLY=20
WITH=21
EXCEPT=22
LAMBDA=23
OR=24
AND=25
NOT=26
IS=27
NONE=28
TRUE=29
FALSE=30
CLASS=31
YIELD=32
DEL=33
PASS=34
CONTINUE=35
BREAK=36
ASYNC=37
AWAIT=38
NEWLINE=39
NAME=40
STRING_LITERAL=41
BYTES_LITERAL=42
DECIMAL_INTEGER=43
OCT_INTEGER=44
HEX_INTEGER=45
BIN_INTEGER=46
FLOAT_NUMBER=47
IMAG_NUMBER=48
DOT=49
ELLIPSIS=50
STAR=51
OPEN_PAREN=52
CLOSE_PAREN=53
COMMA=54
COLON=55
SEMI_COLON=56
POWER=57
ASSIGN=58
OPEN_BRACK=59
CLOSE_BRACK=60
OR_OP=61
XOR=62
AND_OP=63
LEFT_SHIFT=64
RIGHT_SHIFT=65
ADD=66
MINUS=67
DIV=68
MOD=69
IDIV=70
NOT_OP=71
OPEN_BRACE=72
CLOSE_BRACE=73
LESS_THAN=74
GREATER_THAN=75
EQUALS=76
GT_EQ=77
LT_EQ=78
NOT_EQ_1=79
NOT_EQ_2=80
AT=81
ARROW=82
ADD_ASSIGN=83
SUB_ASSIGN=84
MULT_ASSIGN=85
AT_ASSIGN=86
DIV_ASSIGN=87
MOD_ASSIGN=88
AND_ASSIGN=89
OR_ASSIGN=90
XOR_ASSIGN=91
LEFT_SHIFT_ASSIGN=92
RIGHT_SHIFT_ASSIGN=93
POWER_ASSIGN=94
IDIV_ASSIGN=95
SKIP_=96
UNKNOWN_CHAR=97
INDENT=98
DEDENT=99
'def'=4
'return'=5
'raise'=6
'from'=7
'import'=8
'as'=9
'global'=10
'nonlocal'=11
'assert'=12
'if'=13
'elif'=14
'else'=15
'while'=16
'for'=17
'in'=18
'try'=19
'finally'=20
'with'=21
'except'=22
'lambda'=23
'or'=24
'and'=25
'not'=26
'is'=27
'None'=28
'True'=29
'False'=30
'class'=31
'yield'=32
'del'=33
'pass'=34
'continue'=35
'break'=36
'async'=37
'await'=38
'.'=49
'...'=50
'*'=51
'('=52
')'=53
','=54
':'=55
';'=56
'**'=57
'='=58
'['=59
']'=60
'|'=61
'^'=62
'&'=63
'<<'=64
'>>'=65
'+'=66
'-'=67
'/'=68
'%'=69
'//'=70
'~'=71
'{'=72
'}'=73
'<'=74
'>'=75
'=='=76
'>='=77
'<='=78
'<>'=79
'!='=80
'@'=81
'->'=82
'+='=83
'-='=84
'*='=85
'@='=86
'/='=87
'%='=88
'&='=89
'|='=90
'^='=91
'<<='=92
'>>='=93
'**='=94
'//='=95

File diff suppressed because one or more lines are too long

View File

@ -1,770 +0,0 @@
// Generated from h:\Git\gpsl\src\grammar\Python3.g4 by ANTLR 4.8
from antlr4.Token import CommonToken
import re
import importlib
# Allow languages to extend the lexer and parser, by loading the parser dynamically
module_path = __name__[:-5]
language_name = __name__.split('.')[-1]
language_name = language_name[:-5] # Remove Lexer from name
LanguageParser = getattr(importlib.import_module('{}Parser'.format(module_path)), '{}Parser'.format(language_name))
import org.antlr.v4.runtime.Lexer;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.Token;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.atn.*;
import org.antlr.v4.runtime.dfa.DFA;
import org.antlr.v4.runtime.misc.*;
@SuppressWarnings({"all", "warnings", "unchecked", "unused", "cast"})
public class Python3Lexer extends Lexer {
static { RuntimeMetaData.checkVersion("4.8", RuntimeMetaData.VERSION); }
protected static final DFA[] _decisionToDFA;
protected static final PredictionContextCache _sharedContextCache =
new PredictionContextCache();
public static final int
STRING=1, NUMBER=2, INTEGER=3, DEF=4, RETURN=5, RAISE=6, FROM=7, IMPORT=8,
AS=9, GLOBAL=10, NONLOCAL=11, ASSERT=12, IF=13, ELIF=14, ELSE=15, WHILE=16,
FOR=17, IN=18, TRY=19, FINALLY=20, WITH=21, EXCEPT=22, LAMBDA=23, OR=24,
AND=25, NOT=26, IS=27, NONE=28, TRUE=29, FALSE=30, CLASS=31, YIELD=32,
DEL=33, PASS=34, CONTINUE=35, BREAK=36, ASYNC=37, AWAIT=38, NEWLINE=39,
NAME=40, STRING_LITERAL=41, BYTES_LITERAL=42, DECIMAL_INTEGER=43, OCT_INTEGER=44,
HEX_INTEGER=45, BIN_INTEGER=46, FLOAT_NUMBER=47, IMAG_NUMBER=48, DOT=49,
ELLIPSIS=50, STAR=51, OPEN_PAREN=52, CLOSE_PAREN=53, COMMA=54, COLON=55,
SEMI_COLON=56, POWER=57, ASSIGN=58, OPEN_BRACK=59, CLOSE_BRACK=60, OR_OP=61,
XOR=62, AND_OP=63, LEFT_SHIFT=64, RIGHT_SHIFT=65, ADD=66, MINUS=67, DIV=68,
MOD=69, IDIV=70, NOT_OP=71, OPEN_BRACE=72, CLOSE_BRACE=73, LESS_THAN=74,
GREATER_THAN=75, EQUALS=76, GT_EQ=77, LT_EQ=78, NOT_EQ_1=79, NOT_EQ_2=80,
AT=81, ARROW=82, ADD_ASSIGN=83, SUB_ASSIGN=84, MULT_ASSIGN=85, AT_ASSIGN=86,
DIV_ASSIGN=87, MOD_ASSIGN=88, AND_ASSIGN=89, OR_ASSIGN=90, XOR_ASSIGN=91,
LEFT_SHIFT_ASSIGN=92, RIGHT_SHIFT_ASSIGN=93, POWER_ASSIGN=94, IDIV_ASSIGN=95,
SKIP_=96, UNKNOWN_CHAR=97;
public static String[] channelNames = {
"DEFAULT_TOKEN_CHANNEL", "HIDDEN"
};
public static String[] modeNames = {
"DEFAULT_MODE"
};
private static String[] makeRuleNames() {
return new String[] {
"STRING", "NUMBER", "INTEGER", "DEF", "RETURN", "RAISE", "FROM", "IMPORT",
"AS", "GLOBAL", "NONLOCAL", "ASSERT", "IF", "ELIF", "ELSE", "WHILE",
"FOR", "IN", "TRY", "FINALLY", "WITH", "EXCEPT", "LAMBDA", "OR", "AND",
"NOT", "IS", "NONE", "TRUE", "FALSE", "CLASS", "YIELD", "DEL", "PASS",
"CONTINUE", "BREAK", "ASYNC", "AWAIT", "NEWLINE", "NAME", "STRING_LITERAL",
"BYTES_LITERAL", "DECIMAL_INTEGER", "OCT_INTEGER", "HEX_INTEGER", "BIN_INTEGER",
"FLOAT_NUMBER", "IMAG_NUMBER", "DOT", "ELLIPSIS", "STAR", "OPEN_PAREN",
"CLOSE_PAREN", "COMMA", "COLON", "SEMI_COLON", "POWER", "ASSIGN", "OPEN_BRACK",
"CLOSE_BRACK", "OR_OP", "XOR", "AND_OP", "LEFT_SHIFT", "RIGHT_SHIFT",
"ADD", "MINUS", "DIV", "MOD", "IDIV", "NOT_OP", "OPEN_BRACE", "CLOSE_BRACE",
"LESS_THAN", "GREATER_THAN", "EQUALS", "GT_EQ", "LT_EQ", "NOT_EQ_1",
"NOT_EQ_2", "AT", "ARROW", "ADD_ASSIGN", "SUB_ASSIGN", "MULT_ASSIGN",
"AT_ASSIGN", "DIV_ASSIGN", "MOD_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN",
"LEFT_SHIFT_ASSIGN", "RIGHT_SHIFT_ASSIGN", "POWER_ASSIGN", "IDIV_ASSIGN",
"SKIP_", "UNKNOWN_CHAR", "SHORT_STRING", "LONG_STRING", "LONG_STRING_ITEM",
"LONG_STRING_CHAR", "STRING_ESCAPE_SEQ", "NON_ZERO_DIGIT", "DIGIT", "OCT_DIGIT",
"HEX_DIGIT", "BIN_DIGIT", "POINT_FLOAT", "EXPONENT_FLOAT", "INT_PART",
"FRACTION", "EXPONENT", "SHORT_BYTES", "LONG_BYTES", "LONG_BYTES_ITEM",
"SHORT_BYTES_CHAR_NO_SINGLE_QUOTE", "SHORT_BYTES_CHAR_NO_DOUBLE_QUOTE",
"LONG_BYTES_CHAR", "BYTES_ESCAPE_SEQ", "SPACES", "COMMENT", "LINE_JOINING",
"ID_START", "ID_CONTINUE"
};
}
public static final String[] ruleNames = makeRuleNames();
private static String[] makeLiteralNames() {
return new String[] {
null, null, null, null, "'def'", "'return'", "'raise'", "'from'", "'import'",
"'as'", "'global'", "'nonlocal'", "'assert'", "'if'", "'elif'", "'else'",
"'while'", "'for'", "'in'", "'try'", "'finally'", "'with'", "'except'",
"'lambda'", "'or'", "'and'", "'not'", "'is'", "'None'", "'True'", "'False'",
"'class'", "'yield'", "'del'", "'pass'", "'continue'", "'break'", "'async'",
"'await'", null, null, null, null, null, null, null, null, null, null,
"'.'", "'...'", "'*'", "'('", "')'", "','", "':'", "';'", "'**'", "'='",
"'['", "']'", "'|'", "'^'", "'&'", "'<<'", "'>>'", "'+'", "'-'", "'/'",
"'%'", "'//'", "'~'", "'{'", "'}'", "'<'", "'>'", "'=='", "'>='", "'<='",
"'<>'", "'!='", "'@'", "'->'", "'+='", "'-='", "'*='", "'@='", "'/='",
"'%='", "'&='", "'|='", "'^='", "'<<='", "'>>='", "'**='", "'//='"
};
}
private static final String[] _LITERAL_NAMES = makeLiteralNames();
private static String[] makeSymbolicNames() {
return new String[] {
null, "STRING", "NUMBER", "INTEGER", "DEF", "RETURN", "RAISE", "FROM",
"IMPORT", "AS", "GLOBAL", "NONLOCAL", "ASSERT", "IF", "ELIF", "ELSE",
"WHILE", "FOR", "IN", "TRY", "FINALLY", "WITH", "EXCEPT", "LAMBDA", "OR",
"AND", "NOT", "IS", "NONE", "TRUE", "FALSE", "CLASS", "YIELD", "DEL",
"PASS", "CONTINUE", "BREAK", "ASYNC", "AWAIT", "NEWLINE", "NAME", "STRING_LITERAL",
"BYTES_LITERAL", "DECIMAL_INTEGER", "OCT_INTEGER", "HEX_INTEGER", "BIN_INTEGER",
"FLOAT_NUMBER", "IMAG_NUMBER", "DOT", "ELLIPSIS", "STAR", "OPEN_PAREN",
"CLOSE_PAREN", "COMMA", "COLON", "SEMI_COLON", "POWER", "ASSIGN", "OPEN_BRACK",
"CLOSE_BRACK", "OR_OP", "XOR", "AND_OP", "LEFT_SHIFT", "RIGHT_SHIFT",
"ADD", "MINUS", "DIV", "MOD", "IDIV", "NOT_OP", "OPEN_BRACE", "CLOSE_BRACE",
"LESS_THAN", "GREATER_THAN", "EQUALS", "GT_EQ", "LT_EQ", "NOT_EQ_1",
"NOT_EQ_2", "AT", "ARROW", "ADD_ASSIGN", "SUB_ASSIGN", "MULT_ASSIGN",
"AT_ASSIGN", "DIV_ASSIGN", "MOD_ASSIGN", "AND_ASSIGN", "OR_ASSIGN", "XOR_ASSIGN",
"LEFT_SHIFT_ASSIGN", "RIGHT_SHIFT_ASSIGN", "POWER_ASSIGN", "IDIV_ASSIGN",
"SKIP_", "UNKNOWN_CHAR"
};
}
private static final String[] _SYMBOLIC_NAMES = makeSymbolicNames();
public static final Vocabulary VOCABULARY = new VocabularyImpl(_LITERAL_NAMES, _SYMBOLIC_NAMES);
/**
* @deprecated Use {@link #VOCABULARY} instead.
*/
@Deprecated
public static final String[] tokenNames;
static {
tokenNames = new String[_SYMBOLIC_NAMES.length];
for (int i = 0; i < tokenNames.length; i++) {
tokenNames[i] = VOCABULARY.getLiteralName(i);
if (tokenNames[i] == null) {
tokenNames[i] = VOCABULARY.getSymbolicName(i);
}
if (tokenNames[i] == null) {
tokenNames[i] = "<INVALID>";
}
}
}
@Override
@Deprecated
public String[] getTokenNames() {
return tokenNames;
}
@Override
public Vocabulary getVocabulary() {
return VOCABULARY;
}
@property
def tokens(self):
try:
return self._tokens
except AttributeError:
self._tokens = []
return self._tokens
@property
def indents(self):
try:
return self._indents
except AttributeError:
self._indents = []
return self._indents
@property
def opened(self):
try:
return self._opened
except AttributeError:
self._opened = 0
return self._opened
@opened.setter
def opened(self, value):
self._opened = value
@property
def lastToken(self):
try:
return self._lastToken
except AttributeError:
self._lastToken = None
return self._lastToken
@lastToken.setter
def lastToken(self, value):
self._lastToken = value
def reset(self):
super().reset()
self.tokens = []
self.indents = []
self.opened = 0
self.lastToken = None
def emitToken(self, t):
super().emitToken(t)
self.tokens.append(t)
def nextToken(self):
if self._input.LA(1) == Token.EOF and self.indents:
for i in range(len(self.tokens)-1,-1,-1):
if self.tokens[i].type == Token.EOF:
self.tokens.pop(i)
self.emitToken(self.commonToken(LanguageParser.NEWLINE, '\n'))
while self.indents:
self.emitToken(self.createDedent())
self.indents.pop()
self.emitToken(self.commonToken(LanguageParser.EOF, "<EOF>"))
next = super().nextToken()
if next.channel == Token.DEFAULT_CHANNEL:
self.lastToken = next
return next if not self.tokens else self.tokens.pop(0)
def createDedent(self):
dedent = self.commonToken(LanguageParser.DEDENT, "")
dedent.line = self.lastToken.line
return dedent
def commonToken(self, type, text, indent=0):
stop = self.getCharIndex()-1-indent
start = (stop - len(text) + 1) if text else stop
return CommonToken(self._tokenFactorySourcePair, type, super().DEFAULT_TOKEN_CHANNEL, start, stop)
@staticmethod
def getIndentationCount(spaces):
count = 0
for ch in spaces:
if ch == '\t':
count += 8 - (count % 8)
else:
count += 1
return count
def atStartOfInput(self):
return Lexer.column.fget(self) == 0 and Lexer.line.fget(self) == 1
public Python3Lexer(CharStream input) {
super(input);
_interp = new LexerATNSimulator(this,_ATN,_decisionToDFA,_sharedContextCache);
}
@Override
public String getGrammarFileName() { return "Python3.g4"; }
@Override
public String[] getRuleNames() { return ruleNames; }
@Override
public String getSerializedATN() { return _serializedATN; }
@Override
public String[] getChannelNames() { return channelNames; }
@Override
public String[] getModeNames() { return modeNames; }
@Override
public ATN getATN() { return _ATN; }
@Override
public void action(RuleContext _localctx, int ruleIndex, int actionIndex) {
switch (ruleIndex) {
case 38:
NEWLINE_action((RuleContext)_localctx, actionIndex);
break;
case 51:
OPEN_PAREN_action((RuleContext)_localctx, actionIndex);
break;
case 52:
CLOSE_PAREN_action((RuleContext)_localctx, actionIndex);
break;
case 58:
OPEN_BRACK_action((RuleContext)_localctx, actionIndex);
break;
case 59:
CLOSE_BRACK_action((RuleContext)_localctx, actionIndex);
break;
case 71:
OPEN_BRACE_action((RuleContext)_localctx, actionIndex);
break;
case 72:
CLOSE_BRACE_action((RuleContext)_localctx, actionIndex);
break;
}
}
private void NEWLINE_action(RuleContext _localctx, int actionIndex) {
switch (actionIndex) {
case 0:
tempt = Lexer.text.fget(self)
newLine = re.sub("[^\r\n\f]+", "", tempt)
spaces = re.sub("[\r\n\f]+", "", tempt)
la_char = ""
try:
la = self._input.LA(1)
la_char = chr(la) # Python does not compare char to ints directly
except ValueError: # End of file
pass
# Strip newlines inside open clauses except if we are near EOF. We keep NEWLINEs near EOF to
# satisfy the final newline needed by the single_put rule used by the REPL.
try:
nextnext_la = self._input.LA(2)
nextnext_la_char = chr(nextnext_la)
except ValueError:
nextnext_eof = True
else:
nextnext_eof = False
if self.opened > 0 or nextnext_eof is False and (la_char == '\r' or la_char == '\n' or la_char == '\f' or la_char == '#'):
self.skip()
else:
indent = self.getIndentationCount(spaces)
previous = self.indents[-1] if self.indents else 0
self.emitToken(self.commonToken(self.NEWLINE, newLine, indent=indent)) # NEWLINE is actually the '\n' char
if indent == previous:
self.skip()
elif indent > previous:
self.indents.append(indent)
self.emitToken(self.commonToken(LanguageParser.INDENT, spaces))
else:
while self.indents and self.indents[-1] > indent:
self.emitToken(self.createDedent())
self.indents.pop()
break;
}
}
private void OPEN_PAREN_action(RuleContext _localctx, int actionIndex) {
switch (actionIndex) {
case 1:
self.opened += 1
break;
}
}
private void CLOSE_PAREN_action(RuleContext _localctx, int actionIndex) {
switch (actionIndex) {
case 2:
self.opened -= 1
break;
}
}
private void OPEN_BRACK_action(RuleContext _localctx, int actionIndex) {
switch (actionIndex) {
case 3:
self.opened += 1
break;
}
}
private void CLOSE_BRACK_action(RuleContext _localctx, int actionIndex) {
switch (actionIndex) {
case 4:
self.opened -= 1
break;
}
}
private void OPEN_BRACE_action(RuleContext _localctx, int actionIndex) {
switch (actionIndex) {
case 5:
self.opened += 1
break;
}
}
private void CLOSE_BRACE_action(RuleContext _localctx, int actionIndex) {
switch (actionIndex) {
case 6:
self.opened -= 1
break;
}
}
@Override
public boolean sempred(RuleContext _localctx, int ruleIndex, int predIndex) {
switch (ruleIndex) {
case 38:
return NEWLINE_sempred((RuleContext)_localctx, predIndex);
}
return true;
}
private boolean NEWLINE_sempred(RuleContext _localctx, int predIndex) {
switch (predIndex) {
case 0:
return self.atStartOfInput();
}
return true;
}
public static final String _serializedATN =
"\3\u608b\ua72a\u8133\ub9ed\u417c\u3be7\u7786\u5964\2c\u0373\b\1\4\2\t"+
"\2\4\3\t\3\4\4\t\4\4\5\t\5\4\6\t\6\4\7\t\7\4\b\t\b\4\t\t\t\4\n\t\n\4\13"+
"\t\13\4\f\t\f\4\r\t\r\4\16\t\16\4\17\t\17\4\20\t\20\4\21\t\21\4\22\t\22"+
"\4\23\t\23\4\24\t\24\4\25\t\25\4\26\t\26\4\27\t\27\4\30\t\30\4\31\t\31"+
"\4\32\t\32\4\33\t\33\4\34\t\34\4\35\t\35\4\36\t\36\4\37\t\37\4 \t \4!"+
"\t!\4\"\t\"\4#\t#\4$\t$\4%\t%\4&\t&\4\'\t\'\4(\t(\4)\t)\4*\t*\4+\t+\4"+
",\t,\4-\t-\4.\t.\4/\t/\4\60\t\60\4\61\t\61\4\62\t\62\4\63\t\63\4\64\t"+
"\64\4\65\t\65\4\66\t\66\4\67\t\67\48\t8\49\t9\4:\t:\4;\t;\4<\t<\4=\t="+
"\4>\t>\4?\t?\4@\t@\4A\tA\4B\tB\4C\tC\4D\tD\4E\tE\4F\tF\4G\tG\4H\tH\4I"+
"\tI\4J\tJ\4K\tK\4L\tL\4M\tM\4N\tN\4O\tO\4P\tP\4Q\tQ\4R\tR\4S\tS\4T\tT"+
"\4U\tU\4V\tV\4W\tW\4X\tX\4Y\tY\4Z\tZ\4[\t[\4\\\t\\\4]\t]\4^\t^\4_\t_\4"+
"`\t`\4a\ta\4b\tb\4c\tc\4d\td\4e\te\4f\tf\4g\tg\4h\th\4i\ti\4j\tj\4k\t"+
"k\4l\tl\4m\tm\4n\tn\4o\to\4p\tp\4q\tq\4r\tr\4s\ts\4t\tt\4u\tu\4v\tv\4"+
"w\tw\4x\tx\4y\ty\4z\tz\4{\t{\4|\t|\4}\t}\3\2\3\2\5\2\u00fe\n\2\3\3\3\3"+
"\3\3\5\3\u0103\n\3\3\4\3\4\3\4\3\4\5\4\u0109\n\4\3\5\3\5\3\5\3\5\3\6\3"+
"\6\3\6\3\6\3\6\3\6\3\6\3\7\3\7\3\7\3\7\3\7\3\7\3\b\3\b\3\b\3\b\3\b\3\t"+
"\3\t\3\t\3\t\3\t\3\t\3\t\3\n\3\n\3\n\3\13\3\13\3\13\3\13\3\13\3\13\3\13"+
"\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\f\3\r\3\r\3\r\3\r\3\r\3\r\3\r\3\16"+
"\3\16\3\16\3\17\3\17\3\17\3\17\3\17\3\20\3\20\3\20\3\20\3\20\3\21\3\21"+
"\3\21\3\21\3\21\3\21\3\22\3\22\3\22\3\22\3\23\3\23\3\23\3\24\3\24\3\24"+
"\3\24\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\25\3\26\3\26\3\26\3\26\3\26"+
"\3\27\3\27\3\27\3\27\3\27\3\27\3\27\3\30\3\30\3\30\3\30\3\30\3\30\3\30"+
"\3\31\3\31\3\31\3\32\3\32\3\32\3\32\3\33\3\33\3\33\3\33\3\34\3\34\3\34"+
"\3\35\3\35\3\35\3\35\3\35\3\36\3\36\3\36\3\36\3\36\3\37\3\37\3\37\3\37"+
"\3\37\3\37\3 \3 \3 \3 \3 \3 \3!\3!\3!\3!\3!\3!\3\"\3\"\3\"\3\"\3#\3#\3"+
"#\3#\3#\3$\3$\3$\3$\3$\3$\3$\3$\3$\3%\3%\3%\3%\3%\3%\3&\3&\3&\3&\3&\3"+
"&\3\'\3\'\3\'\3\'\3\'\3\'\3(\3(\3(\5(\u01cc\n(\3(\3(\5(\u01d0\n(\3(\5"+
"(\u01d3\n(\5(\u01d5\n(\3(\3(\3)\3)\7)\u01db\n)\f)\16)\u01de\13)\3*\3*"+
"\3*\3*\3*\5*\u01e5\n*\3*\3*\5*\u01e9\n*\3+\3+\3+\3+\3+\5+\u01f0\n+\3+"+
"\3+\5+\u01f4\n+\3,\3,\7,\u01f8\n,\f,\16,\u01fb\13,\3,\6,\u01fe\n,\r,\16"+
",\u01ff\5,\u0202\n,\3-\3-\3-\6-\u0207\n-\r-\16-\u0208\3.\3.\3.\6.\u020e"+
"\n.\r.\16.\u020f\3/\3/\3/\6/\u0215\n/\r/\16/\u0216\3\60\3\60\5\60\u021b"+
"\n\60\3\61\3\61\5\61\u021f\n\61\3\61\3\61\3\62\3\62\3\63\3\63\3\63\3\63"+
"\3\64\3\64\3\65\3\65\3\65\3\66\3\66\3\66\3\67\3\67\38\38\39\39\3:\3:\3"+
":\3;\3;\3<\3<\3<\3=\3=\3=\3>\3>\3?\3?\3@\3@\3A\3A\3A\3B\3B\3B\3C\3C\3"+
"D\3D\3E\3E\3F\3F\3G\3G\3G\3H\3H\3I\3I\3I\3J\3J\3J\3K\3K\3L\3L\3M\3M\3"+
"M\3N\3N\3N\3O\3O\3O\3P\3P\3P\3Q\3Q\3Q\3R\3R\3S\3S\3S\3T\3T\3T\3U\3U\3"+
"U\3V\3V\3V\3W\3W\3W\3X\3X\3X\3Y\3Y\3Y\3Z\3Z\3Z\3[\3[\3[\3\\\3\\\3\\\3"+
"]\3]\3]\3]\3^\3^\3^\3^\3_\3_\3_\3_\3`\3`\3`\3`\3a\3a\3a\5a\u02a7\na\3"+
"a\3a\3b\3b\3c\3c\3c\7c\u02b0\nc\fc\16c\u02b3\13c\3c\3c\3c\3c\7c\u02b9"+
"\nc\fc\16c\u02bc\13c\3c\5c\u02bf\nc\3d\3d\3d\3d\3d\7d\u02c6\nd\fd\16d"+
"\u02c9\13d\3d\3d\3d\3d\3d\3d\3d\3d\7d\u02d3\nd\fd\16d\u02d6\13d\3d\3d"+
"\3d\5d\u02db\nd\3e\3e\5e\u02df\ne\3f\3f\3g\3g\3g\3g\5g\u02e7\ng\3h\3h"+
"\3i\3i\3j\3j\3k\3k\3l\3l\3m\5m\u02f4\nm\3m\3m\3m\3m\5m\u02fa\nm\3n\3n"+
"\5n\u02fe\nn\3n\3n\3o\6o\u0303\no\ro\16o\u0304\3p\3p\6p\u0309\np\rp\16"+
"p\u030a\3q\3q\5q\u030f\nq\3q\6q\u0312\nq\rq\16q\u0313\3r\3r\3r\7r\u0319"+
"\nr\fr\16r\u031c\13r\3r\3r\3r\3r\7r\u0322\nr\fr\16r\u0325\13r\3r\5r\u0328"+
"\nr\3s\3s\3s\3s\3s\7s\u032f\ns\fs\16s\u0332\13s\3s\3s\3s\3s\3s\3s\3s\3"+
"s\7s\u033c\ns\fs\16s\u033f\13s\3s\3s\3s\5s\u0344\ns\3t\3t\5t\u0348\nt"+
"\3u\5u\u034b\nu\3v\5v\u034e\nv\3w\5w\u0351\nw\3x\3x\3x\3y\6y\u0357\ny"+
"\ry\16y\u0358\3z\3z\7z\u035d\nz\fz\16z\u0360\13z\3{\3{\5{\u0364\n{\3{"+
"\5{\u0367\n{\3{\3{\5{\u036b\n{\3|\5|\u036e\n|\3}\3}\5}\u0372\n}\6\u02c7"+
"\u02d4\u0330\u033d\2~\3\3\5\4\7\5\t\6\13\7\r\b\17\t\21\n\23\13\25\f\27"+
"\r\31\16\33\17\35\20\37\21!\22#\23%\24\'\25)\26+\27-\30/\31\61\32\63\33"+
"\65\34\67\359\36;\37= ?!A\"C#E$G%I&K\'M(O)Q*S+U,W-Y.[/]\60_\61a\62c\63"+
"e\64g\65i\66k\67m8o9q:s;u<w=y>{?}@\177A\u0081B\u0083C\u0085D\u0087E\u0089"+
"F\u008bG\u008dH\u008fI\u0091J\u0093K\u0095L\u0097M\u0099N\u009bO\u009d"+
"P\u009fQ\u00a1R\u00a3S\u00a5T\u00a7U\u00a9V\u00abW\u00adX\u00afY\u00b1"+
"Z\u00b3[\u00b5\\\u00b7]\u00b9^\u00bb_\u00bd`\u00bfa\u00c1b\u00c3c\u00c5"+
"\2\u00c7\2\u00c9\2\u00cb\2\u00cd\2\u00cf\2\u00d1\2\u00d3\2\u00d5\2\u00d7"+
"\2\u00d9\2\u00db\2\u00dd\2\u00df\2\u00e1\2\u00e3\2\u00e5\2\u00e7\2\u00e9"+
"\2\u00eb\2\u00ed\2\u00ef\2\u00f1\2\u00f3\2\u00f5\2\u00f7\2\u00f9\2\3\2"+
"\33\b\2HHTTWWhhttww\4\2HHhh\4\2TTtt\4\2DDdd\4\2QQqq\4\2ZZzz\4\2LLll\6"+
"\2\f\f\16\17))^^\6\2\f\f\16\17$$^^\3\2^^\3\2\63;\3\2\62;\3\2\629\5\2\62"+
";CHch\3\2\62\63\4\2GGgg\4\2--//\7\2\2\13\r\16\20(*]_\u0081\7\2\2\13\r"+
"\16\20#%]_\u0081\4\2\2]_\u0081\3\2\2\u0081\4\2\13\13\"\"\4\2\f\f\16\17"+
"\u0129\2C\\aac|\u00ac\u00ac\u00b7\u00b7\u00bc\u00bc\u00c2\u00d8\u00da"+
"\u00f8\u00fa\u0243\u0252\u02c3\u02c8\u02d3\u02e2\u02e6\u02f0\u02f0\u037c"+
"\u037c\u0388\u0388\u038a\u038c\u038e\u038e\u0390\u03a3\u03a5\u03d0\u03d2"+
"\u03f7\u03f9\u0483\u048c\u04d0\u04d2\u04fb\u0502\u0511\u0533\u0558\u055b"+
"\u055b\u0563\u0589\u05d2\u05ec\u05f2\u05f4\u0623\u063c\u0642\u064c\u0670"+
"\u0671\u0673\u06d5\u06d7\u06d7\u06e7\u06e8\u06f0\u06f1\u06fc\u06fe\u0701"+
"\u0701\u0712\u0712\u0714\u0731\u074f\u076f\u0782\u07a7\u07b3\u07b3\u0906"+
"\u093b\u093f\u093f\u0952\u0952\u095a\u0963\u097f\u097f\u0987\u098e\u0991"+
"\u0992\u0995\u09aa\u09ac\u09b2\u09b4\u09b4\u09b8\u09bb\u09bf\u09bf\u09d0"+
"\u09d0\u09de\u09df\u09e1\u09e3\u09f2\u09f3\u0a07\u0a0c\u0a11\u0a12\u0a15"+
"\u0a2a\u0a2c\u0a32\u0a34\u0a35\u0a37\u0a38\u0a3a\u0a3b\u0a5b\u0a5e\u0a60"+
"\u0a60\u0a74\u0a76\u0a87\u0a8f\u0a91\u0a93\u0a95\u0aaa\u0aac\u0ab2\u0ab4"+
"\u0ab5\u0ab7\u0abb\u0abf\u0abf\u0ad2\u0ad2\u0ae2\u0ae3\u0b07\u0b0e\u0b11"+
"\u0b12\u0b15\u0b2a\u0b2c\u0b32\u0b34\u0b35\u0b37\u0b3b\u0b3f\u0b3f\u0b5e"+
"\u0b5f\u0b61\u0b63\u0b73\u0b73\u0b85\u0b85\u0b87\u0b8c\u0b90\u0b92\u0b94"+
"\u0b97\u0b9b\u0b9c\u0b9e\u0b9e\u0ba0\u0ba1\u0ba5\u0ba6\u0baa\u0bac\u0bb0"+
"\u0bbb\u0c07\u0c0e\u0c10\u0c12\u0c14\u0c2a\u0c2c\u0c35\u0c37\u0c3b\u0c62"+
"\u0c63\u0c87\u0c8e\u0c90\u0c92\u0c94\u0caa\u0cac\u0cb5\u0cb7\u0cbb\u0cbf"+
"\u0cbf\u0ce0\u0ce0\u0ce2\u0ce3\u0d07\u0d0e\u0d10\u0d12\u0d14\u0d2a\u0d2c"+
"\u0d3b\u0d62\u0d63\u0d87\u0d98\u0d9c\u0db3\u0db5\u0dbd\u0dbf\u0dbf\u0dc2"+
"\u0dc8\u0e03\u0e32\u0e34\u0e35\u0e42\u0e48\u0e83\u0e84\u0e86\u0e86\u0e89"+
"\u0e8a\u0e8c\u0e8c\u0e8f\u0e8f\u0e96\u0e99\u0e9b\u0ea1\u0ea3\u0ea5\u0ea7"+
"\u0ea7\u0ea9\u0ea9\u0eac\u0ead\u0eaf\u0eb2\u0eb4\u0eb5\u0ebf\u0ebf\u0ec2"+
"\u0ec6\u0ec8\u0ec8\u0ede\u0edf\u0f02\u0f02\u0f42\u0f49\u0f4b\u0f6c\u0f8a"+
"\u0f8d\u1002\u1023\u1025\u1029\u102b\u102c\u1052\u1057\u10a2\u10c7\u10d2"+
"\u10fc\u10fe\u10fe\u1102\u115b\u1161\u11a4\u11aa\u11fb\u1202\u124a\u124c"+
"\u124f\u1252\u1258\u125a\u125a\u125c\u125f\u1262\u128a\u128c\u128f\u1292"+
"\u12b2\u12b4\u12b7\u12ba\u12c0\u12c2\u12c2\u12c4\u12c7\u12ca\u12d8\u12da"+
"\u1312\u1314\u1317\u131a\u135c\u1382\u1391\u13a2\u13f6\u1403\u166e\u1671"+
"\u1678\u1683\u169c\u16a2\u16ec\u16f0\u16f2\u1702\u170e\u1710\u1713\u1722"+
"\u1733\u1742\u1753\u1762\u176e\u1770\u1772\u1782\u17b5\u17d9\u17d9\u17de"+
"\u17de\u1822\u1879\u1882\u18aa\u1902\u191e\u1952\u196f\u1972\u1976\u1982"+
"\u19ab\u19c3\u19c9\u1a02\u1a18\u1d02\u1dc1\u1e02\u1e9d\u1ea2\u1efb\u1f02"+
"\u1f17\u1f1a\u1f1f\u1f22\u1f47\u1f4a\u1f4f\u1f52\u1f59\u1f5b\u1f5b\u1f5d"+
"\u1f5d\u1f5f\u1f5f\u1f61\u1f7f\u1f82\u1fb6\u1fb8\u1fbe\u1fc0\u1fc0\u1fc4"+
"\u1fc6\u1fc8\u1fce\u1fd2\u1fd5\u1fd8\u1fdd\u1fe2\u1fee\u1ff4\u1ff6\u1ff8"+
"\u1ffe\u2073\u2073\u2081\u2081\u2092\u2096\u2104\u2104\u2109\u2109\u210c"+
"\u2115\u2117\u2117\u211a\u211f\u2126\u2126\u2128\u2128\u212a\u212a\u212c"+
"\u2133\u2135\u213b\u213e\u2141\u2147\u214b\u2162\u2185\u2c02\u2c30\u2c32"+
"\u2c60\u2c82\u2ce6\u2d02\u2d27\u2d32\u2d67\u2d71\u2d71\u2d82\u2d98\u2da2"+
"\u2da8\u2daa\u2db0\u2db2\u2db8\u2dba\u2dc0\u2dc2\u2dc8\u2dca\u2dd0\u2dd2"+
"\u2dd8\u2dda\u2de0\u3007\u3009\u3023\u302b\u3033\u3037\u303a\u303e\u3043"+
"\u3098\u309d\u30a1\u30a3\u30fc\u30fe\u3101\u3107\u312e\u3133\u3190\u31a2"+
"\u31b9\u31f2\u3201\u3402\u4db7\u4e02\u9fbd\ua002\ua48e\ua802\ua803\ua805"+
"\ua807\ua809\ua80c\ua80e\ua824\uac02\ud7a5\uf902\ufa2f\ufa32\ufa6c\ufa72"+
"\ufadb\ufb02\ufb08\ufb15\ufb19\ufb1f\ufb1f\ufb21\ufb2a\ufb2c\ufb38\ufb3a"+
"\ufb3e\ufb40\ufb40\ufb42\ufb43\ufb45\ufb46\ufb48\ufbb3\ufbd5\ufd3f\ufd52"+
"\ufd91\ufd94\ufdc9\ufdf2\ufdfd\ufe72\ufe76\ufe78\ufefe\uff23\uff3c\uff43"+
"\uff5c\uff68\uffc0\uffc4\uffc9\uffcc\uffd1\uffd4\uffd9\uffdc\uffde\u0096"+
"\2\62;\u0302\u0371\u0485\u0488\u0593\u05bb\u05bd\u05bf\u05c1\u05c1\u05c3"+
"\u05c4\u05c6\u05c7\u05c9\u05c9\u0612\u0617\u064d\u0660\u0662\u066b\u0672"+
"\u0672\u06d8\u06de\u06e1\u06e6\u06e9\u06ea\u06ec\u06ef\u06f2\u06fb\u0713"+
"\u0713\u0732\u074c\u07a8\u07b2\u0903\u0905\u093e\u093e\u0940\u094f\u0953"+
"\u0956\u0964\u0965\u0968\u0971\u0983\u0985\u09be\u09be\u09c0\u09c6\u09c9"+
"\u09ca\u09cd\u09cf\u09d9\u09d9\u09e4\u09e5\u09e8\u09f1\u0a03\u0a05\u0a3e"+
"\u0a3e\u0a40\u0a44\u0a49\u0a4a\u0a4d\u0a4f\u0a68\u0a73\u0a83\u0a85\u0abe"+
"\u0abe\u0ac0\u0ac7\u0ac9\u0acb\u0acd\u0acf\u0ae4\u0ae5\u0ae8\u0af1\u0b03"+
"\u0b05\u0b3e\u0b3e\u0b40\u0b45\u0b49\u0b4a\u0b4d\u0b4f\u0b58\u0b59\u0b68"+
"\u0b71\u0b84\u0b84\u0bc0\u0bc4\u0bc8\u0bca\u0bcc\u0bcf\u0bd9\u0bd9\u0be8"+
"\u0bf1\u0c03\u0c05\u0c40\u0c46\u0c48\u0c4a\u0c4c\u0c4f\u0c57\u0c58\u0c68"+
"\u0c71\u0c84\u0c85\u0cbe\u0cbe\u0cc0\u0cc6\u0cc8\u0cca\u0ccc\u0ccf\u0cd7"+
"\u0cd8\u0ce8\u0cf1\u0d04\u0d05\u0d40\u0d45\u0d48\u0d4a\u0d4c\u0d4f\u0d59"+
"\u0d59\u0d68\u0d71\u0d84\u0d85\u0dcc\u0dcc\u0dd1\u0dd6\u0dd8\u0dd8\u0dda"+
"\u0de1\u0df4\u0df5\u0e33\u0e33\u0e36\u0e3c\u0e49\u0e50\u0e52\u0e5b\u0eb3"+
"\u0eb3\u0eb6\u0ebb\u0ebd\u0ebe\u0eca\u0ecf\u0ed2\u0edb\u0f1a\u0f1b\u0f22"+
"\u0f2b\u0f37\u0f37\u0f39\u0f39\u0f3b\u0f3b\u0f40\u0f41\u0f73\u0f86\u0f88"+
"\u0f89\u0f92\u0f99\u0f9b\u0fbe\u0fc8\u0fc8\u102e\u1034\u1038\u103b\u1042"+
"\u104b\u1058\u105b\u1361\u1361\u136b\u1373\u1714\u1716\u1734\u1736\u1754"+
"\u1755\u1774\u1775\u17b8\u17d5\u17df\u17df\u17e2\u17eb\u180d\u180f\u1812"+
"\u181b\u18ab\u18ab\u1922\u192d\u1932\u193d\u1948\u1951\u19b2\u19c2\u19ca"+
"\u19cb\u19d2\u19db\u1a19\u1a1d\u1dc2\u1dc5\u2041\u2042\u2056\u2056\u20d2"+
"\u20de\u20e3\u20e3\u20e7\u20ed\u302c\u3031\u309b\u309c\ua804\ua804\ua808"+
"\ua808\ua80d\ua80d\ua825\ua829\ufb20\ufb20\ufe02\ufe11\ufe22\ufe25\ufe35"+
"\ufe36\ufe4f\ufe51\uff12\uff1b\uff41\uff41\2\u0393\2\3\3\2\2\2\2\5\3\2"+
"\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2\2\2\2\21"+
"\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2\2\33\3\2"+
"\2\2\2\35\3\2\2\2\2\37\3\2\2\2\2!\3\2\2\2\2#\3\2\2\2\2%\3\2\2\2\2\'\3"+
"\2\2\2\2)\3\2\2\2\2+\3\2\2\2\2-\3\2\2\2\2/\3\2\2\2\2\61\3\2\2\2\2\63\3"+
"\2\2\2\2\65\3\2\2\2\2\67\3\2\2\2\29\3\2\2\2\2;\3\2\2\2\2=\3\2\2\2\2?\3"+
"\2\2\2\2A\3\2\2\2\2C\3\2\2\2\2E\3\2\2\2\2G\3\2\2\2\2I\3\2\2\2\2K\3\2\2"+
"\2\2M\3\2\2\2\2O\3\2\2\2\2Q\3\2\2\2\2S\3\2\2\2\2U\3\2\2\2\2W\3\2\2\2\2"+
"Y\3\2\2\2\2[\3\2\2\2\2]\3\2\2\2\2_\3\2\2\2\2a\3\2\2\2\2c\3\2\2\2\2e\3"+
"\2\2\2\2g\3\2\2\2\2i\3\2\2\2\2k\3\2\2\2\2m\3\2\2\2\2o\3\2\2\2\2q\3\2\2"+
"\2\2s\3\2\2\2\2u\3\2\2\2\2w\3\2\2\2\2y\3\2\2\2\2{\3\2\2\2\2}\3\2\2\2\2"+
"\177\3\2\2\2\2\u0081\3\2\2\2\2\u0083\3\2\2\2\2\u0085\3\2\2\2\2\u0087\3"+
"\2\2\2\2\u0089\3\2\2\2\2\u008b\3\2\2\2\2\u008d\3\2\2\2\2\u008f\3\2\2\2"+
"\2\u0091\3\2\2\2\2\u0093\3\2\2\2\2\u0095\3\2\2\2\2\u0097\3\2\2\2\2\u0099"+
"\3\2\2\2\2\u009b\3\2\2\2\2\u009d\3\2\2\2\2\u009f\3\2\2\2\2\u00a1\3\2\2"+
"\2\2\u00a3\3\2\2\2\2\u00a5\3\2\2\2\2\u00a7\3\2\2\2\2\u00a9\3\2\2\2\2\u00ab"+
"\3\2\2\2\2\u00ad\3\2\2\2\2\u00af\3\2\2\2\2\u00b1\3\2\2\2\2\u00b3\3\2\2"+
"\2\2\u00b5\3\2\2\2\2\u00b7\3\2\2\2\2\u00b9\3\2\2\2\2\u00bb\3\2\2\2\2\u00bd"+
"\3\2\2\2\2\u00bf\3\2\2\2\2\u00c1\3\2\2\2\2\u00c3\3\2\2\2\3\u00fd\3\2\2"+
"\2\5\u0102\3\2\2\2\7\u0108\3\2\2\2\t\u010a\3\2\2\2\13\u010e\3\2\2\2\r"+
"\u0115\3\2\2\2\17\u011b\3\2\2\2\21\u0120\3\2\2\2\23\u0127\3\2\2\2\25\u012a"+
"\3\2\2\2\27\u0131\3\2\2\2\31\u013a\3\2\2\2\33\u0141\3\2\2\2\35\u0144\3"+
"\2\2\2\37\u0149\3\2\2\2!\u014e\3\2\2\2#\u0154\3\2\2\2%\u0158\3\2\2\2\'"+
"\u015b\3\2\2\2)\u015f\3\2\2\2+\u0167\3\2\2\2-\u016c\3\2\2\2/\u0173\3\2"+
"\2\2\61\u017a\3\2\2\2\63\u017d\3\2\2\2\65\u0181\3\2\2\2\67\u0185\3\2\2"+
"\29\u0188\3\2\2\2;\u018d\3\2\2\2=\u0192\3\2\2\2?\u0198\3\2\2\2A\u019e"+
"\3\2\2\2C\u01a4\3\2\2\2E\u01a8\3\2\2\2G\u01ad\3\2\2\2I\u01b6\3\2\2\2K"+
"\u01bc\3\2\2\2M\u01c2\3\2\2\2O\u01d4\3\2\2\2Q\u01d8\3\2\2\2S\u01e4\3\2"+
"\2\2U\u01ef\3\2\2\2W\u0201\3\2\2\2Y\u0203\3\2\2\2[\u020a\3\2\2\2]\u0211"+
"\3\2\2\2_\u021a\3\2\2\2a\u021e\3\2\2\2c\u0222\3\2\2\2e\u0224\3\2\2\2g"+
"\u0228\3\2\2\2i\u022a\3\2\2\2k\u022d\3\2\2\2m\u0230\3\2\2\2o\u0232\3\2"+
"\2\2q\u0234\3\2\2\2s\u0236\3\2\2\2u\u0239\3\2\2\2w\u023b\3\2\2\2y\u023e"+
"\3\2\2\2{\u0241\3\2\2\2}\u0243\3\2\2\2\177\u0245\3\2\2\2\u0081\u0247\3"+
"\2\2\2\u0083\u024a\3\2\2\2\u0085\u024d\3\2\2\2\u0087\u024f\3\2\2\2\u0089"+
"\u0251\3\2\2\2\u008b\u0253\3\2\2\2\u008d\u0255\3\2\2\2\u008f\u0258\3\2"+
"\2\2\u0091\u025a\3\2\2\2\u0093\u025d\3\2\2\2\u0095\u0260\3\2\2\2\u0097"+
"\u0262\3\2\2\2\u0099\u0264\3\2\2\2\u009b\u0267\3\2\2\2\u009d\u026a\3\2"+
"\2\2\u009f\u026d\3\2\2\2\u00a1\u0270\3\2\2\2\u00a3\u0273\3\2\2\2\u00a5"+
"\u0275\3\2\2\2\u00a7\u0278\3\2\2\2\u00a9\u027b\3\2\2\2\u00ab\u027e\3\2"+
"\2\2\u00ad\u0281\3\2\2\2\u00af\u0284\3\2\2\2\u00b1\u0287\3\2\2\2\u00b3"+
"\u028a\3\2\2\2\u00b5\u028d\3\2\2\2\u00b7\u0290\3\2\2\2\u00b9\u0293\3\2"+
"\2\2\u00bb\u0297\3\2\2\2\u00bd\u029b\3\2\2\2\u00bf\u029f\3\2\2\2\u00c1"+
"\u02a6\3\2\2\2\u00c3\u02aa\3\2\2\2\u00c5\u02be\3\2\2\2\u00c7\u02da\3\2"+
"\2\2\u00c9\u02de\3\2\2\2\u00cb\u02e0\3\2\2\2\u00cd\u02e6\3\2\2\2\u00cf"+
"\u02e8\3\2\2\2\u00d1\u02ea\3\2\2\2\u00d3\u02ec\3\2\2\2\u00d5\u02ee\3\2"+
"\2\2\u00d7\u02f0\3\2\2\2\u00d9\u02f9\3\2\2\2\u00db\u02fd\3\2\2\2\u00dd"+
"\u0302\3\2\2\2\u00df\u0306\3\2\2\2\u00e1\u030c\3\2\2\2\u00e3\u0327\3\2"+
"\2\2\u00e5\u0343\3\2\2\2\u00e7\u0347\3\2\2\2\u00e9\u034a\3\2\2\2\u00eb"+
"\u034d\3\2\2\2\u00ed\u0350\3\2\2\2\u00ef\u0352\3\2\2\2\u00f1\u0356\3\2"+
"\2\2\u00f3\u035a\3\2\2\2\u00f5\u0361\3\2\2\2\u00f7\u036d\3\2\2\2\u00f9"+
"\u0371\3\2\2\2\u00fb\u00fe\5S*\2\u00fc\u00fe\5U+\2\u00fd\u00fb\3\2\2\2"+
"\u00fd\u00fc\3\2\2\2\u00fe\4\3\2\2\2\u00ff\u0103\5\7\4\2\u0100\u0103\5"+
"_\60\2\u0101\u0103\5a\61\2\u0102\u00ff\3\2\2\2\u0102\u0100\3\2\2\2\u0102"+
"\u0101\3\2\2\2\u0103\6\3\2\2\2\u0104\u0109\5W,\2\u0105\u0109\5Y-\2\u0106"+
"\u0109\5[.\2\u0107\u0109\5]/\2\u0108\u0104\3\2\2\2\u0108\u0105\3\2\2\2"+
"\u0108\u0106\3\2\2\2\u0108\u0107\3\2\2\2\u0109\b\3\2\2\2\u010a\u010b\7"+
"f\2\2\u010b\u010c\7g\2\2\u010c\u010d\7h\2\2\u010d\n\3\2\2\2\u010e\u010f"+
"\7t\2\2\u010f\u0110\7g\2\2\u0110\u0111\7v\2\2\u0111\u0112\7w\2\2\u0112"+
"\u0113\7t\2\2\u0113\u0114\7p\2\2\u0114\f\3\2\2\2\u0115\u0116\7t\2\2\u0116"+
"\u0117\7c\2\2\u0117\u0118\7k\2\2\u0118\u0119\7u\2\2\u0119\u011a\7g\2\2"+
"\u011a\16\3\2\2\2\u011b\u011c\7h\2\2\u011c\u011d\7t\2\2\u011d\u011e\7"+
"q\2\2\u011e\u011f\7o\2\2\u011f\20\3\2\2\2\u0120\u0121\7k\2\2\u0121\u0122"+
"\7o\2\2\u0122\u0123\7r\2\2\u0123\u0124\7q\2\2\u0124\u0125\7t\2\2\u0125"+
"\u0126\7v\2\2\u0126\22\3\2\2\2\u0127\u0128\7c\2\2\u0128\u0129\7u\2\2\u0129"+
"\24\3\2\2\2\u012a\u012b\7i\2\2\u012b\u012c\7n\2\2\u012c\u012d\7q\2\2\u012d"+
"\u012e\7d\2\2\u012e\u012f\7c\2\2\u012f\u0130\7n\2\2\u0130\26\3\2\2\2\u0131"+
"\u0132\7p\2\2\u0132\u0133\7q\2\2\u0133\u0134\7p\2\2\u0134\u0135\7n\2\2"+
"\u0135\u0136\7q\2\2\u0136\u0137\7e\2\2\u0137\u0138\7c\2\2\u0138\u0139"+
"\7n\2\2\u0139\30\3\2\2\2\u013a\u013b\7c\2\2\u013b\u013c\7u\2\2\u013c\u013d"+
"\7u\2\2\u013d\u013e\7g\2\2\u013e\u013f\7t\2\2\u013f\u0140\7v\2\2\u0140"+
"\32\3\2\2\2\u0141\u0142\7k\2\2\u0142\u0143\7h\2\2\u0143\34\3\2\2\2\u0144"+
"\u0145\7g\2\2\u0145\u0146\7n\2\2\u0146\u0147\7k\2\2\u0147\u0148\7h\2\2"+
"\u0148\36\3\2\2\2\u0149\u014a\7g\2\2\u014a\u014b\7n\2\2\u014b\u014c\7"+
"u\2\2\u014c\u014d\7g\2\2\u014d \3\2\2\2\u014e\u014f\7y\2\2\u014f\u0150"+
"\7j\2\2\u0150\u0151\7k\2\2\u0151\u0152\7n\2\2\u0152\u0153\7g\2\2\u0153"+
"\"\3\2\2\2\u0154\u0155\7h\2\2\u0155\u0156\7q\2\2\u0156\u0157\7t\2\2\u0157"+
"$\3\2\2\2\u0158\u0159\7k\2\2\u0159\u015a\7p\2\2\u015a&\3\2\2\2\u015b\u015c"+
"\7v\2\2\u015c\u015d\7t\2\2\u015d\u015e\7{\2\2\u015e(\3\2\2\2\u015f\u0160"+
"\7h\2\2\u0160\u0161\7k\2\2\u0161\u0162\7p\2\2\u0162\u0163\7c\2\2\u0163"+
"\u0164\7n\2\2\u0164\u0165\7n\2\2\u0165\u0166\7{\2\2\u0166*\3\2\2\2\u0167"+
"\u0168\7y\2\2\u0168\u0169\7k\2\2\u0169\u016a\7v\2\2\u016a\u016b\7j\2\2"+
"\u016b,\3\2\2\2\u016c\u016d\7g\2\2\u016d\u016e\7z\2\2\u016e\u016f\7e\2"+
"\2\u016f\u0170\7g\2\2\u0170\u0171\7r\2\2\u0171\u0172\7v\2\2\u0172.\3\2"+
"\2\2\u0173\u0174\7n\2\2\u0174\u0175\7c\2\2\u0175\u0176\7o\2\2\u0176\u0177"+
"\7d\2\2\u0177\u0178\7f\2\2\u0178\u0179\7c\2\2\u0179\60\3\2\2\2\u017a\u017b"+
"\7q\2\2\u017b\u017c\7t\2\2\u017c\62\3\2\2\2\u017d\u017e\7c\2\2\u017e\u017f"+
"\7p\2\2\u017f\u0180\7f\2\2\u0180\64\3\2\2\2\u0181\u0182\7p\2\2\u0182\u0183"+
"\7q\2\2\u0183\u0184\7v\2\2\u0184\66\3\2\2\2\u0185\u0186\7k\2\2\u0186\u0187"+
"\7u\2\2\u01878\3\2\2\2\u0188\u0189\7P\2\2\u0189\u018a\7q\2\2\u018a\u018b"+
"\7p\2\2\u018b\u018c\7g\2\2\u018c:\3\2\2\2\u018d\u018e\7V\2\2\u018e\u018f"+
"\7t\2\2\u018f\u0190\7w\2\2\u0190\u0191\7g\2\2\u0191<\3\2\2\2\u0192\u0193"+
"\7H\2\2\u0193\u0194\7c\2\2\u0194\u0195\7n\2\2\u0195\u0196\7u\2\2\u0196"+
"\u0197\7g\2\2\u0197>\3\2\2\2\u0198\u0199\7e\2\2\u0199\u019a\7n\2\2\u019a"+
"\u019b\7c\2\2\u019b\u019c\7u\2\2\u019c\u019d\7u\2\2\u019d@\3\2\2\2\u019e"+
"\u019f\7{\2\2\u019f\u01a0\7k\2\2\u01a0\u01a1\7g\2\2\u01a1\u01a2\7n\2\2"+
"\u01a2\u01a3\7f\2\2\u01a3B\3\2\2\2\u01a4\u01a5\7f\2\2\u01a5\u01a6\7g\2"+
"\2\u01a6\u01a7\7n\2\2\u01a7D\3\2\2\2\u01a8\u01a9\7r\2\2\u01a9\u01aa\7"+
"c\2\2\u01aa\u01ab\7u\2\2\u01ab\u01ac\7u\2\2\u01acF\3\2\2\2\u01ad\u01ae"+
"\7e\2\2\u01ae\u01af\7q\2\2\u01af\u01b0\7p\2\2\u01b0\u01b1\7v\2\2\u01b1"+
"\u01b2\7k\2\2\u01b2\u01b3\7p\2\2\u01b3\u01b4\7w\2\2\u01b4\u01b5\7g\2\2"+
"\u01b5H\3\2\2\2\u01b6\u01b7\7d\2\2\u01b7\u01b8\7t\2\2\u01b8\u01b9\7g\2"+
"\2\u01b9\u01ba\7c\2\2\u01ba\u01bb\7m\2\2\u01bbJ\3\2\2\2\u01bc\u01bd\7"+
"c\2\2\u01bd\u01be\7u\2\2\u01be\u01bf\7{\2\2\u01bf\u01c0\7p\2\2\u01c0\u01c1"+
"\7e\2\2\u01c1L\3\2\2\2\u01c2\u01c3\7c\2\2\u01c3\u01c4\7y\2\2\u01c4\u01c5"+
"\7c\2\2\u01c5\u01c6\7k\2\2\u01c6\u01c7\7v\2\2\u01c7N\3\2\2\2\u01c8\u01c9"+
"\6(\2\2\u01c9\u01d5\5\u00f1y\2\u01ca\u01cc\7\17\2\2\u01cb\u01ca\3\2\2"+
"\2\u01cb\u01cc\3\2\2\2\u01cc\u01cd\3\2\2\2\u01cd\u01d0\7\f\2\2\u01ce\u01d0"+
"\4\16\17\2\u01cf\u01cb\3\2\2\2\u01cf\u01ce\3\2\2\2\u01d0\u01d2\3\2\2\2"+
"\u01d1\u01d3\5\u00f1y\2\u01d2\u01d1\3\2\2\2\u01d2\u01d3\3\2\2\2\u01d3"+
"\u01d5\3\2\2\2\u01d4\u01c8\3\2\2\2\u01d4\u01cf\3\2\2\2\u01d5\u01d6\3\2"+
"\2\2\u01d6\u01d7\b(\2\2\u01d7P\3\2\2\2\u01d8\u01dc\5\u00f7|\2\u01d9\u01db"+
"\5\u00f9}\2\u01da\u01d9\3\2\2\2\u01db\u01de\3\2\2\2\u01dc\u01da\3\2\2"+
"\2\u01dc\u01dd\3\2\2\2\u01ddR\3\2\2\2\u01de\u01dc\3\2\2\2\u01df\u01e5"+
"\t\2\2\2\u01e0\u01e1\t\3\2\2\u01e1\u01e5\t\4\2\2\u01e2\u01e3\t\4\2\2\u01e3"+
"\u01e5\t\3\2\2\u01e4\u01df\3\2\2\2\u01e4\u01e0\3\2\2\2\u01e4\u01e2\3\2"+
"\2\2\u01e4\u01e5\3\2\2\2\u01e5\u01e8\3\2\2\2\u01e6\u01e9\5\u00c5c\2\u01e7"+
"\u01e9\5\u00c7d\2\u01e8\u01e6\3\2\2\2\u01e8\u01e7\3\2\2\2\u01e9T\3\2\2"+
"\2\u01ea\u01f0\t\5\2\2\u01eb\u01ec\t\5\2\2\u01ec\u01f0\t\4\2\2\u01ed\u01ee"+
"\t\4\2\2\u01ee\u01f0\t\5\2\2\u01ef\u01ea\3\2\2\2\u01ef\u01eb\3\2\2\2\u01ef"+
"\u01ed\3\2\2\2\u01f0\u01f3\3\2\2\2\u01f1\u01f4\5\u00e3r\2\u01f2\u01f4"+
"\5\u00e5s\2\u01f3\u01f1\3\2\2\2\u01f3\u01f2\3\2\2\2\u01f4V\3\2\2\2\u01f5"+
"\u01f9\5\u00cfh\2\u01f6\u01f8\5\u00d1i\2\u01f7\u01f6\3\2\2\2\u01f8\u01fb"+
"\3\2\2\2\u01f9\u01f7\3\2\2\2\u01f9\u01fa\3\2\2\2\u01fa\u0202\3\2\2\2\u01fb"+
"\u01f9\3\2\2\2\u01fc\u01fe\7\62\2\2\u01fd\u01fc\3\2\2\2\u01fe\u01ff\3"+
"\2\2\2\u01ff\u01fd\3\2\2\2\u01ff\u0200\3\2\2\2\u0200\u0202\3\2\2\2\u0201"+
"\u01f5\3\2\2\2\u0201\u01fd\3\2\2\2\u0202X\3\2\2\2\u0203\u0204\7\62\2\2"+
"\u0204\u0206\t\6\2\2\u0205\u0207\5\u00d3j\2\u0206\u0205\3\2\2\2\u0207"+
"\u0208\3\2\2\2\u0208\u0206\3\2\2\2\u0208\u0209\3\2\2\2\u0209Z\3\2\2\2"+
"\u020a\u020b\7\62\2\2\u020b\u020d\t\7\2\2\u020c\u020e\5\u00d5k\2\u020d"+
"\u020c\3\2\2\2\u020e\u020f\3\2\2\2\u020f\u020d\3\2\2\2\u020f\u0210\3\2"+
"\2\2\u0210\\\3\2\2\2\u0211\u0212\7\62\2\2\u0212\u0214\t\5\2\2\u0213\u0215"+
"\5\u00d7l\2\u0214\u0213\3\2\2\2\u0215\u0216\3\2\2\2\u0216\u0214\3\2\2"+
"\2\u0216\u0217\3\2\2\2\u0217^\3\2\2\2\u0218\u021b\5\u00d9m\2\u0219\u021b"+
"\5\u00dbn\2\u021a\u0218\3\2\2\2\u021a\u0219\3\2\2\2\u021b`\3\2\2\2\u021c"+
"\u021f\5_\60\2\u021d\u021f\5\u00ddo\2\u021e\u021c\3\2\2\2\u021e\u021d"+
"\3\2\2\2\u021f\u0220\3\2\2\2\u0220\u0221\t\b\2\2\u0221b\3\2\2\2\u0222"+
"\u0223\7\60\2\2\u0223d\3\2\2\2\u0224\u0225\7\60\2\2\u0225\u0226\7\60\2"+
"\2\u0226\u0227\7\60\2\2\u0227f\3\2\2\2\u0228\u0229\7,\2\2\u0229h\3\2\2"+
"\2\u022a\u022b\7*\2\2\u022b\u022c\b\65\3\2\u022cj\3\2\2\2\u022d\u022e"+
"\7+\2\2\u022e\u022f\b\66\4\2\u022fl\3\2\2\2\u0230\u0231\7.\2\2\u0231n"+
"\3\2\2\2\u0232\u0233\7<\2\2\u0233p\3\2\2\2\u0234\u0235\7=\2\2\u0235r\3"+
"\2\2\2\u0236\u0237\7,\2\2\u0237\u0238\7,\2\2\u0238t\3\2\2\2\u0239\u023a"+
"\7?\2\2\u023av\3\2\2\2\u023b\u023c\7]\2\2\u023c\u023d\b<\5\2\u023dx\3"+
"\2\2\2\u023e\u023f\7_\2\2\u023f\u0240\b=\6\2\u0240z\3\2\2\2\u0241\u0242"+
"\7~\2\2\u0242|\3\2\2\2\u0243\u0244\7`\2\2\u0244~\3\2\2\2\u0245\u0246\7"+
"(\2\2\u0246\u0080\3\2\2\2\u0247\u0248\7>\2\2\u0248\u0249\7>\2\2\u0249"+
"\u0082\3\2\2\2\u024a\u024b\7@\2\2\u024b\u024c\7@\2\2\u024c\u0084\3\2\2"+
"\2\u024d\u024e\7-\2\2\u024e\u0086\3\2\2\2\u024f\u0250\7/\2\2\u0250\u0088"+
"\3\2\2\2\u0251\u0252\7\61\2\2\u0252\u008a\3\2\2\2\u0253\u0254\7\'\2\2"+
"\u0254\u008c\3\2\2\2\u0255\u0256\7\61\2\2\u0256\u0257\7\61\2\2\u0257\u008e"+
"\3\2\2\2\u0258\u0259\7\u0080\2\2\u0259\u0090\3\2\2\2\u025a\u025b\7}\2"+
"\2\u025b\u025c\bI\7\2\u025c\u0092\3\2\2\2\u025d\u025e\7\177\2\2\u025e"+
"\u025f\bJ\b\2\u025f\u0094\3\2\2\2\u0260\u0261\7>\2\2\u0261\u0096\3\2\2"+
"\2\u0262\u0263\7@\2\2\u0263\u0098\3\2\2\2\u0264\u0265\7?\2\2\u0265\u0266"+
"\7?\2\2\u0266\u009a\3\2\2\2\u0267\u0268\7@\2\2\u0268\u0269\7?\2\2\u0269"+
"\u009c\3\2\2\2\u026a\u026b\7>\2\2\u026b\u026c\7?\2\2\u026c\u009e\3\2\2"+
"\2\u026d\u026e\7>\2\2\u026e\u026f\7@\2\2\u026f\u00a0\3\2\2\2\u0270\u0271"+
"\7#\2\2\u0271\u0272\7?\2\2\u0272\u00a2\3\2\2\2\u0273\u0274\7B\2\2\u0274"+
"\u00a4\3\2\2\2\u0275\u0276\7/\2\2\u0276\u0277\7@\2\2\u0277\u00a6\3\2\2"+
"\2\u0278\u0279\7-\2\2\u0279\u027a\7?\2\2\u027a\u00a8\3\2\2\2\u027b\u027c"+
"\7/\2\2\u027c\u027d\7?\2\2\u027d\u00aa\3\2\2\2\u027e\u027f\7,\2\2\u027f"+
"\u0280\7?\2\2\u0280\u00ac\3\2\2\2\u0281\u0282\7B\2\2\u0282\u0283\7?\2"+
"\2\u0283\u00ae\3\2\2\2\u0284\u0285\7\61\2\2\u0285\u0286\7?\2\2\u0286\u00b0"+
"\3\2\2\2\u0287\u0288\7\'\2\2\u0288\u0289\7?\2\2\u0289\u00b2\3\2\2\2\u028a"+
"\u028b\7(\2\2\u028b\u028c\7?\2\2\u028c\u00b4\3\2\2\2\u028d\u028e\7~\2"+
"\2\u028e\u028f\7?\2\2\u028f\u00b6\3\2\2\2\u0290\u0291\7`\2\2\u0291\u0292"+
"\7?\2\2\u0292\u00b8\3\2\2\2\u0293\u0294\7>\2\2\u0294\u0295\7>\2\2\u0295"+
"\u0296\7?\2\2\u0296\u00ba\3\2\2\2\u0297\u0298\7@\2\2\u0298\u0299\7@\2"+
"\2\u0299\u029a\7?\2\2\u029a\u00bc\3\2\2\2\u029b\u029c\7,\2\2\u029c\u029d"+
"\7,\2\2\u029d\u029e\7?\2\2\u029e\u00be\3\2\2\2\u029f\u02a0\7\61\2\2\u02a0"+
"\u02a1\7\61\2\2\u02a1\u02a2\7?\2\2\u02a2\u00c0\3\2\2\2\u02a3\u02a7\5\u00f1"+
"y\2\u02a4\u02a7\5\u00f3z\2\u02a5\u02a7\5\u00f5{\2\u02a6\u02a3\3\2\2\2"+
"\u02a6\u02a4\3\2\2\2\u02a6\u02a5\3\2\2\2\u02a7\u02a8\3\2\2\2\u02a8\u02a9"+
"\ba\t\2\u02a9\u00c2\3\2\2\2\u02aa\u02ab\13\2\2\2\u02ab\u00c4\3\2\2\2\u02ac"+
"\u02b1\7)\2\2\u02ad\u02b0\5\u00cdg\2\u02ae\u02b0\n\t\2\2\u02af\u02ad\3"+
"\2\2\2\u02af\u02ae\3\2\2\2\u02b0\u02b3\3\2\2\2\u02b1\u02af\3\2\2\2\u02b1"+
"\u02b2\3\2\2\2\u02b2\u02b4\3\2\2\2\u02b3\u02b1\3\2\2\2\u02b4\u02bf\7)"+
"\2\2\u02b5\u02ba\7$\2\2\u02b6\u02b9\5\u00cdg\2\u02b7\u02b9\n\n\2\2\u02b8"+
"\u02b6\3\2\2\2\u02b8\u02b7\3\2\2\2\u02b9\u02bc\3\2\2\2\u02ba\u02b8\3\2"+
"\2\2\u02ba\u02bb\3\2\2\2\u02bb\u02bd\3\2\2\2\u02bc\u02ba\3\2\2\2\u02bd"+
"\u02bf\7$\2\2\u02be\u02ac\3\2\2\2\u02be\u02b5\3\2\2\2\u02bf\u00c6\3\2"+
"\2\2\u02c0\u02c1\7)\2\2\u02c1\u02c2\7)\2\2\u02c2\u02c3\7)\2\2\u02c3\u02c7"+
"\3\2\2\2\u02c4\u02c6\5\u00c9e\2\u02c5\u02c4\3\2\2\2\u02c6\u02c9\3\2\2"+
"\2\u02c7\u02c8\3\2\2\2\u02c7\u02c5\3\2\2\2\u02c8\u02ca\3\2\2\2\u02c9\u02c7"+
"\3\2\2\2\u02ca\u02cb\7)\2\2\u02cb\u02cc\7)\2\2\u02cc\u02db\7)\2\2\u02cd"+
"\u02ce\7$\2\2\u02ce\u02cf\7$\2\2\u02cf\u02d0\7$\2\2\u02d0\u02d4\3\2\2"+
"\2\u02d1\u02d3\5\u00c9e\2\u02d2\u02d1\3\2\2\2\u02d3\u02d6\3\2\2\2\u02d4"+
"\u02d5\3\2\2\2\u02d4\u02d2\3\2\2\2\u02d5\u02d7\3\2\2\2\u02d6\u02d4\3\2"+
"\2\2\u02d7\u02d8\7$\2\2\u02d8\u02d9\7$\2\2\u02d9\u02db\7$\2\2\u02da\u02c0"+
"\3\2\2\2\u02da\u02cd\3\2\2\2\u02db\u00c8\3\2\2\2\u02dc\u02df\5\u00cbf"+
"\2\u02dd\u02df\5\u00cdg\2\u02de\u02dc\3\2\2\2\u02de\u02dd\3\2\2\2\u02df"+
"\u00ca\3\2\2\2\u02e0\u02e1\n\13\2\2\u02e1\u00cc\3\2\2\2\u02e2\u02e3\7"+
"^\2\2\u02e3\u02e7\13\2\2\2\u02e4\u02e5\7^\2\2\u02e5\u02e7\5O(\2\u02e6"+
"\u02e2\3\2\2\2\u02e6\u02e4\3\2\2\2\u02e7\u00ce\3\2\2\2\u02e8\u02e9\t\f"+
"\2\2\u02e9\u00d0\3\2\2\2\u02ea\u02eb\t\r\2\2\u02eb\u00d2\3\2\2\2\u02ec"+
"\u02ed\t\16\2\2\u02ed\u00d4\3\2\2\2\u02ee\u02ef\t\17\2\2\u02ef\u00d6\3"+
"\2\2\2\u02f0\u02f1\t\20\2\2\u02f1\u00d8\3\2\2\2\u02f2\u02f4\5\u00ddo\2"+
"\u02f3\u02f2\3\2\2\2\u02f3\u02f4\3\2\2\2\u02f4\u02f5\3\2\2\2\u02f5\u02fa"+
"\5\u00dfp\2\u02f6\u02f7\5\u00ddo\2\u02f7\u02f8\7\60\2\2\u02f8\u02fa\3"+
"\2\2\2\u02f9\u02f3\3\2\2\2\u02f9\u02f6\3\2\2\2\u02fa\u00da\3\2\2\2\u02fb"+
"\u02fe\5\u00ddo\2\u02fc\u02fe\5\u00d9m\2\u02fd\u02fb\3\2\2\2\u02fd\u02fc"+
"\3\2\2\2\u02fe\u02ff\3\2\2\2\u02ff\u0300\5\u00e1q\2\u0300\u00dc\3\2\2"+
"\2\u0301\u0303\5\u00d1i\2\u0302\u0301\3\2\2\2\u0303\u0304\3\2\2\2\u0304"+
"\u0302\3\2\2\2\u0304\u0305\3\2\2\2\u0305\u00de\3\2\2\2\u0306\u0308\7\60"+
"\2\2\u0307\u0309\5\u00d1i\2\u0308\u0307\3\2\2\2\u0309\u030a\3\2\2\2\u030a"+
"\u0308\3\2\2\2\u030a\u030b\3\2\2\2\u030b\u00e0\3\2\2\2\u030c\u030e\t\21"+
"\2\2\u030d\u030f\t\22\2\2\u030e\u030d\3\2\2\2\u030e\u030f\3\2\2\2\u030f"+
"\u0311\3\2\2\2\u0310\u0312\5\u00d1i\2\u0311\u0310\3\2\2\2\u0312\u0313"+
"\3\2\2\2\u0313\u0311\3\2\2\2\u0313\u0314\3\2\2\2\u0314\u00e2\3\2\2\2\u0315"+
"\u031a\7)\2\2\u0316\u0319\5\u00e9u\2\u0317\u0319\5\u00efx\2\u0318\u0316"+
"\3\2\2\2\u0318\u0317\3\2\2\2\u0319\u031c\3\2\2\2\u031a\u0318\3\2\2\2\u031a"+
"\u031b\3\2\2\2\u031b\u031d\3\2\2\2\u031c\u031a\3\2\2\2\u031d\u0328\7)"+
"\2\2\u031e\u0323\7$\2\2\u031f\u0322\5\u00ebv\2\u0320\u0322\5\u00efx\2"+
"\u0321\u031f\3\2\2\2\u0321\u0320\3\2\2\2\u0322\u0325\3\2\2\2\u0323\u0321"+
"\3\2\2\2\u0323\u0324\3\2\2\2\u0324\u0326\3\2\2\2\u0325\u0323\3\2\2\2\u0326"+
"\u0328\7$\2\2\u0327\u0315\3\2\2\2\u0327\u031e\3\2\2\2\u0328\u00e4\3\2"+
"\2\2\u0329\u032a\7)\2\2\u032a\u032b\7)\2\2\u032b\u032c\7)\2\2\u032c\u0330"+
"\3\2\2\2\u032d\u032f\5\u00e7t\2\u032e\u032d\3\2\2\2\u032f\u0332\3\2\2"+
"\2\u0330\u0331\3\2\2\2\u0330\u032e\3\2\2\2\u0331\u0333\3\2\2\2\u0332\u0330"+
"\3\2\2\2\u0333\u0334\7)\2\2\u0334\u0335\7)\2\2\u0335\u0344\7)\2\2\u0336"+
"\u0337\7$\2\2\u0337\u0338\7$\2\2\u0338\u0339\7$\2\2\u0339\u033d\3\2\2"+
"\2\u033a\u033c\5\u00e7t\2\u033b\u033a\3\2\2\2\u033c\u033f\3\2\2\2\u033d"+
"\u033e\3\2\2\2\u033d\u033b\3\2\2\2\u033e\u0340\3\2\2\2\u033f\u033d\3\2"+
"\2\2\u0340\u0341\7$\2\2\u0341\u0342\7$\2\2\u0342\u0344\7$\2\2\u0343\u0329"+
"\3\2\2\2\u0343\u0336\3\2\2\2\u0344\u00e6\3\2\2\2\u0345\u0348\5\u00edw"+
"\2\u0346\u0348\5\u00efx\2\u0347\u0345\3\2\2\2\u0347\u0346\3\2\2\2\u0348"+
"\u00e8\3\2\2\2\u0349\u034b\t\23\2\2\u034a\u0349\3\2\2\2\u034b\u00ea\3"+
"\2\2\2\u034c\u034e\t\24\2\2\u034d\u034c\3\2\2\2\u034e\u00ec\3\2\2\2\u034f"+
"\u0351\t\25\2\2\u0350\u034f\3\2\2\2\u0351\u00ee\3\2\2\2\u0352\u0353\7"+
"^\2\2\u0353\u0354\t\26\2\2\u0354\u00f0\3\2\2\2\u0355\u0357\t\27\2\2\u0356"+
"\u0355\3\2\2\2\u0357\u0358\3\2\2\2\u0358\u0356\3\2\2\2\u0358\u0359\3\2"+
"\2\2\u0359\u00f2\3\2\2\2\u035a\u035e\7%\2\2\u035b\u035d\n\30\2\2\u035c"+
"\u035b\3\2\2\2\u035d\u0360\3\2\2\2\u035e\u035c\3\2\2\2\u035e\u035f\3\2"+
"\2\2\u035f\u00f4\3\2\2\2\u0360\u035e\3\2\2\2\u0361\u0363\7^\2\2\u0362"+
"\u0364\5\u00f1y\2\u0363\u0362\3\2\2\2\u0363\u0364\3\2\2\2\u0364\u036a"+
"\3\2\2\2\u0365\u0367\7\17\2\2\u0366\u0365\3\2\2\2\u0366\u0367\3\2\2\2"+
"\u0367\u0368\3\2\2\2\u0368\u036b\7\f\2\2\u0369\u036b\4\16\17\2\u036a\u0366"+
"\3\2\2\2\u036a\u0369\3\2\2\2\u036b\u00f6\3\2\2\2\u036c\u036e\t\31\2\2"+
"\u036d\u036c\3\2\2\2\u036e\u00f8\3\2\2\2\u036f\u0372\5\u00f7|\2\u0370"+
"\u0372\t\32\2\2\u0371\u036f\3\2\2\2\u0371\u0370\3\2\2\2\u0372\u00fa\3"+
"\2\2\2<\2\u00fd\u0102\u0108\u01cb\u01cf\u01d2\u01d4\u01dc\u01e4\u01e8"+
"\u01ef\u01f3\u01f9\u01ff\u0201\u0208\u020f\u0216\u021a\u021e\u02a6\u02af"+
"\u02b1\u02b8\u02ba\u02be\u02c7\u02d4\u02da\u02de\u02e6\u02f3\u02f9\u02fd"+
"\u0304\u030a\u030e\u0313\u0318\u031a\u0321\u0323\u0327\u0330\u033d\u0343"+
"\u0347\u034a\u034d\u0350\u0358\u035e\u0363\u0366\u036a\u036d\u0371\n\3"+
"(\2\3\65\3\3\66\4\3<\5\3=\6\3I\7\3J\b\b\2\2";
public static final ATN _ATN =
new ATNDeserializer().deserialize(_serializedATN.toCharArray());
static {
_decisionToDFA = new DFA[_ATN.getNumberOfDecisions()];
for (int i = 0; i < _ATN.getNumberOfDecisions(); i++) {
_decisionToDFA[i] = new DFA(_ATN.getDecisionState(i), i);
}
}
}

View File

@ -1,179 +0,0 @@
STRING=1
NUMBER=2
INTEGER=3
DEF=4
RETURN=5
RAISE=6
FROM=7
IMPORT=8
AS=9
GLOBAL=10
NONLOCAL=11
ASSERT=12
IF=13
ELIF=14
ELSE=15
WHILE=16
FOR=17
IN=18
TRY=19
FINALLY=20
WITH=21
EXCEPT=22
LAMBDA=23
OR=24
AND=25
NOT=26
IS=27
NONE=28
TRUE=29
FALSE=30
CLASS=31
YIELD=32
DEL=33
PASS=34
CONTINUE=35
BREAK=36
ASYNC=37
AWAIT=38
NEWLINE=39
NAME=40
STRING_LITERAL=41
BYTES_LITERAL=42
DECIMAL_INTEGER=43
OCT_INTEGER=44
HEX_INTEGER=45
BIN_INTEGER=46
FLOAT_NUMBER=47
IMAG_NUMBER=48
DOT=49
ELLIPSIS=50
STAR=51
OPEN_PAREN=52
CLOSE_PAREN=53
COMMA=54
COLON=55
SEMI_COLON=56
POWER=57
ASSIGN=58
OPEN_BRACK=59
CLOSE_BRACK=60
OR_OP=61
XOR=62
AND_OP=63
LEFT_SHIFT=64
RIGHT_SHIFT=65
ADD=66
MINUS=67
DIV=68
MOD=69
IDIV=70
NOT_OP=71
OPEN_BRACE=72
CLOSE_BRACE=73
LESS_THAN=74
GREATER_THAN=75
EQUALS=76
GT_EQ=77
LT_EQ=78
NOT_EQ_1=79
NOT_EQ_2=80
AT=81
ARROW=82
ADD_ASSIGN=83
SUB_ASSIGN=84
MULT_ASSIGN=85
AT_ASSIGN=86
DIV_ASSIGN=87
MOD_ASSIGN=88
AND_ASSIGN=89
OR_ASSIGN=90
XOR_ASSIGN=91
LEFT_SHIFT_ASSIGN=92
RIGHT_SHIFT_ASSIGN=93
POWER_ASSIGN=94
IDIV_ASSIGN=95
SKIP_=96
UNKNOWN_CHAR=97
'def'=4
'return'=5
'raise'=6
'from'=7
'import'=8
'as'=9
'global'=10
'nonlocal'=11
'assert'=12
'if'=13
'elif'=14
'else'=15
'while'=16
'for'=17
'in'=18
'try'=19
'finally'=20
'with'=21
'except'=22
'lambda'=23
'or'=24
'and'=25
'not'=26
'is'=27
'None'=28
'True'=29
'False'=30
'class'=31
'yield'=32
'del'=33
'pass'=34
'continue'=35
'break'=36
'async'=37
'await'=38
'.'=49
'...'=50
'*'=51
'('=52
')'=53
','=54
':'=55
';'=56
'**'=57
'='=58
'['=59
']'=60
'|'=61
'^'=62
'&'=63
'<<'=64
'>>'=65
'+'=66
'-'=67
'/'=68
'%'=69
'//'=70
'~'=71
'{'=72
'}'=73
'<'=74
'>'=75
'=='=76
'>='=77
'<='=78
'<>'=79
'!='=80
'@'=81
'->'=82
'+='=83
'-='=84
'*='=85
'@='=86
'/='=87
'%='=88
'&='=89
'|='=90
'^='=91
'<<='=92
'>>='=93
'**='=94
'//='=95

File diff suppressed because it is too large Load Diff

View File

@ -1,51 +0,0 @@
lexer grammar GpslLexer;
WS
: [ \t\r\n]
-> skip
;
SHARP: '#' ;
DOLLER: '$' ;
ADD: '+' ;
SUB: '-' ;
MUL: '*' ;
DIV: '/' ;
CONJ: '&&' ;
AND: '&' ;
EQ: '=' ;
EQEQ: '==' ;
NE: '!=' ;
BE: '>=' ;
LE: '<=' ;
BT: '>' ;
LT: '<' ;
SEMICOLON: ';' ;
COLON: ':' ;
COMMA: ',' ;
DOT: '.' ;
QUOTE: '"' ;
ADD_ASSIGNMENT: '+=' ;
SUB_ASSIGNMENT: '-=' ;
MUL_ASSIGNMENT: '*=' ;
DIV_ASSIGNMENT: '/=' ;
LPAREN: '(' ;
RPAREN: ')' ;
LCURL: '{' ;
RCURL: '}' ;
LBRACKET: '[' ;
RBRACKET: ']' ;
ARROW: '->' ;
FN: 'fn' ;
FOR: 'for' ;
WHILE: 'while' ;
IF: 'if' ;
ELSE: 'else' ;
LET: 'let' ;
RETURN: 'return' ;
NUM: [1-9] [0-9]* ;
TEXT: QUOTE [a-zA-Z0-9_-]* QUOTE ;
IDENT: [a-zA-Z_]+ ;

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 49 KiB

View File

@ -1,42 +0,0 @@
parser grammar GpslParser;
options { tokenVocab = GpslLexer; }
gpslFile: function* EOF ;
function: FN IDENT LPAREN (IDENT COLON IDENT COMMA?)* RPAREN (ARROW IDENT)? block ;
program: stmt* ;
stmt: let
| block
| return
| if
| while
| for
| expr SEMICOLON
;
let: LET IDENT COLON IDENT SEMICOLON ;
block: permission? LCURL stmt* RCURL ;
return: RETURN expr? SEMICOLON ;
if: IF LPAREN expr RPAREN stmt (ELSE stmt)? ;
while: WHILE LPAREN expr RPAREN stmt ;
for: FOR LPAREN expr? SEMICOLON expr? SEMICOLON expr? RPAREN stmt ;
mode: SHARP IDENT ;
permission: DOLLER LPAREN ( IDENT LBRACKET ( IDENT COMMA? )* RBRACKET COMMA? )* RPAREN ;
expr: assign ;
assign: equality (EQ assign)? ;
equality: relational (EQEQ relational | NE relational | CONJ)* ;
relational: add (LE add | LT add | BE add | BT add)* ;
add: mul (ADD mul | SUB mul | SUB_ASSIGNMENT mul | ADD_ASSIGNMENT mul)* ;
mul: unary (MUL unary | DIV unary | DIV_ASSIGNMENT unary | MUL_ASSIGNMENT unary)* ;
primary: LPAREN expr RPAREN | function_call | TEXT | NUM ;
function_call: IDENT LPAREN (unary COMMA?)* RPAREN ;
unary: ADD primary
| SUB primary
| primary
;

File diff suppressed because one or more lines are too long

View File

@ -1,242 +0,0 @@
/*
* This file contains all default CSS rules for the dark vscode them, used for various diagrams and graphs.
* Use the "antlr4.customcss" setting in vscode to specify your own file, if you like to override some rules.
*
* Usually most of the appearance is defined in light.css and here we only have some adjustments for
* the dark theme.
*/
body.vscode-dark svg {
background: rgba(255, 255, 255, 0.05);
}
/* ATN graphs. */
body.vscode-dark .marker {
fill: #eee;
stroke: none;
}
body.vscode-dark .stateLabel {
fill: #202020;
}
body.vscode-dark .stateTypeLabel {
fill: #404040;
}
body.vscode-dark .linkLabel {
fill: #ddd;
}
body.vscode-dark .state {
stroke: white;
filter: url(#white-glow);
}
/* Railroad diagrams */
body.vscode-dark .atn-graph-save-image {
background: rgba(206, 11, 70, 1) url('../misc/save-dark.png');
}
body.vscode-dark .rrd-save-image {
background: rgba(10, 188, 80, 1) url('../misc/save-dark.png');
}
body.vscode-dark .call-graph-save-image {
background: rgba(255, 191, 15, 1) url('../misc/save-dark.png');
}
body.vscode-dark .parse-tree-save-image {
background: rgba(49, 112, 212, 1) url('../misc/save-dark.png');
}
body.vscode-dark svg.railroad-diagram path {
/* The connection lines. */
stroke-width: 2;
stroke: darkgray;
fill: rgba(0, 0, 0, 0);
}
body.vscode-dark svg.railroad-diagram text {
/* All text except comments. */
font: bold 12px Hack, "Source Code Pro", monospace;
text-anchor: middle;
fill: #404040;
/* Use fill instead of color for svg text. */
}
body.vscode-dark svg.railroad-diagram text.comment {
/* Comment text */
font: italic 10px Hack, "Source Code Pro", monospace;
fill: #909090;
}
body.vscode-dark svg.railroad-diagram g.non-terminal rect {
/* The non-terminal boxes. */
stroke-width: 2;
stroke: #404040;
fill: rgba(255, 255, 255, 1);
}
body.vscode-dark svg.railroad-diagram g.terminal rect {
/* The terminal boxes. */
stroke-width: 2;
stroke: #404040;
fill: rgba(255, 255, 255, 0.7);
}
body.vscode-dark svg.railroad-diagram text.diagram-text {
/* Multiple choice text, not working atm. */
font-size: 12px Hack, "Source Code Pro", monospace;
fill: red;
}
body.vscode-dark svg.railroad-diagram path.diagram-text {
/* Multiple choice text, not working atm. */
stroke-width: 1;
stroke: red;
fill: white;
cursor: help;
}
body.vscode-dark svg.railroad-diagram g.diagram-text:hover path.diagram-text {
/* Multiple choice text, not working atm. */
fill: #f00;
}
/* Call graphs */
body.vscode-dark .node-source {
fill: #e6db74;
}
body.vscode-dark .node-target {
fill: #45aa73;
}
body.vscode-dark .module-1 {
fill: #0ca9fd;
}
body.vscode-dark .module-2 {
fill: #63bf8d;
}
body.vscode-dark .module-3 {
fill: #ff8801;
}
body.vscode-dark .module-4 {
fill: #b9fc34;
}
body.vscode-dark .module-5 {
fill: #90e0e0;
}
body.vscode-dark .module-6 {
fill: #b4a3f5;
}
body.vscode-dark .module-7 {
fill: #f92672;
}
body.vscode-dark .module-8 {
fill: #e9e901;
}
body.vscode-dark .module-9 {
fill: #83be69;
}
body.vscode-dark .module-10 {
fill: #f1d18c;
}
body.vscode-dark .node:hover {
fill: #fff;
}
body.vscode-dark .node-source {
fill: #ff5711;
}
body.vscode-dark .node-target {
fill: #45aa73;
}
body.vscode-dark .link-source,
body.vscode-dark .link-target {
stroke-opacity: 1;
stroke-width: 2px;
}
body.vscode-dark .link {
stroke: #fff;
stroke-opacity: .2;
fill: none;
pointer-events: none;
animation: fadeIn 0.5s ease-out 0.2s 1 normal backwards;
}
body.vscode-dark .link-source {
stroke-opacity: 1;
stroke-width: 2px;
stroke: #45aa73;
animation: none;
}
body.vscode-dark .link-target {
stroke-opacity: 1;
stroke-width: 2px;
stroke: #ff5711;
animation: none;
}
body.vscode-dark .link-dimmed {
stroke-opacity: 0.075;
animation: fadeOut 0.25s ease-out 0s 1 normal backwards;
}
/* Parse trees */
body.vscode-dark .tree-node {
stroke-width: 2;
stroke: #404040;
fill: rgba(255, 255, 255, 1);
}
body.vscode-dark g .tree-root {
stroke-width: 2;
fill: #3a3c37;
stroke: #ffffff;
}
body.vscode-dark g .tree-leaf {
stroke-width: 2;
fill: #828e66;
stroke: #ffffff;
}
body.vscode-dark g .tree-error {
stroke-width: 2;
fill: rgb(187, 43, 33);
stroke: #ffffff;
}
body.vscode-dark g .token-value {
fill: white;
stroke: none;
font: 12pt "Source Code Pro", "Hack", "Consolas", "Andale Mono", monospace;
}
body.vscode-dark g .token-range {
fill: #bb832c;
stroke: none;
font: 8pt "Source Code Pro", "Hack", "Consolas", "Andale Mono", monospace;
}
/* Default CSS for internal elements, only visible in vscode */

View File

@ -1,484 +0,0 @@
/*
* This file contains all default CSS rules for the light vscode them, used for various diagrams and graphs.
* Use the "antlr4.customcss" setting in vscode to specify your own file, if you like to override some rules.
*
* Most of the appearance is defined here, while only some adjustments for the dark theme exist in dark.css.
* This style sheet is also used for exported svg files.
*/
body {
padding-left: 20px;
}
svg {
background: rgba(0, 0, 0, 0.03);
}
/* ATN graphs */
.transition {
fill: none;
stroke: #AAA;
stroke-width: 2px;
}
.marker {
fill: #999;
stroke: none;
}
.stateLabel {
font: bold 11pt "Helvetica Neue", Arial, sans-serif;
fill: white;
text-anchor: middle;
pointer-events: none;
}
.stateTypeLabel {
font: bold 7pt monospace;
fill: #EEE;
text-anchor: middle;
pointer-events: none;
}
.linkLabel {
font: bold 9pt "Helvetica Neue", Arial, sans-serif;
fill: #606060;
text-anchor: middle;
pointer-events: none;
}
.state {
stroke: #505050;
stroke-width: 3px;
cursor: move;
pointer-events: all;
/*filter: url(#black-glow);*/
}
.state.BASIC {
fill: #AAA;
}
.state.START {
fill: #36bde0;
}
.state.BSTART {
fill: #f39900;
}
.state.PBSTART {
fill: #98c000;
}
.state.SBSTART {
fill: #607dbd;
}
.state.TSTART {
fill: #ffd300;
}
.state.STOP {
fill: #2baa5b;
}
.state.BEND {
fill: #c2c269;
}
.state.SLBACK {
fill: #608b4e;
}
.state.SLENTRY {
fill: #a260cb;
}
.state.PLBACK {
fill: #517979;
}
.state.LEND {
fill: #9b90c3;
}
.state.RULE {
fill: #b73645;
}
.state.RULE.recursive {
fill: #36bde0;
}
/* Railroad diagrams */
svg.railroad-diagram path {
/* The connection lines. */
stroke-width: 2;
stroke: darkgray;
fill: rgba(0, 0, 0, 0);
}
svg.railroad-diagram text {
/* All text except comments. */
font: bold 12px Hack, "Source Code Pro", monospace;
text-anchor: middle;
fill: #404040;
/* Use fill instead of color for svg text. */
}
svg.railroad-diagram text.comment {
/* Comment text */
font: italic 10px Hack, "Source Code Pro", monospace;
fill: #404040;
}
svg.railroad-diagram g.non-terminal rect {
/* The non-terminal boxes. */
stroke-width: 2;
stroke: #404040;
fill: rgba(255, 255, 255, 1);
}
svg.railroad-diagram g.terminal rect {
/* The terminal boxes. */
stroke-width: 2;
stroke: #404040;
fill: rgba(0, 0, 0, 0.1);
}
svg.railroad-diagram text.diagram-text {
/* Multiple choice text, not working atm. */
font-size: 12px Hack, "Source Code Pro", monospace;
fill: red;
}
svg.railroad-diagram path.diagram-text {
/* Multiple choice text, not working atm. */
stroke-width: 1;
stroke: red;
fill: red;
cursor: help;
}
svg.railroad-diagram g.diagram-text:hover path.diagram-text {
/* Multiple choice text, not working atm. */
fill: #f00;
}
/* Call graphs */
.node {
font: 200 10px "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.link {
stroke: #000;
stroke-opacity: .2;
fill: none;
pointer-events: none;
animation: fadeIn 0.25s ease-out 0.2s 1 normal backwards;
}
.module-1 {
fill: #0ca9fd;
}
.module-2 {
fill: #63bf8d;
}
.module-3 {
fill: #ff8801;
}
.module-4 {
fill: #b9fc34;
}
.module-5 {
fill: #90e0e0;
}
.module-6 {
fill: #b4a3f5;
}
.module-7 {
fill: #f92672;
}
.module-8 {
fill: #e9e901;
}
.module-9 {
fill: #83be69;
}
.module-10 {
fill: #f1d18c;
}
.node:hover {
fill: #000;
}
.node:hover,
.node-source,
.node-target {
font: 700 12px "Helvetica Neue", Helvetica, Arial, sans-serif;
cursor: pointer;
}
.node-source {
fill: #ff5711;
}
.node-target {
fill: #45aa73;
}
.link-source,
.link-target {
stroke-opacity: 1;
stroke-width: 2px;
animation: none;
}
.link-source {
stroke: #3dcd92;
}
.link-target {
stroke: #ff5711;
}
@keyframes fadeOut {
0% {
stroke-opacity: 0.2;
}
100% {
stroke-opacity: 0.075;
}
}
@keyframes fadeIn {
0% {
stroke-opacity: 0.075;
}
100% {
stroke-opacity: 0.2;
}
}
.link-dimmed {
stroke-opacity: 0.075;
animation: fadeOut 0.25s ease-out 0.1s 1 normal backwards;
}
/* Parse trees */
.tree-node {
stroke-width: 2;
stroke: #C0C0C0;
fill: rgba(255, 255, 255, 1);
}
.tree-root {
stroke-width: 2;
fill: #7db6dd;
stroke: #7db6dd;
}
.tree-leaf {
cursor: default;
stroke-width: 2;
fill: rgba(160, 171, 136, 1);
stroke: rgba(117, 119, 91, 1);
}
.tree-error {
stroke-width: 2;
fill: #dd8f7d;
stroke: rgba(188, 106, 122, 1);
}
.tree-node text {
cursor: default;
font: 16px "Helvetica Neue", sans-serif;
fill: rgba(41, 41, 41, 1);
stroke: none;
}
.tree-leaf text,
.tree-root text,
.tree-error text {
font: 16px "Helvetica Neue", sans-serif;
fill: #ffffff;
stroke: none;
}
.tree-link {
stroke-width: 2px;
fill: none;
stroke: rgba(128, 128, 128, 1);
}
g .token-value {
fill: #404040;
stroke: none;
font: 14pt "Source Code Pro", "Hack", "Consolas", "Andale Mono", monospace;
}
g .token-range {
fill: rgba(0, 77, 98, 1);
stroke: none;
font: 8pt "Source Code Pro", "Hack", "Consolas", "Andale Mono", monospace;
}
/* Internal elements, only used in vscode */
.header {
font-size: 12pt;
z-index: 9999;
top: 0;
left: 0;
right: 0;
height: 45px;
background-color: var(--background-color);
cursor: default;
user-select: none;
white-space: nowrap;
}
.graph-initial {
font-size: 30pt;
font-weight: 600;
vertical-align: middle;
}
.rule-index {
font-size: 8pt;
}
#container {
margin-top: 45px;
}
.action-box {
font: 10pt monospace;
margin-left: 15px;
padding: 5px;
border: dotted 1px #606060;
cursor: default;
}
.atn-graph-color {
color: rgba(206, 11, 70, 1);
}
.atn-graph-save-image {
background: rgba(206, 11, 70, 1) url('../misc/save.png');
vertical-align: middle;
margin-left: 5px;
width: 24px;
height: 24px;
display: inline-block;
cursor: pointer;
}
.rrd-color {
color: rgba(10, 188, 80, 1);
}
.rrd-save-image {
background: rgba(10, 188, 80, 1) url('../misc/save.png');
vertical-align: middle;
margin-left: 5px;
width: 24px;
height: 24px;
display: inline-block;
cursor: pointer;
}
.call-graph-color {
color: rgba(255, 191, 15, 1);
}
.call-graph-save-image {
background: rgba(255, 191, 15, 1) url('../misc/save.png');
vertical-align: middle;
margin-left: 5px;
width: 24px;
height: 24px;
display: inline-block;
cursor: pointer;
}
.parse-tree-color {
color: rgba(49, 112, 212, 1);
}
.parse-tree-save-image {
background: rgba(49, 112, 212, 1) url('../misc/save.png');
vertical-align: middle;
margin-left: 5px;
width: 24px;
height: 24px;
display: inline-block;
cursor: pointer;
}
.switch label {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
display: block;
position: absolute;
top: 0;
left: 0;
z-index: 10;
}
.switch input {
display: none;
}
.switch > span {
display: inline-block;
top: 3px;
transition: left 0.2s;
}
.switch-border {
height: 12px;
width: 24px;
position: relative;
border: 1px solid rgba(49, 112, 212, 0.75);
background-color: rgba(49, 112, 212, 0.75);
border-radius: 3.5em;
}
.switch-handle-top {
width: 12px;
height: 12px;
position: absolute;
left: 0px;
top: 0px;
z-index: 4;
background-color: white;
border-radius: 2.5em;
transition: left 0.2s;
}
.switch input:checked~.switch-handle-top {
top: 0px;
left: 12px;
}

View File

@ -1,11 +0,0 @@
pub mod node;
pub mod parser;
pub mod vm;
pub mod source;
pub mod token;
pub mod tokenizer;
pub mod variable;
pub mod external_function;
pub mod permission;
#[macro_use]
extern crate log;

View File

@ -1,90 +0,0 @@
use std::collections::HashMap;
#[derive(Debug, PartialEq, Clone)]
pub enum NodeKind {
ASSIGN,
ADD,
SUB,
MUL,
DIV,
EQ, // ==
NE, // !=
LT, // <
LE, // <=
}
#[derive(Debug, Clone, PartialEq)]
pub enum Node {
Function {
name: String,
args: HashMap<String, String>,
body: Vec<Box<Node>>,
},
Mode {
mode: String,
},
Permission {
accept: Vec<String>,
reject: Vec<String>,
},
Operator {
kind: NodeKind,
lhs: Box<Node>,
rhs: Box<Node>,
},
Number {
value: usize,
},
Text {
value: String,
},
Lvar {
value: String,
},
Return {
lhs: Box<Node>,
},
If {
condition: Box<Node>,
stmt: Box<Node>,
else_stmt: Option<Box<Node>>,
},
While {
condition: Box<Node>,
stmt: Box<Node>,
},
For {
init: Option<Box<Node>>,
condition: Option<Box<Node>>,
update: Option<Box<Node>>,
stmt: Box<Node>,
},
Block {
stmts: Vec<Box<Node>>,
permission: Option<Box<Node>>,
mode: Option<Box<Node>>,
},
Define {
name: String,
var_type: String,
},
Call {
name: String,
args: Vec<Box<Node>>,
},
None,
}
impl Node {
pub fn new_node(kind: NodeKind, lhs: Box<Node>, rhs: Box<Node>) -> Box<Node> {
Box::new(Node::Operator { kind, lhs, rhs })
}
pub fn new_num_node(value: usize) -> Box<Node> {
Box::new(Node::Number { value })
}
pub fn new_lvar_node(value: String) -> Box<Node> {
Box::new(Node::Lvar { value })
}
}

View File

@ -1,454 +0,0 @@
use crate::node::*;
use crate::token::*;
use crate::tokenizer::*;
use std::collections::HashMap;
#[derive(Clone)]
pub struct Parser {
pub tokenizer: Tokenizer,
pub local_vars: HashMap<String, usize>,
}
impl Parser {
pub fn functions(&mut self) -> Result<HashMap<String, Box<Node>>, String> {
let mut nodes: HashMap<String, Box<Node>> = HashMap::new();
loop {
if self.tokenizer.current_token().kind != TokenKind::EOF {
let function = self.function()?;
if let Node::Function { name, .. } = *function.clone() {
nodes.insert(name, function);
}
} else {
return Ok(nodes);
}
}
}
/*
function: FN IDENT LPAREN (IDENT COLON IDENT COMMA?)* RPAREN (ARROW IDENT)? block ;
*/
pub fn function(&mut self) -> Result<Box<Node>, String> {
if self
.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from("fn"))
{
debug!("parsing function");
let func_name = self.tokenizer.current_token().clone();
self.tokenizer.expect_kind(TokenKind::IDENT)?;
let mut args = HashMap::new();
self.tokenizer.expect(String::from("("))?;
debug!("parsing args");
while !self
.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from(")"))
{
debug!("consume argument");
let name = self.tokenizer.expect_ident()?;
self.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from(":"));
let type_str = self.tokenizer.expect_ident()?;
self.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from(","));
args.insert(name, type_str);
}
let mut nodes: Vec<Box<Node>> = vec![];
debug!("parsing body node");
loop {
nodes.push(self.stmt()?);
debug!("body nodes parsed");
//self.tokenizer.expect(String::from("}"))?;
return Ok(Box::new(Node::Function {
name: func_name.str,
args,
body: nodes,
}));
}
} else {
println!("{:?}", self.tokenizer.current_token());
Err(String::from("Unexpected token."))
}
}
/*
program: stmt* ;
*/
pub fn program(&mut self) -> Result<Vec<Box<Node>>, String> {
let mut nodes: Vec<Box<Node>> = vec![];
loop {
if self.tokenizer.current_token().kind != TokenKind::EOF {
nodes.push(self.stmt()?);
} else {
return Ok(nodes);
}
}
}
/*
stmt: let
| block
| return
| if
| while
| for
| expr SEMICOLON
;
*/
pub fn stmt(&mut self) -> Result<Box<Node>, String> {
if self
.tokenizer
.consume_kind_str(TokenKind::IDENT, String::from("let"))
{
let ident = self.tokenizer.current_token().clone();
self.tokenizer.expect_kind(TokenKind::IDENT)?;
self.tokenizer.expect(String::from(":"))?;
let var_type = self.tokenizer.current_token().clone();
self.tokenizer.expect_kind(TokenKind::IDENT)?;
self.tokenizer.expect(String::from(";"))?;
return Ok(Box::new(Node::Define {
name: ident.str,
var_type: var_type.str,
}));
}
debug!("parsing permission");
let permission = if self.tokenizer.current_token().str == "$" {
Some(self.permission()?)
} else {
None
};
debug!("parsing mode");
let mode = if self.tokenizer.current_token().str == "#" {
Some(self.mode()?)
} else {
None
};
if self
.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from("{"))
|| permission != None
{
let mut stmts: Vec<Box<Node>> = vec![];
loop {
if self
.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from("}"))
{
return Ok(Box::new(Node::Block {
stmts,
permission: permission,
mode: mode,
}));
} else {
stmts.push(self.stmt()?);
}
}
}
if self.tokenizer.consume_kind(TokenKind::RETURN) {
let node = Node::Return { lhs: self.expr()? };
self.tokenizer.expect(String::from(";"))?;
return Ok(Box::new(node));
}
if self.tokenizer.current_token().kind == TokenKind::CONTROL {
match &*self.tokenizer.current_token().str {
"if" => {
self.tokenizer.cursor += 1;
self.tokenizer.expect(String::from("("))?;
let condition = self.expr()?;
self.tokenizer.expect(String::from(")"))?;
let stmt = self.stmt()?;
let mut else_stmt: Option<Box<Node>> = None;
if self
.tokenizer
.consume_kind_str(TokenKind::CONTROL, String::from("else"))
{
else_stmt = Some(self.stmt()?);
}
return Ok(Box::new(Node::If {
condition,
stmt,
else_stmt,
}));
}
"while" => {
self.tokenizer.cursor += 1;
self.tokenizer.expect(String::from("("))?;
let condition = self.expr()?;
self.tokenizer.expect(String::from(")"))?;
let stmt = self.stmt()?;
return Ok(Box::new(Node::While { condition, stmt }));
}
"for" => {
self.tokenizer.cursor += 1;
self.tokenizer.expect(String::from("("))?;
let init: Option<Box<Node>> =
if self.tokenizer.current_token().str != String::from(";") {
Some(self.expr()?)
} else {
None
};
self.tokenizer.expect(String::from(";"))?;
let condition: Option<Box<Node>> =
if self.tokenizer.current_token().str != String::from(";") {
Some(self.expr()?)
} else {
None
};
self.tokenizer.expect(String::from(";"))?;
let update: Option<Box<Node>> =
if self.tokenizer.current_token().str != String::from(")") {
Some(self.expr()?)
} else {
None
};
self.tokenizer.expect(String::from(")"))?;
let stmt = self.stmt()?;
return Ok(Box::new(Node::For {
init,
condition,
update,
stmt,
}));
}
_ => {}
}
}
let node = self.expr();
self.tokenizer.expect(String::from(";"))?;
return node;
}
/*
mode: SHARP IDENT ;
*/
pub fn mode(&mut self) -> Result<Box<Node>, String> {
self.tokenizer.expect(String::from("#"))?;
let mode = self.tokenizer.current_token().clone();
self.tokenizer.expect_kind(TokenKind::IDENT)?;
self.tokenizer.expect(String::from(";"))?;
return Ok(Box::new(Node::Mode { mode: mode.str }));
}
/*
permission: DOLLER LPAREN ( IDENT LBRACKET ( IDENT COMMA? )* RBRACKET COMMA? )* RPAREN ;
*/
pub fn permission(&mut self) -> Result<Box<Node>, String> {
self.tokenizer.expect(String::from("$"))?;
self.tokenizer.expect(String::from("("))?;
let mut accept: Vec<String> = vec![];
let mut reject: Vec<String> = vec![];
while !self
.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from(")"))
{
let name = self.tokenizer.expect_ident()?;
if name != "accept" && name != "reject" {
return Err(String::from(format!("Unexpected: {}", name)));
}
self.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from("["));
while !self
.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from("]"))
{
let permission = self.tokenizer.expect_ident()?;
self.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from(","));
if name == "accept" {
accept.push(permission);
} else if name == "reject" {
reject.push(permission);
}
}
self.tokenizer
.consume_kind_str(TokenKind::RESERVED, String::from(","));
}
Ok(Box::new(Node::Permission { accept, reject }))
}
/*
expr: assign ;
*/
pub fn expr(&mut self) -> Result<Box<Node>, String> {
Ok(self.assign()?)
}
/*
assign: equality (EQ assign)? ;
*/
pub fn assign(&mut self) -> Result<Box<Node>, String> {
let mut node = self.equality()?;
if self.tokenizer.consume(String::from("=")) {
node = Node::new_node(NodeKind::ASSIGN, node, self.assign()?);
}
Ok(node)
}
/*
equality: relational (EQEQ relational | NE relational | CONJ)* ;
*/
pub fn equality(&mut self) -> Result<Box<Node>, String> {
let mut node = self.relational()?;
loop {
if self.tokenizer.consume(String::from("==")) {
node = Node::new_node(NodeKind::EQ, node, self.relational()?);
} else if self.tokenizer.consume(String::from("!=")) {
node = Node::new_node(NodeKind::NE, node, self.relational()?);
} else {
return Ok(node);
}
}
}
/*
relational: add (LE add | LT add | BE add | BT add)* ;
*/
pub fn relational(&mut self) -> Result<Box<Node>, String> {
let mut node = self.add()?;
loop {
if self.tokenizer.consume(String::from("<=")) {
node = Node::new_node(NodeKind::LE, node, self.add()?);
} else if self.tokenizer.consume(String::from("<")) {
node = Node::new_node(NodeKind::LT, node, self.add()?);
} else if self.tokenizer.consume(String::from(">=")) {
node = Node::new_node(NodeKind::LE, self.add()?, node);
} else if self.tokenizer.consume(String::from(">")) {
node = Node::new_node(NodeKind::LT, self.add()?, node);
} else {
return Ok(node);
}
}
}
/*
add: mul (ADD mul | SUB mul | SUB_ASSIGNMENT mul | ADD_ASSIGNMENT mul)* ;
*/
pub fn add(&mut self) -> Result<Box<Node>, String> {
let mut node = self.mul()?;
loop {
if self.tokenizer.consume(String::from("+")) {
node = Node::new_node(NodeKind::ADD, node, self.mul()?);
} else if self.tokenizer.consume(String::from("-")) {
node = Node::new_node(NodeKind::SUB, node, self.mul()?);
} else if self.tokenizer.consume(String::from("+=")) {
node = Node::new_node(
NodeKind::ASSIGN,
Box::new((*node).clone()),
Node::new_node(NodeKind::ADD, node, self.mul()?),
);
} else if self.tokenizer.consume(String::from("-=")) {
node = Node::new_node(
NodeKind::ASSIGN,
Box::new((*node).clone()),
Node::new_node(NodeKind::SUB, node, self.mul()?),
);
} else {
return Ok(node);
}
}
}
/*
mul: unary (MUL unary | DIV unary | DIV_ASSIGNMENT unary | MUL_ASSIGNMENT unary)* ;
*/
pub fn mul(&mut self) -> Result<Box<Node>, String> {
let mut node = self.unary()?;
loop {
if self.tokenizer.consume(String::from("*")) {
node = Node::new_node(NodeKind::MUL, node, self.unary()?);
} else if self.tokenizer.consume(String::from("/")) {
node = Node::new_node(NodeKind::DIV, node, self.unary()?);
} else if self.tokenizer.consume(String::from("*=")) {
node = Node::new_node(
NodeKind::ASSIGN,
Box::new((*node).clone()),
Node::new_node(NodeKind::MUL, node, self.unary()?),
);
} else if self.tokenizer.consume(String::from("/=")) {
node = Node::new_node(
NodeKind::ASSIGN,
Box::new((*node).clone()),
Node::new_node(NodeKind::DIV, node, self.unary()?),
);
} else {
return Ok(node);
}
}
}
/*
primary: LPAREN expr RPAREN | function_call | TEXT | NUM ;
*/
pub fn primary(&mut self) -> Result<Box<Node>, String> {
if self.tokenizer.consume(String::from("(")) {
let node = self.expr()?;
self.tokenizer.expect(String::from(")"))?;
return Ok(node);
}
if self.tokenizer.current_token().kind == TokenKind::IDENT {
let node = self.tokenizer.expect_ident()?;
if self.tokenizer.consume(String::from("(")) {
let mut args: Vec<Box<Node>> = vec![];
while self.tokenizer.current_token().str != ")" {
args.push(self.unary()?);
self.tokenizer.consume(String::from(","));
}
self.tokenizer.expect(String::from(")"))?;
return Ok(Box::new(Node::Call {
name: node.clone(),
args: args,
}));
}
return Ok(Node::new_lvar_node(node.clone()));
}
if self.tokenizer.current_token().kind == TokenKind::TEXT {
let text = self.tokenizer.current_token().str.clone();
self.tokenizer.consume_kind(TokenKind::TEXT);
return Ok(Box::new(Node::Text { value: text }));
}
return Ok(Node::new_num_node(self.tokenizer.expect_number()?));
}
/*
unary: ADD primary
| SUB primary
| primary
;
*/
pub fn unary(&mut self) -> Result<Box<Node>, String> {
if self.tokenizer.consume(String::from("+")) {
return Ok(self.primary()?);
}
if self.tokenizer.consume(String::from("-")) {
return Ok(Node::new_node(
NodeKind::SUB,
Node::new_num_node(0),
self.primary()?,
));
}
return Ok(self.primary()?);
}
}

View File

@ -1,16 +0,0 @@
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Permission {
Administrator,
StdIo
}
impl Permission {
pub fn from_string(permission: &str) -> Self {
match permission {
"Administrator" => Self::Administrator,
"StdIo" => Self::StdIo,
_ => panic!("Permission not found.")
}
}
}

View File

@ -1,91 +0,0 @@
#[derive(Clone)]
pub struct Source {
pub src: Vec<char>,
pub pos: usize,
}
impl Source {
pub fn get_char(&mut self, check: impl Fn(char) -> bool) -> Result<char, String> {
match self.get_next() {
Ok(c) => {
if check(c) {
Ok(c)
} else {
self.pos -= 1;
Err(String::from("Not found."))
}
}
Err(text) => Err(text),
}
}
pub fn get_string(&mut self, string: String) -> Result<String, String> {
let first_pos = self.pos;
for i in 0..string.chars().count() {
if self.has_next() {
match self.get_next() {
Ok(c) => {
if c == string.chars().nth(i).unwrap() {
continue;
} else {
self.pos = first_pos;
return Err(String::from(""));
}
}
Err(_) => {}
}
} else {
self.pos = first_pos;
return Err(String::from(""));
}
}
Ok(string)
}
pub fn get_chars(&mut self, check: impl Fn(char) -> bool) -> Result<String, String> {
let mut buffer = String::from("");
while self.has_next() {
match self.get_next() {
Ok(c) => {
if check(c) {
buffer += &c.to_string();
} else {
self.pos -= 1;
break;
}
}
Err(_) => {
break;
}
}
}
if buffer == "" {
Err(String::from("Not found."))
} else {
Ok(buffer)
}
}
pub fn get_next(&mut self) -> Result<char, String> {
self.pos += 1;
if self.src.len() > self.pos - 1 {
Ok(self.src[self.pos - 1])
} else {
Err(String::from("EOF"))
}
}
pub fn new(src: String) -> Source {
Source {
src: src.chars().collect(),
pos: 0,
}
}
pub fn has_next(&self) -> bool {
self.src.len() > self.pos
}
}

View File

@ -1,17 +0,0 @@
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum TokenKind {
CONTROL,
RETURN,
RESERVED,
IDENT,
NUMBER,
EOF,
TEXT,
}
#[derive(Clone, Debug)]
pub struct Token {
pub kind: TokenKind,
pub num: usize,
pub str: String,
}

View File

@ -1,269 +0,0 @@
use crate::source::*;
use crate::token::*;
#[derive(Clone)]
pub struct Tokenizer {
pub tokens: Vec<Token>,
pub cursor: usize,
}
impl Tokenizer {
pub fn current_token(&mut self) -> &mut Token {
&mut self.tokens[self.cursor]
}
pub fn consume(&mut self, op: String) -> bool {
debug!("consume OP {} {:?}", op, self.current_token());
return if self.current_token().kind != TokenKind::RESERVED || self.current_token().str != op
{
false
} else {
self.cursor += 1;
true
};
}
pub fn consume_kind(&mut self, kind: TokenKind) -> bool {
debug!("consume kind {:?} {:?}", kind, self.current_token());
return if self.current_token().kind != kind {
false
} else {
self.cursor += 1;
true
};
}
pub fn consume_kind_str(&mut self, kind: TokenKind, string: String) -> bool {
debug!(
"consume kind str {:?} {:?} {:?}",
kind,
string,
self.current_token()
);
return if self.current_token().kind == kind && self.current_token().str == string {
self.cursor += 1;
true
} else {
false
};
}
pub fn expect(&mut self, op: String) -> Result<(), String> {
debug!("Expect OP {} {:?}", op, self.current_token());
if self.current_token().str != op {
return Err(format!("Unexpected type : {}", op));
}
self.cursor += 1;
Ok(())
}
pub fn expect_kind(&mut self, kind: TokenKind) -> Result<(), String> {
debug!("expect kind {:?} {:?}", kind, self.current_token());
if self.current_token().kind != kind {
return Err(format!("Unexpected token: {:?}", self.current_token().kind));
}
self.cursor += 1;
Ok(())
}
pub fn expect_ident(&mut self) -> Result<String, String> {
debug!("Expect IDENT {:?}", self.current_token());
if self.current_token().kind != TokenKind::IDENT {
return Err(format!("Unexpected type : {:?}", self.current_token().kind));
}
let val = self.current_token().str.clone();
self.cursor += 1;
Ok(val.to_string())
}
pub fn expect_number(&mut self) -> Result<usize, String> {
let kind = self.current_token().kind;
debug!("Expect NUM {:?}", self.current_token());
if kind != TokenKind::NUMBER {
return Err(format!("Unexpected type : {:?}", kind));
}
let val = self.current_token().num;
self.cursor += 1;
Ok(val)
}
pub fn new() -> Tokenizer {
Tokenizer {
cursor: 0,
tokens: vec![],
}
}
pub fn create_reserved(op: String) -> Token {
Token {
kind: TokenKind::RESERVED,
str: op,
num: 0,
}
}
pub fn create_number(num: usize) -> Token {
Token {
kind: TokenKind::NUMBER,
num: num,
str: String::default(),
}
}
pub fn tokenize(&mut self, source: &mut Source) -> Result<Vec<Token>, String> {
let reserved: Vec<String> = vec![
String::from("+="),
String::from("-="),
String::from("*="),
String::from("/="),
String::from("#"),
String::from("$"),
String::from("+"),
String::from("-"),
String::from("*"),
String::from("/"),
String::from("&&"),
String::from("&"),
String::from("{"),
String::from("}"),
String::from("("),
String::from(")"),
String::from("["),
String::from("]"),
String::from("=="),
String::from("!="),
String::from(">="),
String::from("<="),
String::from("<"),
String::from(">"),
String::from("="),
String::from(";"),
String::from(":"),
String::from(","),
String::from("\""),
String::from("fn"),
String::from("->"),
];
let controls: Vec<String> = vec![
String::from("for"),
String::from("while"),
String::from("if"),
String::from("else"),
];
while source.has_next() {
match source.get_char(is('"')) {
Ok(_) => {
let text = match source.get_chars(not(is('"'))) {
Ok(t) => t,
Err(_) => String::from(""),
};
source.get_char(is('"'))?;
self.tokens.push(Token {
kind: TokenKind::TEXT,
str: text,
num: 0,
});
continue;
}
Err(_) => {}
}
match source.get_char(is_whitespace) {
Ok(_) => {
continue;
}
Err(_) => {}
}
match contains_list_chars(source, reserved.clone()) {
Ok(op) => {
self.tokens
.push(Tokenizer::create_reserved(String::from(op)));
continue;
}
Err(_) => {}
}
match source.get_chars(is_digit) {
Ok(num) => {
self.tokens
.push(Tokenizer::create_number(num.parse().unwrap()));
continue;
}
Err(_) => {}
}
match source.get_chars(or(is_ascii, or(is_digit, is('_')))) {
Ok(c) => {
if c == String::from("return") {
self.tokens.push(Token {
kind: TokenKind::RETURN,
str: String::default(),
num: 0,
});
continue;
}
if controls.contains(&c) {
self.tokens.push(Token {
kind: TokenKind::CONTROL,
str: c,
num: 0,
});
continue;
}
self.tokens.push(Token {
kind: TokenKind::IDENT,
str: c,
num: 0,
});
continue;
}
Err(_) => {}
}
return Err(String::from("Failed to tokenize"));
}
self.tokens.push(Token {
kind: TokenKind::EOF,
str: String::default(),
num: 0,
});
Ok(self.tokens.clone())
}
}
fn contains_list_chars(source: &mut Source, list: Vec<String>) -> Result<String, String> {
for target in list {
match source.get_string(target) {
Ok(string) => {
return Ok(string);
}
Err(_) => {}
}
}
return Err(String::from(""));
}
fn or(f: impl Fn(char) -> bool, g: impl Fn(char) -> bool) -> impl Fn(char) -> bool {
move |c| f(c) || g(c)
}
fn is(ch: char) -> impl Fn(char) -> bool {
move |c| c == ch
}
fn not(f: impl Fn(char) -> bool) -> impl Fn(char) -> bool {
move |c| !f(c)
}
fn is_whitespace(c: char) -> bool {
c.is_whitespace()
}
fn is_digit(c: char) -> bool {
c.is_digit(10)
}
fn is_ascii(c: char) -> bool {
c.is_alphabetic()
}

View File

@ -1,14 +0,0 @@
#[derive(Clone, PartialEq, Debug)]
pub enum Variable {
Number {
value: usize,
},
Text {
value: String,
},
Return {
value: Box<Variable>
},
None {}
}

View File

@ -1,507 +0,0 @@
use crate::external_function::{ExternalFuncReturn, ExternalFuncStatus};
use crate::node::*;
use crate::permission::Permission;
use crate::source::Source;
use crate::variable::*;
use std::collections::{HashMap, VecDeque};
use std::string::*;
#[derive(Clone, Debug)]
pub struct Block {
pub accept: Vec<Permission>,
pub reject: Vec<Permission>,
pub variables: HashMap<String, LocalVariable>,
pub is_split: bool,
}
pub struct GPSL {
pub functions: Option<HashMap<String, Box<Node>>>,
pub global_variables: Vec<Variable>,
pub source: Source,
pub blocks: VecDeque<Block>,
pub external_func:
Vec<fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn>,
}
#[derive(Clone, Debug)]
pub struct LocalVariable {
pub name: String,
pub value: Variable,
pub status: VariableStatus,
}
#[derive(Clone, Debug)]
pub struct VariableStatus {
pub initialized: bool,
}
impl VariableStatus {
pub fn default() -> VariableStatus {
VariableStatus { initialized: false }
}
}
impl GPSL {
pub fn new(
source: Source,
functions: Option<HashMap<String, Box<Node>>>,
external_func: Vec<
fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn,
>,
) -> GPSL {
GPSL {
source,
functions,
global_variables: vec![],
blocks: VecDeque::new(),
external_func,
}
}
pub fn get_local_var_mut(&mut self, name: &String) -> Option<&mut LocalVariable> {
for x in 0..self.blocks.len() {
if self.blocks[x].variables.contains_key(name) {
return self.blocks[x].variables.get_mut(name);
}
if self.blocks[x].is_split {
break;
}
}
None
}
pub fn get_local_var(&mut self, name: &String) -> Option<LocalVariable> {
for x in 0..self.blocks.len() {
if self.blocks[x].variables.contains_key(name) {
if let Some(var) = self.blocks[x].variables.get(name).clone() {
return Some(var.clone());
} else {
return None;
}
}
if self.blocks[x].is_split {
break;
}
}
None
}
pub fn extract_number(node: Variable) -> Result<usize, String> {
match node {
Variable::Number { value } => Ok(value),
_ => Err(String::from("Not a number")),
}
}
pub fn evaluate(&mut self, node: Box<Node>) -> Result<Option<Variable>, String> {
match *node {
Node::Call { name, args } => {
let function_name = name;
let f = self.external_func.clone();
let mut args_value: Vec<Variable> = vec![];
for arg in args {
if let Some(val) = self.evaluate(arg).expect("Cannot evaluate") {
args_value.push(val);
}
}
if let Some(functions) = self.functions.clone() {
debug!(
"functions: {:?}",
functions
.iter()
.map(|f| format!("{},", f.0))
.collect::<String>()
);
debug!(
"{}: {}",
&function_name,
functions.contains_key(&function_name)
);
if functions.contains_key(&function_name) {
if let Node::Function { body, .. } = &*(functions[&function_name]) {
for program in body {
let block = {
let blocks = self.blocks.clone();
blocks.front().unwrap().clone()
};
self.blocks.push_front(Block {
accept: block.accept.clone(),
reject: block.reject.clone(),
variables: HashMap::new(),
is_split: true,
});
let res = self.evaluate(Box::new(*program.clone()));
if let Ok(Some(res)) = res {
match res {
Variable::Return { value } => {
return Ok(Some(*value));
}
_ => {}
}
} else if let Err(err) = res {
return Err(err);
}
self.blocks.pop_front();
}
}
return Ok(None);
}
}
debug!("Searching external: {}, ({:?})", &function_name, args_value);
for func in f {
let block = self.blocks.front().unwrap();
let res = func(
function_name.clone(),
args_value.clone(),
block.accept.clone(),
block.reject.clone(),
);
if res.status == ExternalFuncStatus::SUCCESS {
return Ok(res.value);
}
if res.status == ExternalFuncStatus::REJECTED {
return Err("External function rejected.".to_string());
}
}
Err(format!("Function not found: {}", function_name))
}
Node::Text { value } => Ok(Some(Variable::Text { value })),
Node::Number { value } => Ok(Some(Variable::Number { value })),
Node::Operator { kind, lhs, rhs } => {
if kind == NodeKind::ASSIGN {
debug!("Assign: {:?}", self.blocks.front());
let rhs = self.evaluate(rhs);
if let Ok(Some(rhs)) = rhs {
match *(lhs.clone()) {
Node::Lvar { value } => {
self.get_local_var_mut(&value).unwrap().value = rhs;
self.get_local_var_mut(&value).unwrap().status.initialized = true;
}
_ => {}
}
}
return Ok(None);
}
let lhs = self.evaluate(lhs).expect("Cannot evaluate lhs.");
let rhs = self.evaluate(rhs).expect("Cannot evaluate rhs.");
if let Some(lhs) = lhs {
if let Some(rhs) = rhs {
match kind {
NodeKind::ADD => match GPSL::extract_number(lhs) {
Ok(lhs) => match GPSL::extract_number(rhs) {
Ok(rhs) => Ok(Some(Variable::Number { value: lhs + rhs })),
Err(err) => Err(err),
},
Err(err) => Err(err),
},
NodeKind::DIV => match GPSL::extract_number(lhs) {
Ok(lhs) => match GPSL::extract_number(rhs) {
Ok(rhs) => Ok(Some(Variable::Number { value: lhs / rhs })),
Err(err) => Err(err),
},
Err(err) => Err(err),
},
NodeKind::MUL => match GPSL::extract_number(lhs) {
Ok(lhs) => match GPSL::extract_number(rhs) {
Ok(rhs) => Ok(Some(Variable::Number { value: lhs * rhs })),
Err(err) => Err(err),
},
Err(err) => Err(err),
},
NodeKind::SUB => match GPSL::extract_number(lhs) {
Ok(lhs) => match GPSL::extract_number(rhs) {
Ok(rhs) => Ok(Some(Variable::Number { value: lhs - rhs })),
Err(err) => Err(err),
},
Err(err) => Err(err),
},
NodeKind::EQ => {
if lhs == rhs {
Ok(Some(Variable::Number { value: 1 }))
} else {
Ok(Some(Variable::Number { value: 0 }))
}
}
NodeKind::NE => {
if lhs != rhs {
Ok(Some(Variable::Number { value: 1 }))
} else {
Ok(Some(Variable::Number { value: 0 }))
}
}
NodeKind::LT => match GPSL::extract_number(lhs) {
Ok(lhs) => match GPSL::extract_number(rhs) {
Ok(rhs) => {
if lhs < rhs {
Ok(Some(Variable::Number { value: 1 }))
} else {
Ok(Some(Variable::Number { value: 0 }))
}
}
Err(err) => Err(err),
},
Err(err) => Err(err),
},
NodeKind::LE => match GPSL::extract_number(lhs) {
Ok(lhs) => match GPSL::extract_number(rhs) {
Ok(rhs) => {
if lhs <= rhs {
Ok(Some(Variable::Number { value: 1 }))
} else {
Ok(Some(Variable::Number { value: 0 }))
}
}
Err(err) => Err(err),
},
Err(err) => Err(err),
},
_ => Ok(None),
}
} else {
Err(String::from("RHS Variable is null."))
}
} else {
Err(String::from("LHS Variable is null."))
}
}
Node::Lvar { value } => {
return Ok(Some(self.get_local_var(&value).unwrap().value.clone()));
}
Node::Return { lhs } => {
if let Ok(Some(lhs)) = self.evaluate(lhs) {
return Ok(Some(Variable::Return {
value: Box::new(lhs),
}));
} else {
return Err(String::from("Cannot evaluate LHS."));
}
}
Node::If {
condition,
stmt,
else_stmt,
} => {
if let Ok(Some(condition)) = self.evaluate(condition) {
if match condition {
Variable::Number { value } => value == 1,
_ => false,
} {
if let Ok(Some(res)) = self.evaluate(stmt) {
match res.clone() {
Variable::Return { .. } => {
return Ok(Some(res));
}
_ => {}
}
}
} else {
match else_stmt {
Some(else_stmt) => {
if let Ok(Some(res)) = self.evaluate(else_stmt) {
match res.clone() {
Variable::Return { .. } => {
return Ok(Some(res));
}
_ => {}
}
}
}
None => {}
}
}
}
return Ok(None);
}
Node::While { condition, stmt } => {
let mut cond = if let Some(condition) = self.evaluate(condition.clone())? {
condition
} else {
Variable::Number { value: 0 }
};
while match cond {
Variable::Number { value } => value == 1,
_ => false,
} {
self.evaluate(stmt.clone())?;
cond = if let Some(condition) = self.evaluate(condition.clone())? {
condition
} else {
Variable::Number { value: 0 }
};
}
return Ok(None);
}
Node::For {
init,
condition,
update,
stmt,
} => {
match init {
Some(init) => {
self.evaluate(init)?;
}
None => {}
}
let mut cond = match condition.clone() {
Some(condition) => {
if let Some(condition) = self.evaluate(condition)? {
condition
} else {
Variable::Number { value: 0 }
}
}
None => Variable::Number { value: 1 },
};
while match cond {
Variable::Number { value } => value == 1,
_ => false,
} {
self.evaluate(stmt.clone())?;
match update.clone() {
Some(update) => {
self.evaluate(update)?;
}
None => {}
}
cond = match condition.clone() {
Some(condition) => {
if let Some(condition) = self.evaluate(condition)? {
condition
} else {
Variable::Number { value: 0 }
}
}
None => Variable::Number { value: 1 },
};
}
return Ok(None);
}
Node::Block {
stmts,
permission,
mode,
} => {
let accept = self.blocks.front().unwrap().accept.clone();
let reject = self.blocks.front().unwrap().reject.clone();
let (accept, reject) = if let Node::Permission { accept, reject } =
*permission.unwrap_or(Box::new(Node::None))
{
(
accept.iter().map(|p| Permission::from_string(p)).collect(),
reject.iter().map(|p| Permission::from_string(p)).collect(),
)
} else {
(accept, reject)
};
let mode = if let Node::Mode { mode } = *mode.unwrap_or(Box::new(Node::None)) {
mode
} else {
"".to_string()
};
println!("Mode: {}", mode);
self.blocks.push_front(Block {
accept: accept,
reject: reject,
variables: HashMap::new(),
is_split: false,
});
for stmt in stmts {
let ret = self.evaluate(stmt)?;
if let Some(ret) = ret {
match ret.clone() {
Variable::Return { .. } => {
return Ok(Some(ret));
}
_ => {}
}
}
}
self.blocks.pop_front();
return Ok(None);
}
Node::Define { name, var_type } => {
let value = if var_type == "num" {
Variable::Number { value: 0 }
} else if var_type == "String" {
Variable::Text {
value: String::default(),
}
} else {
return Err(format!("{}: 未知の型です。", var_type));
};
self.blocks.front_mut().unwrap().variables.insert(
name.clone(),
LocalVariable {
name,
value,
status: VariableStatus::default(),
},
);
debug!("Define: {:?}", self.blocks.front());
return Ok(None);
}
_ => Ok(None),
}
}
pub fn run(&mut self, function_name: String, _: Vec<Box<Node>>) -> Result<Variable, String> {
debug!("functions: {:?}", self.functions);
debug!("searching {}", function_name);
self.blocks.push_front(Block {
accept: vec![Permission::Administrator, Permission::StdIo],
reject: vec![],
variables: HashMap::new(),
is_split: true,
});
if let Some(functions) = self.functions.clone() {
if let Node::Function { body, .. } = &*(functions[&function_name]) {
for program in body {
let res = self.evaluate(Box::new(*program.clone()));
if let Ok(Some(res)) = res {
match res {
Variable::Return { value } => {
return Ok(*value);
}
_ => {}
}
} else if let Err(err) = res {
return Err(err);
}
}
}
}
Ok(Variable::None {})
}
}

View File

@ -1 +0,0 @@
pub mod gpsl;

View File

@ -1,14 +0,0 @@
fn untrusted_function(a: num) $(accept[StdIo]) {
println("test");
}
fn main() $(accept[Administrator, StdIo]) {
println("1");
$(accept[StdIo], reject[Administrator]) {
untrusted_function();
}
println("2");
}

View File

@ -1,7 +1,11 @@
use serde::Deserializer;
use crate::gpsl::{permission::Permission, variable::Variable};
use std::{io::Read, net::TcpStream};
use std::{
io::Read,
net::TcpStream,
sync::{Arc, Mutex},
};
#[derive(PartialEq)]
pub enum ExternalFuncStatus {
@ -17,7 +21,7 @@ pub struct ExternalFuncReturn {
}
pub struct ExternalFuncCallData {
pub stream: Option<TcpStream>,
pub stream: Arc<Mutex<Option<TcpStream>>>,
}
#[allow(dead_code)]
@ -68,11 +72,14 @@ pub const STD_FUNC: fn(
}
"receive" => {
let mut buffer = String::default();
data.unwrap()
.stream
.unwrap()
.read_to_string(&mut buffer)
.unwrap();
let data = data.unwrap();
let mut stream = data.stream.lock().unwrap();
let stream = match &mut *stream {
Some(stream) => stream,
None => panic!("Cannot access to tcp stream"),
};
stream.read_to_string(&mut buffer).unwrap();
ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: Some(serde_json::from_str(&buffer).unwrap()),

View File

@ -9,6 +9,7 @@ use log::*;
use std::collections::{HashMap, VecDeque};
use std::net::TcpStream;
use std::string::*;
use std::sync::{Arc, Mutex};
#[derive(Clone, Debug)]
pub struct Block {
@ -23,7 +24,7 @@ pub struct GPSL {
pub global_variables: Vec<Variable>,
pub source: Source,
pub blocks: VecDeque<Block>,
pub tcp_stream: Option<TcpStream>,
pub tcp_stream: Arc<Mutex<Option<TcpStream>>>,
pub external_func: Vec<
fn(
String,
@ -57,7 +58,7 @@ impl GPSL {
pub fn new(
source: Source,
functions: Option<HashMap<String, Box<Node>>>,
tcp_sream: Option<TcpStream>,
tcp_sream: Arc<Mutex<Option<TcpStream>>>,
external_func: Vec<
fn(
String,
@ -185,7 +186,7 @@ impl GPSL {
block.accept.clone(),
block.reject.clone(),
Some(ExternalFuncCallData {
stream: Some(self.tcp_stream.unwrap().try_clone().unwrap()),
stream: self.tcp_stream.clone(),
}),
);
if res.status == ExternalFuncStatus::SUCCESS {

View File

@ -3,6 +3,7 @@ use gpsl::variable::Variable;
use gpsl::{external_function::STD_FUNC, parser::*, source::*, tokenizer::*, vm::gpsl::*};
use primitive_types::U512;
use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::{collections::HashMap, fs};
/*
[6139062701328441600,
@ -95,7 +96,7 @@ fn main() {
let mut gpsl = GPSL::new(
source,
Some(parser.functions().unwrap()),
Some(stream),
Arc::new(Mutex::new(Some(stream))),
vec![STD_FUNC],
);
let res = gpsl.run("main".to_string(), vec![]);