Updating Lexer to KLL 0.5c
- Added syntax check unit-test - Added none emitter (for syntax validation check) - Added KLL 0.5c example expressions - Added Travis-CI test for syntax check - Cleaned up README
This commit is contained in:
parent
fd106b77f2
commit
d7b7752dc1
@ -33,6 +33,7 @@ before_install:
|
|||||||
env:
|
env:
|
||||||
# Basic KLL Tests
|
# Basic KLL Tests
|
||||||
- DIR=tests SCRIPT=sanity.bash
|
- DIR=tests SCRIPT=sanity.bash
|
||||||
|
- DIR=tests SCRIPT=syntax.bash
|
||||||
|
|
||||||
# Exclusions
|
# Exclusions
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -10,7 +10,7 @@ kll - keyboard layout language
|
|||||||
KLL Compiler
|
KLL Compiler
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Most current version of the [KLL Spec](http://input.club/kll).
|
Most current version of the [KLL Spec](https://github.com/kiibohd/kll-spec).
|
||||||
|
|
||||||
Uses [funcparserlib](https://code.google.com/p/funcparserlib/)
|
Uses [funcparserlib](https://code.google.com/p/funcparserlib/)
|
||||||
|
|
||||||
@ -21,16 +21,25 @@ Usage
|
|||||||
### General Usage
|
### General Usage
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kll.py <kll files>
|
kll <kll files>
|
||||||
```
|
```
|
||||||
|
|
||||||
### Kiibohd Controller Usage
|
### Kiibohd Controller Usage
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kll.py <basemap kll files> --default <default layer kll files> --partial <partial layer 1 kll files> --partial <partial layer 2 kll files> --backend kiibohd --templates templates/kiibohdKeymap.h templates/kiibohdDefs.h --outputs generatedKeymap.h kll_defs.h
|
kll.py <misc kll files> --config <config/capability kll files> --base <basemap kll files) --default <default layer kll files> --partial <partial layer 1 kll files> --partial <partial layer 2 kll files>
|
||||||
```
|
```
|
||||||
|
|
||||||
See `kll.py --help` for the most up to date documentation
|
See `kll --help` for the most up to date documentation
|
||||||
|
|
||||||
|
|
||||||
|
Unit Tests
|
||||||
|
----------
|
||||||
|
|
||||||
|
Unit tests can be found in the [tests](tests) directory.
|
||||||
|
They are run by Travis-CI, but can be useful when testing your own changes.
|
||||||
|
|
||||||
|
Remember to add new tests when adding new features/changes.
|
||||||
|
|
||||||
|
|
||||||
Patches/Features/Backends
|
Patches/Features/Backends
|
||||||
|
@ -248,6 +248,12 @@ class CompilerConfigurationStage( Stage ):
|
|||||||
# TODO Detect whether colorization should be used
|
# TODO Detect whether colorization should be used
|
||||||
self.color = self.color in ['auto', 'always']
|
self.color = self.color in ['auto', 'always']
|
||||||
|
|
||||||
|
# Validate if it's a valid emitter
|
||||||
|
if self.emitter not in self.emitters.emitter_list():
|
||||||
|
print( "{0} Invalid emitter '{1}'".format( ERROR, self.emitter ) )
|
||||||
|
print( "Valid emitters: {0}".format( self.emitters.emitter_list() ) )
|
||||||
|
sys.exit( 2 )
|
||||||
|
|
||||||
def command_line_flags( self, parser ):
|
def command_line_flags( self, parser ):
|
||||||
'''
|
'''
|
||||||
Group parser for command line options
|
Group parser for command line options
|
||||||
@ -875,16 +881,23 @@ class OperationSpecificsStage( Stage ):
|
|||||||
( 'PixelLayerStart', ( r'PL\[', ) ),
|
( 'PixelLayerStart', ( r'PL\[', ) ),
|
||||||
( 'Animation', ( r'A"[^"]+"', ) ),
|
( 'Animation', ( r'A"[^"]+"', ) ),
|
||||||
( 'AnimationStart', ( r'A\[', ) ),
|
( 'AnimationStart', ( r'A\[', ) ),
|
||||||
|
( 'USBCode', ( r'U(("[^"]+")|(0x[0-9a-fA-F]+)|([0-9]+))', ) ),
|
||||||
|
( 'USBCodeStart', ( r'U\[', ) ),
|
||||||
|
( 'ScanCode', ( r'S((0x[0-9a-fA-F]+)|([0-9]+))', ) ),
|
||||||
|
( 'ScanCodeStart', ( r'S\[', ) ),
|
||||||
( 'CodeBegin', ( r'\[', ) ),
|
( 'CodeBegin', ( r'\[', ) ),
|
||||||
( 'CodeEnd', ( r'\]', ) ),
|
( 'CodeEnd', ( r'\]', ) ),
|
||||||
( 'Position', ( r'r?[xyz]:[0-9]+(.[0-9]+)?', ) ),
|
( 'Position', ( r'r?[xyz]:[0-9]+(.[0-9]+)?', ) ),
|
||||||
( 'PixelOperator', ( r'(\+:|-:|>>|<<)', ) ),
|
( 'PixelOperator', ( r'(\+:|-:|>>|<<)', ) ),
|
||||||
|
|
||||||
|
( 'String', ( r'"[^"]*"', ) ),
|
||||||
|
|
||||||
( 'Operator', ( r':', ) ),
|
( 'Operator', ( r':', ) ),
|
||||||
( 'Comma', ( r',', ) ),
|
( 'Comma', ( r',', ) ),
|
||||||
( 'Dash', ( r'-', ) ),
|
( 'Dash', ( r'-', ) ),
|
||||||
( 'Plus', ( r'\+', ) ),
|
( 'Plus', ( r'\+', ) ),
|
||||||
( 'Parenthesis', ( r'\(|\)', ) ),
|
( 'Parenthesis', ( r'\(|\)', ) ),
|
||||||
|
( 'Percent', ( r'0|([1-9][0-9]*)%', ) ),
|
||||||
( 'Number', ( r'-?(0x[0-9a-fA-F]+)|(0|([1-9][0-9]*))', ) ),
|
( 'Number', ( r'-?(0x[0-9a-fA-F]+)|(0|([1-9][0-9]*))', ) ),
|
||||||
( 'Name', ( r'[A-Za-z_][A-Za-z_0-9]*', ) ),
|
( 'Name', ( r'[A-Za-z_][A-Za-z_0-9]*', ) ),
|
||||||
]
|
]
|
||||||
|
@ -21,6 +21,7 @@ KLL Emitters Container Classes
|
|||||||
### Imports ###
|
### Imports ###
|
||||||
|
|
||||||
import emitters.kiibohd.kiibohd as kiibohd
|
import emitters.kiibohd.kiibohd as kiibohd
|
||||||
|
import emitters.none.none as none
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -58,7 +59,8 @@ class Emitters:
|
|||||||
|
|
||||||
# Dictionary of Emitters
|
# Dictionary of Emitters
|
||||||
self.emitters = {
|
self.emitters = {
|
||||||
'kiibohd' : kiibohd.Kiibohd( control )
|
'kiibohd' : kiibohd.Kiibohd( control ),
|
||||||
|
'none' : none.Drop( control )
|
||||||
}
|
}
|
||||||
|
|
||||||
def emitter_default( self ):
|
def emitter_default( self ):
|
||||||
|
0
emitters/none/__init__.py
Normal file
0
emitters/none/__init__.py
Normal file
76
emitters/none/none.py
Normal file
76
emitters/none/none.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
'''
|
||||||
|
KLL Data Dropper (Doesn't emit anything)
|
||||||
|
'''
|
||||||
|
|
||||||
|
# Copyright (C) 2016 by Jacob Alexander
|
||||||
|
#
|
||||||
|
# This file is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This file is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this file. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
### Imports ###
|
||||||
|
|
||||||
|
from common.emitter import Emitter
|
||||||
|
|
||||||
|
|
||||||
|
### Decorators ###
|
||||||
|
|
||||||
|
## Print Decorator Variables
|
||||||
|
ERROR = '\033[5;1;31mERROR\033[0m:'
|
||||||
|
WARNING = '\033[5;1;33mWARNING\033[0m:'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Classes ###
|
||||||
|
|
||||||
|
class Drop( Emitter ):
|
||||||
|
'''
|
||||||
|
Doesn't emit at all, just ignores everything
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__( self, control ):
|
||||||
|
'''
|
||||||
|
Emitter initialization
|
||||||
|
|
||||||
|
@param control: ControlStage object, used to access data from other stages
|
||||||
|
'''
|
||||||
|
Emitter.__init__( self, control )
|
||||||
|
|
||||||
|
def command_line_args( self, args ):
|
||||||
|
'''
|
||||||
|
Group parser for command line arguments
|
||||||
|
|
||||||
|
@param args: Name space of processed arguments
|
||||||
|
'''
|
||||||
|
|
||||||
|
def command_line_flags( self, parser ):
|
||||||
|
'''
|
||||||
|
Group parser for command line options
|
||||||
|
|
||||||
|
@param parser: argparse setup object
|
||||||
|
'''
|
||||||
|
|
||||||
|
def output( self ):
|
||||||
|
'''
|
||||||
|
Final Stage of Emitter
|
||||||
|
|
||||||
|
Nothing to do
|
||||||
|
'''
|
||||||
|
|
||||||
|
def process( self ):
|
||||||
|
'''
|
||||||
|
Emitter Processing
|
||||||
|
|
||||||
|
Nothing to do, just dropping all the results
|
||||||
|
'''
|
||||||
|
|
@ -44,6 +44,15 @@ A[BLEEdsing, 11, 13-15] <= P[4-10](+32);
|
|||||||
|
|
||||||
A[BLEEdsing2, 0] <= PL[0](127, 30, 40), P[5](20, 30, 40);
|
A[BLEEdsing2, 0] <= PL[0](127, 30, 40), P[5](20, 30, 40);
|
||||||
A[BLEEdsing2, 1] <= P[1-20,40](40,50,0x60);
|
A[BLEEdsing2, 1] <= P[1-20,40](40,50,0x60);
|
||||||
|
A[BLEEdsing2, 2] <= P[c:0](40,50,0x60);
|
||||||
|
A[BLEEdsing2, 3] <= P[c:10%](40,50,0x60);
|
||||||
|
A[BLEEdsing2, 4] <= P[r:10%,c:20](40,50,0x60);
|
||||||
|
A[BLEEdsing2, 5] <= P[r:i+10%,c:i-20](40,50,0x60);
|
||||||
|
A[BLEEdsing2, 6] <= P[r:i+10%](40,50,0x60);
|
||||||
|
A[BLEEdsing2, 7] <= U["A"](40,50,0x60);
|
||||||
|
A[BLEEdsing2, 8] <= U"B"(40,50,0x60);
|
||||||
|
A[BLEEdsing2, 9] <= S120(40,50,0x60);
|
||||||
|
A[BLEEdsing2, 10] <= S[0x10](40,50,0x60);
|
||||||
|
|
||||||
# Animation Triggers
|
# Animation Triggers
|
||||||
myCapability => myFunc( myArg1 : 1, myArg2 : 4 );
|
myCapability => myFunc( myArg1 : 1, myArg2 : 4 );
|
||||||
|
2
kll
2
kll
@ -99,7 +99,7 @@ def command_line_args( control ):
|
|||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
usage="%(prog)s [options..] [<generic>..]",
|
usage="%(prog)s [options..] [<generic>..]",
|
||||||
description="KLL Compiler - Generates specified output from KLL .kll files.",
|
description="KLL Compiler - Generates specified output from KLL .kll files.",
|
||||||
epilog="Example: {0} TODO".format( os.path.basename( sys.argv[0] ) ),
|
epilog="Example: {0} scan_map.kll".format( os.path.basename( sys.argv[0] ) ),
|
||||||
formatter_class=argparse.RawTextHelpFormatter,
|
formatter_class=argparse.RawTextHelpFormatter,
|
||||||
add_help=False,
|
add_help=False,
|
||||||
)
|
)
|
||||||
|
63
tests/common.bash
Normal file
63
tests/common.bash
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Common functions for running kll unit tests
|
||||||
|
# Jacob Alexander 2016
|
||||||
|
|
||||||
|
PASSED=0
|
||||||
|
FAILED=0
|
||||||
|
|
||||||
|
# Results
|
||||||
|
result() {
|
||||||
|
echo "--- Results ---"
|
||||||
|
echo "${PASSED}/$((PASSED+FAILED))"
|
||||||
|
if (( FAILED == 0 )); then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Runs a command, increments test passed/failed
|
||||||
|
# Args: Command
|
||||||
|
cmd() {
|
||||||
|
# Run command
|
||||||
|
echo "CMD: $@"
|
||||||
|
$@
|
||||||
|
local RET=$?
|
||||||
|
|
||||||
|
# Check command
|
||||||
|
if [[ ${RET} -ne 0 ]]; then
|
||||||
|
((FAILED++))
|
||||||
|
else
|
||||||
|
((PASSED++))
|
||||||
|
fi
|
||||||
|
|
||||||
|
return ${RET}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Run a command multiple times using an array of values
|
||||||
|
# Arg #1: Base command
|
||||||
|
# Arg #2: Static arguments
|
||||||
|
# Arg #3: Static arguments to call when command fails (debug info)
|
||||||
|
# Arg #4+: Array of variations to swap into the command
|
||||||
|
cmds() {
|
||||||
|
local BASE=${1}
|
||||||
|
shift
|
||||||
|
local STATIC=${1}
|
||||||
|
shift
|
||||||
|
local FAIL_STATIC=${1}
|
||||||
|
shift
|
||||||
|
local VARS=${@} # Rest of arguments
|
||||||
|
|
||||||
|
# Base command
|
||||||
|
echo "BASE CMD: ${BASE} ${STATIC}"
|
||||||
|
|
||||||
|
# Iterate over variations
|
||||||
|
for var in ${VARS[@]}; do
|
||||||
|
cmd ${BASE} ${STATIC} ${var}
|
||||||
|
if [[ $? -ne 0 ]]; then
|
||||||
|
echo "CMD FAILED - RUNNING DEBUG ARGS - ${BASE} ${FAIL_STATIC} ${var}"
|
||||||
|
${BASE} ${FAIL_STATIC} ${var}
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
@ -1,46 +1,24 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Basic sanity check for kll compiler
|
# Basic sanity check for kll compiler
|
||||||
# Currently runs both versions of the compiler
|
# Currently runs both versions of the compiler
|
||||||
set +x
|
# Jacob Alexander 2016
|
||||||
|
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
PASSED=0
|
# Common functions
|
||||||
FAILED=0
|
source ${SCRIPT_DIR}/common.bash
|
||||||
|
|
||||||
# Results
|
|
||||||
result() {
|
|
||||||
echo "--- Results ---"
|
|
||||||
echo "${PASSED}/$((PASSED+FAILED))"
|
|
||||||
if (( FAILED == 0 )); then
|
|
||||||
return 0
|
|
||||||
else
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Runs a command, increments test passed/failed
|
|
||||||
# Args: Command
|
|
||||||
cmd() {
|
|
||||||
# Run command
|
|
||||||
echo "CMD: $@"
|
|
||||||
$@
|
|
||||||
|
|
||||||
# Check command
|
|
||||||
if [[ $? -ne 0 ]]; then
|
|
||||||
((FAILED++))
|
|
||||||
else
|
|
||||||
((PASSED++))
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# Start in kll top-level directory
|
# Start in kll top-level directory
|
||||||
cd ${SCRIPT_DIR}/..
|
cd ${SCRIPT_DIR}/..
|
||||||
|
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
cmd ./kll.py --version
|
cmd ./kll.py --version
|
||||||
cmd ./kll --version
|
cmd ./kll --version
|
||||||
|
|
||||||
|
## Tests complete
|
||||||
|
|
||||||
|
|
||||||
result
|
result
|
||||||
exit $?
|
exit $?
|
||||||
|
|
||||||
|
47
tests/syntax.bash
Executable file
47
tests/syntax.bash
Executable file
@ -0,0 +1,47 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Use example .kll files to check syntax compatibility
|
||||||
|
# Does not generate code, so resulting datastructures do not necessarily need to functino
|
||||||
|
# Jacob Alexander 2016
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
|
||||||
|
# Common functions
|
||||||
|
source ${SCRIPT_DIR}/common.bash
|
||||||
|
|
||||||
|
# Start in kll top-level directory
|
||||||
|
cd ${SCRIPT_DIR}/..
|
||||||
|
|
||||||
|
|
||||||
|
# Args used for each of the tests
|
||||||
|
ARGS="--emitter none --data-finalization-display"
|
||||||
|
FAIL_ARGS="--emitter none --token-debug --parser-token-debug --operation-organization-display --data-organization-display --data-finalization-display"
|
||||||
|
|
||||||
|
# Files to check syntax on
|
||||||
|
FILES=(
|
||||||
|
examples/assignment.kll
|
||||||
|
examples/capabilitiesExample.kll
|
||||||
|
examples/colemak.kll
|
||||||
|
examples/defaultMapExample.kll
|
||||||
|
examples/example.kll
|
||||||
|
examples/hhkbpro2.kll
|
||||||
|
examples/leds.kll
|
||||||
|
examples/mapping.kll
|
||||||
|
examples/md1Map.kll
|
||||||
|
examples/simple1.kll
|
||||||
|
examples/simple2.kll
|
||||||
|
examples/simpleExample.kll
|
||||||
|
examples/state_scheduling.kll
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
|
||||||
|
cmds "./kll" "${ARGS}" "${FAIL_ARGS}" ${FILES[@]}
|
||||||
|
|
||||||
|
|
||||||
|
## Tests complete
|
||||||
|
|
||||||
|
|
||||||
|
result
|
||||||
|
exit $?
|
||||||
|
|
Reference in New Issue
Block a user