2019-08-12 23:28:25 +08:00
|
|
|
# Nasal-- Interpreter
|
2019-07-25 02:14:33 +08:00
|
|
|
|
|
|
|
# Nasal
|
|
|
|
|
|
|
|
Nasal is a script language that used in FlightGear.
|
|
|
|
|
|
|
|
There is a Nasal console in FlightGear but sometimes it is not so easy for every developer to use.
|
|
|
|
|
|
|
|
So this is an interpreter for Nasal written by C++.
|
2019-07-25 02:17:35 +08:00
|
|
|
|
|
|
|
The interpreter is still in development.Anyone who interested in this could also join us!
|
2019-07-28 00:06:29 +08:00
|
|
|
|
2019-08-25 00:41:12 +08:00
|
|
|
# Issue in nasal console in flightgear
|
|
|
|
|
|
|
|
When calling a function without a ';' ,the console does not find the error.But in nasal's grammar this seems really wrong.
|
|
|
|
|
|
|
|
So in my interpreter,if you call the function only without a ';' behind it,you will get a piece of error information!
|
|
|
|
|
2019-07-28 00:06:29 +08:00
|
|
|
# Now complete all types
|
|
|
|
|
|
|
|
var: int float double std::string char long long int
|
|
|
|
|
|
|
|
NasalList: array in nasal []
|
|
|
|
|
|
|
|
append
|
|
|
|
|
|
|
|
setsize
|
|
|
|
|
|
|
|
subvec
|
|
|
|
|
|
|
|
pop
|
|
|
|
|
|
|
|
sort
|
|
|
|
|
|
|
|
NasalHash: Hash in nasal {}
|
|
|
|
|
|
|
|
append
|
|
|
|
|
|
|
|
delete
|
|
|
|
|
|
|
|
contains
|
|
|
|
|
|
|
|
keys
|
|
|
|
|
2019-07-29 21:50:18 +08:00
|
|
|
# Now complete Lexical Analysis!
|
2019-07-28 00:06:29 +08:00
|
|
|
|
2019-07-29 21:50:18 +08:00
|
|
|
What it looks like?
|
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Identifier | engineTimer )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | . )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Identifier | start )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | ( )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | ) )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | ; )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( ReserveWord | print )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | ( )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( String | "Engine started" )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | ) )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | ; )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | } )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( ReserveWord | var )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Identifier | stopEngine )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | = )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( ReserveWord | func )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
2019-07-30 21:01:04 +08:00
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | { )
|
|
|
|
|
|
|
|
( Identifier | props )
|
|
|
|
|
|
|
|
( Operator | . )
|
|
|
|
|
|
|
|
( Identifier | getNode )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( String | "/" )
|
|
|
|
|
|
|
|
( Operator | , )
|
|
|
|
|
|
|
|
( Number | 1 )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | . )
|
|
|
|
|
|
|
|
( Identifier | setValue )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( String | "/controls/engines/engine/started" )
|
|
|
|
|
|
|
|
( Operator | , )
|
|
|
|
|
|
|
|
( Number | 0 )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | ; )
|
|
|
|
|
|
|
|
( Identifier | props )
|
|
|
|
|
|
|
|
( Operator | . )
|
|
|
|
|
|
|
|
( Identifier | getNode )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( String | "/" )
|
|
|
|
|
|
|
|
( Operator | , )
|
|
|
|
|
|
|
|
( Number | 1 )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | . )
|
|
|
|
|
|
|
|
( Identifier | setValue )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( String | "/fdm/jsbsim/external_reactions/engine/magnitude" )
|
|
|
|
|
|
|
|
( Operator | , )
|
|
|
|
|
|
|
|
( Number | 0 )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | ; )
|
|
|
|
|
|
|
|
( Identifier | props )
|
|
|
|
|
|
|
|
( Operator | . )
|
|
|
|
|
|
|
|
( Identifier | getNode )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( String | "/" )
|
|
|
|
|
|
|
|
( Operator | , )
|
|
|
|
|
|
|
|
( Number | 1 )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | . )
|
|
|
|
|
|
|
|
( Identifier | setValue )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( String | "/systems/electrical/e-tron/switch/bat-fwd-eng" )
|
|
|
|
|
|
|
|
( Operator | , )
|
|
|
|
|
|
|
|
( Number | 0 )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | ; )
|
|
|
|
|
|
|
|
( Identifier | props )
|
|
|
|
|
|
|
|
( Operator | . )
|
|
|
|
|
|
|
|
( Identifier | getNode )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( String | "/" )
|
|
|
|
|
|
|
|
( Operator | , )
|
|
|
|
|
|
|
|
( Number | 1 )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | . )
|
|
|
|
|
|
|
|
( Identifier | setValue )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( String | "/systems/electrical/e-tron/switch/bat-bwd-eng" )
|
|
|
|
|
|
|
|
( Operator | , )
|
|
|
|
|
|
|
|
( Number | 0 )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | ; )
|
|
|
|
|
|
|
|
( Identifier | engineTimer )
|
|
|
|
|
|
|
|
( Operator | . )
|
|
|
|
|
|
|
|
( Identifier | stop )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | ; )
|
|
|
|
|
|
|
|
( ReserveWord | print )
|
|
|
|
|
|
|
|
( Operator | ( )
|
|
|
|
|
|
|
|
( String | "Engine stopped" )
|
|
|
|
|
|
|
|
( Operator | ) )
|
|
|
|
|
|
|
|
( Operator | ; )
|
|
|
|
|
|
|
|
( Operator | } )
|
2019-07-29 21:50:18 +08:00
|
|
|
|
|
|
|
This is what it outputs.
|
2019-08-07 02:48:03 +08:00
|
|
|
|
|
|
|
# Now with var_stack and function_stack
|
|
|
|
|
|
|
|
By printing the two stacks you can see how vars and functions change!
|
|
|
|
|
|
|
|
[long long int]a:1
|
|
|
|
|
|
|
|
[double]b:3.14
|
|
|
|
|
|
|
|
[string]c:"hello world!"
|
|
|
|
|
|
|
|
function:swap
|
|
|
|
|
|
|
|
function:__main
|
|
|
|
|
|
|
|
function:hello
|
2019-08-08 21:22:22 +08:00
|
|
|
|
2019-08-17 20:25:01 +08:00
|
|
|
# Now the parser can...
|
|
|
|
|
2019-08-21 00:20:31 +08:00
|
|
|
recognize all these things...
|
2019-08-17 20:25:01 +08:00
|
|
|
|
2019-08-21 00:24:42 +08:00
|
|
|
print("a",e);
|
|
|
|
var e=1;
|
|
|
|
var e="str";
|
|
|
|
var e=[];
|
|
|
|
var e={};
|
|
|
|
var e=e[0];
|
|
|
|
var e=e.e;
|
|
|
|
var e=e(0);
|
|
|
|
var e=e();
|
|
|
|
var e=e[e()];
|
|
|
|
var e=[1,e,1,e,1];
|
|
|
|
var e=[e,e,e,e];
|
|
|
|
var e={e:1,e:2,e:3};
|
|
|
|
var e=e[e.e];
|
2019-08-21 00:20:31 +08:00
|
|
|
e=1;
|
2019-08-21 00:24:42 +08:00
|
|
|
e="str";
|
|
|
|
e=[];
|
|
|
|
e={};
|
2019-08-21 00:20:31 +08:00
|
|
|
e=e[0];
|
2019-08-21 00:24:42 +08:00
|
|
|
e=e.e;
|
|
|
|
e=e(0);
|
|
|
|
e=e();
|
|
|
|
e=e[e()];
|
|
|
|
e=[1,e,1,e,1];
|
|
|
|
e=[e,e,e,e];
|
|
|
|
e={e:1,e:2,e:3};
|
|
|
|
e=e[e.e];
|
|
|
|
e=e.e();
|
|
|
|
var e={
|
|
|
|
e:1,
|
|
|
|
e:func(){},
|
|
|
|
e:func(e,e){},
|
|
|
|
e:func(){
|
|
|
|
e;
|
|
|
|
e;
|
|
|
|
},
|
|
|
|
e:func(e,e){
|
|
|
|
e;
|
|
|
|
e;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
var e=func(){}
|
|
|
|
var e=func(e,e){}
|
|
|
|
var e=func(){e;e;}
|
|
|
|
var e=func(e,e){e;e;}
|
|
|
|
var e=func(e,e,e,e,e){
|
|
|
|
e=1;
|
|
|
|
e=e[0];
|
|
|
|
e=e(e,e,e);
|
|
|
|
return e;
|
|
|
|
}
|
2019-08-21 16:52:51 +08:00
|
|
|
e+=e;
|
|
|
|
e-=e;
|
|
|
|
e*=e;
|
|
|
|
e/=e;
|
|
|
|
e~=e;
|
|
|
|
e+=(e-e)*(e+(e/e));
|
2019-08-21 16:56:48 +08:00
|
|
|
e=e-e*(!2);
|
2019-08-25 00:05:23 +08:00
|
|
|
var e=e[0]~e[1]~e[2];
|
|
|
|
var e={
|
|
|
|
e:[],
|
|
|
|
e:{}
|
|
|
|
};
|
|
|
|
return {};
|
|
|
|
return [];
|
|
|
|
return {parent:[e]};
|
|
|
|
var e=0o7103;#Oct
|
|
|
|
var e=0x55aa;#Hex
|
|
|
|
var e=e/e;
|
|
|
|
var e=e[e/e];
|
|
|
|
var e=-e;
|
|
|
|
var e=-1;
|
|
|
|
var e=func(e){e;}
|
|
|
|
var e={e:e/e,e:1};
|
|
|
|
e= e.e(e,1).e()+e*e.e(e.e*e/180);
|
|
|
|
if(!e.e)e;
|
|
|
|
var e=e.e("str",1).e()*e.e("str",1).e*0.001;
|
|
|
|
e.e("str",1).e("str",e-e);
|
|
|
|
e.e(e("str",e.e()/2880)~"str");
|
|
|
|
var e=func(){e;};
|
2019-08-21 16:52:51 +08:00
|
|
|
|
2019-08-21 00:20:31 +08:00
|
|
|
|
2019-08-08 21:22:22 +08:00
|
|
|
# The structure of basical elements is...
|
|
|
|
|
|
|
|
class var;
|
|
|
|
|
|
|
|
class nasal_hash;//forward declaration
|
|
|
|
|
|
|
|
struct nasal_list_unit;
|
|
|
|
|
|
|
|
class nasal_list;
|
|
|
|
|
|
|
|
struct nasal_hash_unit;
|
|
|
|
|
|
|
|
class nasal_hash;
|
|
|
|
|
|
|
|
struct token_unit;
|
|
|
|
|
|
|
|
struct parameter;
|
|
|
|
|
|
|
|
class func;
|
|
|
|
|
2019-08-10 23:59:54 +08:00
|
|
|
class var_stack;
|
|
|
|
|
|
|
|
var_stack nasal_var_stack;
|
|
|
|
|
|
|
|
class func_stack;
|
|
|
|
|
|
|
|
func_stack nasal_func_stack;
|
|
|
|
|
2019-08-08 21:22:22 +08:00
|
|
|
class token_list;
|
|
|
|
|
2019-08-12 23:28:25 +08:00
|
|
|
token_list nasal_lexer;
|
2019-08-08 21:22:22 +08:00
|
|
|
|
2019-08-12 23:28:25 +08:00
|
|
|
class parse;
|
|
|
|
|
|
|
|
parse nasal_parser;
|
|
|
|
|
|
|
|
#include "nasal_lexer.h"
|
2019-08-10 23:59:54 +08:00
|
|
|
|
2019-08-08 21:22:22 +08:00
|
|
|
main();
|
2019-08-28 15:37:21 +08:00
|
|
|
|
|
|
|
# Push down automata
|
|
|
|
|
|
|
|
After many times of failure,i finally try to use PDA to do the parse work.
|